Episode ini membahas cara memberi konfigurasi berbeda untuk setiap client: direktif client-config-dir, script client-connect dan client-disconnect untuk hook lifecycle, hingga alokasi IP statis dengan ifconfig-push dan iroute.

Sejauh ini semua client mendapat perlakuan yang sama: alamat dari pool yang sama, rute yang sama, kebijakan yang sama. Di dunia nyata hampir tidak demikian. Manager butuh akses ke seluruh jaringan, admin keuangan hanya ke satu server, dan tim engineering butuh alamat IP tetap untuk firewall inbound.
Episode 9 ini membahas client config distribution (CCD) — mekanisme OpenVPN untuk memberi konfigurasi berbeda kepada setiap client. Kalian akan belajar direktif client-config-dir, script client-connect dan client-disconnect sebagai hook di awal dan akhir sesi, serta alokasi IP statis dengan ifconfig-push dan iroute.
Ini adalah episode yang mengubah OpenVPN dari sekadar tunnel menjadi infrastruktur dengan kebijakan nyata. Setelah episode ini, kalian bisa memberikan tingkat akses yang berbeda-beda untuk setiap pengguna atau site.
Direktif client-config-dir menunjuk ke direktori berisi file konfigurasi per client. Setiap file diberi nama sesuai common name sertifikat client:
client-config-dir /etc/openvpn/server/ccdKetika sebuah client terhubung, OpenVPN mencari file dengan nama yang sama dengan CN sertifikat client di direktori tersebut. Contoh: client dengan CN arman akan memuat file /etc/openvpn/server/ccd/arman. Jika file tidak ada, client mendapat konfigurasi default dari server.conf.
Direktori CCD menangani kontrol akses jaringan, jadi pastikan hanya root yang bisa menulis ke dalamnya:
mkdir -p /etc/openvpn/server/ccd
chown root:root /etc/openvpn/server/ccd
chmod 700 /etc/openvpn/server/ccdchmod 700 memastikan hanya pemilik direktori yang bisa mengakses. Sebuah file CCD yang bisa ditulis pengguna lain adalah lubang keamanan: penyerang bisa menyuntikkan direktif push untuk membajak routing client lain.
File CCD adalah potongan konfigurasi server yang dimuat khusus untuk client tersebut. Direktif yang umum ditulis di sini adalah iroute, ifconfig-push, dan push:
iroute 192.168.10.0 255.255.255.0
ifconfig-push 10.8.0.10 255.255.255.0
push "route 10.20.0.0 255.255.255.0"Baris push "route ..." di dalam CCD ditambahkan ke konfigurasi client, sama seperti push di server.conf — tetapi sekarang hanya untuk client tertentu.
Ketika sebuah client membutuhkan alamat IP tetap di dalam subnet VPN, gunakan ifconfig-push di file CCD-nya. Kombinasi dengan topology subnet di server memberi client alamat statis yang sama setiap connect:
ifconfig-push 10.8.0.50 255.255.255.0Alamat yang dialokasikan dengan ifconfig-push harus berada di luar pool otomatis server agar tidak bentrok. Kebiasaan yang baik: alokasikan IP statis mulai dari bagian bawah rentang subnet dan biarkan pool dinamis mengisi bagian atas.
Jika kalian memakai topology net30 atau p2p, format ifconfig-push berbeda: butuh dua alamat, satu untuk client dan satu untuk sisi server. Jangan mencampur format tanpa memahami topologi yang aktif, karena kesalahan format menghasilkan error option ifconfig-push on non-subnet topology di log.
Setelah client terhubung, verifikasi di openvpn-status.log bahwa client mendapat IP yang diharapkan. Jika dua client menerima IP yang sama, tunjukan sumber konfliknya di file CCD — OpenVPN tidak otomatis menolak duplikat alamat.
iroute memberitahu server bahwa subnet di belakang sebuah client dapat dijangkau melalui tunnel client tersebut. Ini esensial untuk site-to-site dan untuk client yang berada di balik NAT:
iroute 192.168.10.0 255.255.255.0Satu pasang direktif yang umum untuk client yang mewakili sebuah site: ifconfig-push memberi client IP tetap, sementara iroute memberi server cara menjangkau subnet di belakang client. Keduanya biasanya ditulis berdampingan di file CCD yang sama.
Agar lalu lintas mengalir dua arah, server juga perlu memberi tahu client rute ke jaringan lain. Di file CCD, tambahkan push "route ..." untuk jaringan yang ingin dijangkau client. Tanpa push, client tahu cara kirim ke subnet server, tetapi server juga harus tahu cara menjangkau subnet client lewat iroute.
OpenVPN memanggil script pada momen tertentu dalam lifecycle sesi client. Dua yang paling berguna adalah client-connect, yang dipanggil setelah autentikasi berhasil sebelum tunnel diaktifkan, dan client-disconnect, yang dipanggil setelah sesi berakhir:
client-connect /etc/openvpn/server/scripts/on-connect.sh
client-disconnect /etc/openvpn/server/scripts/on-disconnect.sh
script-security 2script-security 2 wajib diaktifkan agar OpenVPN berkenan menjalankan script eksternal. Script menerima informasi client melalui environment variable seperti common_name, untrusted_ip, dan ifconfig_pool_remote_ip.
Script hook sering dipakai untuk menerapkan aturan firewall dinamis, mencatat log akses ke database, atau mengirim notifikasi. Contoh sederhana yang mencatat sesi baru:
#!/bin/bash
echo "$(date) client $common_name connected from $untrusted_ip" >> /var/log/openvpn-ccd.logSetelah membuat script, jangan lupa chmod +x agar bisa dieksekusi. Kesalahan kecil berupa permission yang salah sering membuat script diam-diam tidak berjalan.
Karena client-connect dipanggil sebelum tunnel aktif, script ini bisa menolak koneksi dengan exit code bukan nol. Pola ini dipakai untuk kontrol akses tambahan di luar sertifikat — misalnya menolak client yang tidak ada di daftar izin, atau menerapkan kebijakan berdasar waktu.
Inti yang harus dibawa pulang:
client-config-dir memetakan file konfigurasi per client berdasarkan CN sertifikat.ifconfig-push memberi client alamat IP tetap di subnet VPN.iroute memberi tahu server cara menjangkau subnet di belakang client.push "route ..." di dalam CCD bersifat khusus untuk client tersebut.client-connect dan client-disconnect adalah hook lifecycle sesi.Di episode 10 selanjutnya kita akan membahas advanced authentication — integrasi LDAP dan RADIUS untuk menggantikan file user statis, plugin auth-pam dan auth-radius, serta penambahan MFA dengan OTP dan TOTP untuk lapisan keamanan kedua. Setelah episode ini, autentikasi OpenVPN kalian siap untuk skala enterprise.