Hook client-connect OpenVPN: ke mana alamat Anda sebenarnya pergi
Skrip client-connect tidak dapat mengembalikan alamat dengan mencetaknya. Lihat bagaimana file sementara hook, status keluar, dan topologi menentukan IP klien.
Mengembalikan alamat dari skrip client-connect tampak seolah-olah harus menetapkan IP klien. Tidak: satu-satunya saluran hook ke server adalah file sementara yang path-nya datang sebagai argumen terakhir skrip, dan alamat harus ditulis di sana dalam sintaks ifconfig-push. Skrip yang mencetak alamat atau keluar dengan nol tanpa menulis apa pun menghasilkan klien terhubung dengan alamat dari pool, dan log server tampak sepenuhnya sehat.
Kebingungan itu wajar, karena beberapa hook lain memang membalas melalui kode keluar atau variabel lingkungan. Yang ini punya kontraknya sendiri, dan kontraknya dimulai dengan nama file.
Hook menulis file, bukan nilai kembali
Deklarasinya dua baris: script-security 2 untuk mengizinkan panggilan, lalu client-connect /etc/openvpn/server/assign-address.sh. Saat klien terautentikasi, server menjalankan skrip itu dengan path file yang dihasilkan ditambahkan sebagai argumen terakhir, yang merupakan $1 hanya jika deklarasi tidak mengirimkan argumen tambahan miliknya sendiri. Semua yang diterapkan pada klien tersebut masuk ke file itu sebagai direktif biasa, satu per baris, persis seperti yang akan muncul dalam konfigurasi. Pembungkus yang menambahkan parameternya sendiri menggeser posisi, dan gejala klasiknya adalah skrip yang menulis ke path yang tampak seperti --verbose.
Status keluar adalah separuh kontrak lainnya. Nol berarti terima dan baca file; apa pun selain itu menolak koneksi, dan begitulah identitas yang tidak dipetakan ditolak alih-alih diam-diam kembali ke pool. Tulis direktif lengkap sebelum mengembalikan sukses, agar file setengah tertulis tidak pernah menjadi konfigurasi klien.
Dua direktif layak diperhatikan karena keduanya berinteraksi dengan semua hal lain. ifconfig-push menetapkan alamat, sedangkan route yang didorong memberi tahu klien apa yang dapat dijangkau melalui terowongan; kembalikan yang pertama dan lupakan yang kedua dan Anda mendapatkan klien dengan alamat dan tidak punya tujuan. Urutan di dalam file tidak penting, tetapi kelengkapannya penting. Hook yang mendorong rute untuk prefiks yang tidak dapat dijangkau rekan mana pun adalah kesalahan yang sama dilihat dari ujung lain.
Masukan datang melalui variabel lingkungan: common_name, trusted_ip, ifconfig_pool_remote_ip dan sisanya. Perlakukan semuanya sebagai string dari luar server, jangan pernah sebagai fragmen shell.
Pemetaan alamat adalah kebijakan, bukan aritmetika
Jalan pintas yang menggoda adalah mengurai nama sertifikat dan menggunakan digitnya sebagai oktet terakhir. Itu bukan pengalokasi, dan gagal dengan cara biasa: dua nama dengan sufiks sama bertabrakan, nama yang berakhiran 300 bukan alamat, dan sertifikat yang diganti nama oleh administrator memindahkan perangkat secara diam-diam. Validasi keanggotaan subnet, rentang host yang dapat digunakan, alamat yang dicadangkan, dan keunikan pada setiap panggilan, dan simpan pemetaan dalam tabel yang dapat dibaca manusia.
Siapa pun yang mengendalikan nama mengendalikan alamat, jadi putuskan apa yang sebenarnya diwakili common_name dalam penerapan ini. Dengan username-as-common-name diaktifkan, identitasnya adalah login, bukan subjek sertifikat. Jangan pernah meneruskan nilai itu ke evaluasi shell, dan jangan pernah membiarkan klien memengaruhi path file.
Pengalokasi berbasis registri harus bertahan terhadap konkurensi. Cadangkan alamat secara atomik, tangani penulisan gagal tanpa menerima klien setengah terkonfigurasi, dan tandai setiap alokasi dengan koneksi yang memilikinya, sehingga pemutusan terlambat dari sesi lama tidak dapat membebaskan alamat yang sudah dipegang sesi lebih baru. Beberapa instans server yang berbagi satu pool membuat persyaratan itu lebih tajam, bukan opsional.
Topologi menentukan arti ifconfig-push
Dengan topology subnet pada 10.77.0.0/24, ifconfig-push 10.77.0.20 255.255.255.0 adalah alamat ditambah netmask-nya. Di bawah topology net30 argumen kedua sama sekali bukan netmask melainkan alamat peer, jadi menyalin bentuk subnet ke server net30 memberi Anda klien yang terasosiasi dan tidak dapat melewatkan lalu lintas. Ubah topologi dengan sengaja, jangan pernah agar sebuah contoh tampak konsisten. Server yang sudah menjalankan net30 memiliki klien aktif pada pengalamatan lama, jadi peralihannya adalah migrasi dengan jendela pemeliharaan, bukan suntingan satu baris.
Alamat statis harus berada di luar pool dinamis dan di luar setiap penetapan statis lainnya, termasuk yang diberikan oleh file client-config-dir biasa. Jika dua mekanisme dapat menghasilkan alamat yang sama untuk klien berbeda, salah satunya pada akhirnya akan melakukannya.
Uji empat kasus sebelum Anda memercayainya
Jalankan pemeriksaan yang sama terhadap identitas yang dipetakan, yang tidak dipetakan, sambungan ulang, dan kegagalan registri yang disimulasikan. openvpn --config client.ovpn --verb 4 menunjukkan alamat yang ditetapkan dalam balasan push, dan di server grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log memastikan apa yang sebenarnya dikirim. Untuk identitas yang tidak dipetakan, hasil yang diharapkan adalah koneksi ditolak, bukan alamat dari pool.
Lalu periksa direktori tempat daemon menulis file sementara itu. Skrip berjalan dalam konteks layanan yang diturunkan, jadi path yang dapat ditulis root tetapi tidak oleh daemon mengubah setiap koneksi menjadi penolakan dengan kesalahan izin yang terkubur beberapa baris di log.
Alokasi bukan otorisasi: alamat yang dipatok tetap tidak memberikan akses ke setiap tujuan di belakang server. Jaga kebijakan perutean dan firewall di lapisannya sendiri, dan verifikasi terhadap alamat yang baru saja Anda tetapkan.