Instalasi Paket Dependensi

dnf install -y epel-release
dnf install -y openvpn openssl easy-rsa policycoreutils-python-utils 

Membuat dan Menyiapkan Sertifikat Server OpenVPN

Set variabel environment untuk easy_rsa

cat <<EOF | tee vars
set_var EASYRSA_ALGO ec
set_var EASYRSA_CURVE prime256v1
set_var EASYRSA_CA_EXPIRE 3650
set_var EASYRSA_CERT_EXPIRE 3650
set_var EASYRSA_CRL_DAYS 3650
EOF

Kemudian jalankan ./easyresa init-pki
init-pki

Buat certificate authority (CA) dan sertifikat server.

SERVER_CN=jumpserver
SERVER_NAME=jumpserver

./easyrsa --batch --req-cn="$SERVER_CN" build-ca nopass
./easyrsa --batch build-server-full "$SERVER_NAME" nopass
./easyrsa gen-crl

create-ca-cert

Pindahkan semua file yang dihasilkan ke direktori /etc/openvpn/cert

mkdir -p /etc/openvpn/cert
cp pki/ca.crt \
    pki/crl.pem \
    pki/private/ca.key \
    "pki/issued/$SERVER_NAME.crt" \
    "pki/private/$SERVER_NAME.key" \
    /etc/openvpn/cert

Generate tls-crypt key untuk meningkatkan keamanan

openvpn --genkey secret /etc/openvpn/server/tls-crypt.key

Membuat Konfigurasi Server

Konfigurasi server default berada di /usr/share/doc/openvpn/sample/sample-config-files/server.conf

cat <<EOF | tee /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
server 10.79.83.0 255.255.255.0
push "route 10.79.80.0 255.255.255.0"
push "dhcp-option DNS 10.79.80.254"
push "dhcp-option DOMAIN lab.tworty.id"
client-config-dir /etc/openvpn/client/ccd
ifconfig-pool-persist /etc/openvpn/client/persistent-ip.list
dh none
ecdh-curve prime256v1
auth SHA256
cipher AES-128-GCM
data-ciphers AES-128-GCM
ca /etc/openvpn/cert/ca.crt
cert /etc/openvpn/cert/jumpserver.crt
key /etc/openvpn/cert/jumpserver.key
crl-verify /etc/openvpn/cert/crl.pem
tls-crypt /etc/openvpn/cert/tls-crypt.key
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
EOF

Tambahkan duplicate-cn ke /etc/openvpn/server/server.conf jika Anda membutuhkan beberapa koneksi VPN dengan CN yang sama. Jika menggunakan RHEL, ubah direktif group dari nogroup menjadi nobody agar sesuai dengan grup yang tersedia di distribusi.

Routing, Kernel dan Konfigurasi Firewall

Tambahkan routing policy

nmcli device modify eth1 +ipv4.routes "10.79.83.0/24 10.79.80.254"
nmcli connection modify 'System eth1' +ipv4.routes "10.79.83.0/24 10.79.80.254"

Tambahkan parameter kernel untuk ip forwarding

cat <<EOF | tee /etc/sysctl.d/ipv4_forward.conf
net.ipv4.ip_forward = 1
EOF

sysctl -p

Tambahkan konfigurasi firewall menggunakan firewalld

firewall-cmd --get-active-zones
firewall-cmd --permanent --add-service openvpn
firewall-cmd --permanent --zone=internal --add-source=10.79.80.0/22
firewall-cmd --reload

atau port dan protokol spesifik dengan firewall-cmd --permanent --add-port=1194/udp

Konfigurasi SELinux

semanage port -a -t openvpn_port_t -p udp 1194

Jika ada masalah dengan kebijakan SElinux gunakan audit 

sealert -a /var/log/audit/audit.log
ausearch -c 'openvpn' --raw | audit2allow -M openvpn-custom

selinux-openport

Membuat Konfigurasi Client

Konfigurasi server default berada di /usr/share/doc/openvpn/sample/sample-config-files/client.conf

YOUR_IP=$(curl -sL ipinfo.io/ip)
cat <<EOF | tee /etc/openvpn/client/client.ovpn
client
proto udp
explicit-exit-notify
remote $YOUR_IP 1194
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name jumpserver name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
verb 3
EOF

Membuat Sertifikat Client

CLIENT_NAME=jumpserver-client
./easyrsa --batch build-client-full "$CLIENT_NAME" nopass

Masukkan file certificate authority

{ echo "<ca>"
    cat /etc/openvpn/cert/ca.crt
    echo "</ca>"
} | tee -a /etc/openvpn/client/client.ovpn

Masukkan file sertifikat

{ echo "<cert>"
    awk '/BEGIN/,/END/' /etc/openvpn/easy-rsa/3/pki/issued/$CLIENT_NAME.crt
    echo "</cert>"
} | tee -a /etc/openvpn/client/client.ovpn

Masukkan file key sertifikat

{ echo "<key>"
    cat /etc/openvpn/easy-rsa/3/pki/private/$CLIENT_NAME.key
    echo "</key>"
} | tee -a /etc/openvpn/client/client.ovpn

Masukkan file tls-crypt key

{ echo "<tls-crypt>"
    awk '/BEGIN/,/END/' /etc/openvpn/cert/tls-crypt.key
    echo "</tls-crypt>"
} | tee -a /etc/openvpn/client/client.ovpn

Sekarang konfigurasi client sudah selesai di /etc/openvpn/client/client.ovpn

Setup logging dan logrotate

Buat direktori log terlebih dahulu

mkdir -p /var/log/openvpn

Kemudian buat kebijakan logrotate

cat <<EOF | tee /etc/logrotate.d/openvpn
/var/log/openvpn/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 0640 root root
    sharedscripts
    postrotate
        /bin/systemctl reload openvpn-server@server > /dev/null 2>&1 || true
    endscript
}
EOF

Pastikan konfigurasi logrotate

logrotate -d /etc/logrotate.d/openvpn

Autentikasi menggunakan Linux PAM dan OTP

Berikut contoh kebijakan SElinux untuk OpenVPN dengan Google Authenticator

cat <<EOF | tee openvpn-custom.te
module openvpn-custom 1.0;

require {
    type openvpn_t;
    type user_home_t;
    type auth_home_t;
    type user_home_dir_t;
    class file { create getattr open read rename setattr unlink write };
    class dir { read write add_name remove_name };
}

#============= openvpn_t ==============
# Allow openvpn to access auth_home_t files
allow openvpn_t auth_home_t:file { open read unlink };

# Allow openvpn to access user_home_t directories and files
allow openvpn_t user_home_dir_t:dir { read write add_name remove_name };
allow openvpn_t user_home_t:dir { read write add_name remove_name };
allow openvpn_t user_home_t:file { create getattr open read rename setattr unlink write };
EOF
checkmodule -M -m -o openvpn-custom.mod openvpn-custom.te
semodule_package -o openvpn-custom.pp -m openvpn-custom.mod
semodule -i openvpn-custom.pp

Tambahkan context untuk direktori home custom

    semanage fcontext -a -t auth_home_t /home/lab.tworty.id/[^/]+/\.google_authenticator
    semanage fcontext -a -t auth_home_t /home/lab.tworty.id/[^/]+/\.google_authenticator~
    restorecon -rv /home

Instalasi paket dan setup kebijakan PAM

dnf install -y google-authenticator qrencode

cat <<EOF | tee /etc/pam.d/openvpn
auth       required     pam_google_authenticator.so forward_pass
auth       include      system-auth
account    include      system-auth
password   include      system-auth
session    include      system-auth
EOF

Ganti konfigurasi server dengan nilai berikut

cat <<EOF | tee -a /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
server 10.79.83.0 255.255.255.0
push "route 10.79.80.0 255.255.255.0"
push "dhcp-option DNS 10.79.80.254"
push "dhcp-option DOMAIN lab.tworty.id"
client-config-dir /etc/openvpn/client/ccd
ifconfig-pool-persist /etc/openvpn/client/persistent-ip.list
dh none
ecdh-curve prime256v1
auth SHA256
cipher AES-128-GCM
data-ciphers AES-128-GCM
ca /etc/openvpn/cert/ca.crt
cert /etc/openvpn/cert/jumpserver.crt
key /etc/openvpn/cert/jumpserver.key
crl-verify /etc/openvpn/cert/crl.pem
tls-crypt /etc/openvpn/cert/tls-crypt.key
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn
username-as-common-name
duplicate-cn
reneg-sec 0
verb 3
EOF

Update file service systemd openvpn, berdasarkan issue ini lalu restart service

cp -r  /usr/lib/systemd/system/[email protected] /etc/systemd/system
sed -i 's/^ProtectHome=true/ProtectHome=false/' /etc/systemd/system/[email protected]
systemctl daemon-reload
systemctl restart [email protected]

Tambahkan konfigurasi berikut agar saat membuat user baru atau login user harus membuat multi factor authenticator

cat <<EOF | tee -a /etc/skel/.bashrc

if [ ! -f ~/.google_authenticator ]; then
    echo "Google Authenticator configuration file not found."
    echo "Setting up Google Authenticator..."