Hook PHP OpenVPN: trusted_ip versus ifconfig_pool_remote_ip
Dua alamat dengan dua makna berbeda, dibaca oleh proses yang tidak Anda jalankan. Apa itu variabel hook, dan mengapa $_ENV kosong tidak membuktikan apa pun.
$_ENV array kosong dalam skrip hook terasa seperti bukti bahwa OpenVPN tidak meneruskan apa pun. Biasanya itu bukti sesuatu yang sama sekali lain: PHP dikonfigurasi untuk tidak mengisi superglobal itu, dan nilainya sudah berada di lingkungan proses sepanjang waktu. Kesimpulan keliru kedua lebih halus, karena dua variabel alamat dalam hook koneksi berarti hal berbeda dan dipakai secara bertukar. Kedua kesalahan itu menghabiskan satu sore jika Anda mulai dari yang salah.
Dua alamat, dua klaim berbeda
Titik akhir luar adalah apa yang diamati server saat klien terhubung, tersedia sebagai trusted_ip untuk IPv4 dan trusted_ip6 untuk IPv6. Alamat virtual adalah yang dialokasikan pool untuk sesi ini, tersedia sebagai ifconfig_pool_remote_ip.
Keduanya menjawab pertanyaan berbeda, dan catatan biasanya membutuhkan salah satunya daripada keduanya. Yang pertama adalah dari mana koneksi berasal, yang bisa berupa alamat NAT berbagi yang dipakai ratusan orang. Yang kedua adalah di mana sesi ini hidup di dalam terowongan, dan alamat itu bisa dialokasikan ulang ke sesi lain nanti. Mencampur keduanya menghasilkan catatan yang tampak masuk akal dan salah.
Pembacaan minimal terlihat seperti ini.
$outer4 = getenv('trusted_ip');
$outer6 = getenv('trusted_ip6');
$inner = getenv('ifconfig_pool_remote_ip');
$outer = $outer4 !== false ? $outer4 : $outer6;Tidak satu pun dari kedua nilai itu mengidentifikasi seseorang. Yang satu adalah pengamatan jaringan, yang lain sewa, dan catatan yang memperlakukan salah satunya sebagai pengenal perangkat stabil akan salah pada kali pertama klien terhubung kembali dari jaringan lain atau menerima alamat pool lain. Pilih bidang berdasarkan pertanyaan yang harus dijawab catatan, lalu tulis pertanyaan itu di samping kolom.
Periksa bagaimana PHP dijalankan, bukan shell Anda
Hook berjalan sebagai anak dari daemon VPN dengan lingkungan yang dibangun daemon. Shell interaktif Anda punya lingkungan lain, dan menjalankan skrip dengan tangan menguji lingkungan shell, bukan lingkungan hook.
Mulailah dengan memastikan hook benar-benar terpicu pada tahap yang Anda harapkan. Skrip yang terpasang pada tahap yang salah, atau yang tidak pernah berjalan karena direktif menunjuk ke jalur lain, menghasilkan gejala yang persis sama dengan variabel yang hilang. Tambahkan baris penanda yang disengaja di atas skrip dan pastikan baris itu muncul sebelum Anda memeriksa hal lain. Satu baris bertanda waktu di log memisahkan tidak pernah berjalan dari berjalan tanpa nilai.
Lalu pastikan interpreter dan berkas konfigurasi mana yang dipakai pemanggilan itu. Menyunting konfigurasi PHP untuk server web tidak mengubah apa pun pada proses CLI yang dijalankan OpenVPN, dan keduanya bisa memuat berkas php.ini yang sama sekali berbeda.
Mengapa $_ENV kosong tidak membuktikan apa pun
Referensi getenv milik PHP mendokumentasikan pembacaan langsung lingkungan proses, yang mengembalikan false saat nama itu tidak ada. Superglobal $_ENV diisi terpisah, dan direktif variables_order menentukan superglobal mana yang diisi.
Jika direktif itu menghilangkan E, $_ENV tetap kosong apa pun isi lingkungannya. Kode yang mengindeksnya lalu melaporkan variabel yang hilang padahal sebenarnya ada, dan penyelidikan mengarah ke OpenVPN sementara jawabannya ada di php.ini. Periksa direktif itu khusus untuk konfigurasi CLI, bukan untuk server web.
Membaca dengan getenv menghindari seluruh kelas kebingungan ini, dan skrip pembungkus yang membersihkan lingkungan sebelum memanggil interpreter memunculkannya lagi dalam bentuk lain.
Simpan asosiasi, bukan pembaruan baris
Putuskan nilai mana yang dibutuhkan catatan sebelum menulisnya. Jika tujuannya mencatat dari mana sesi berasal, simpan titik akhir luar dan beri label sebagai pengamatan. Jika tujuannya memetakan sesi ke alamat terowongan selama koneksi, simpan alamat pool dan kaitkan dengan sesi.
Perbarui berdasarkan identitas yang terautentikasi dan sesi saat ini, bukan berdasarkan setiap baris yang berbagi alamat terowongan, karena alamat pool dipakai ulang dan peristiwa pemutusan yang terlambat bisa menimpa data koneksi yang lebih baru. Tangani IPv6 secara eksplisit alih-alih diam-diam hanya menulis nilai IPv4. Baris dengan alamat luar NULL lebih baik daripada baris dengan alamat yang salah, karena yang pertama terlihat tidak lengkap.
Kaitkan penulisan ke pengenal sesi yang disediakan OpenVPN agar koneksi ulang membuat catatan baru alih-alih menyunting yang lama. Gunakan pernyataan berparameter dan akun dengan hanya izin yang dibutuhkan operasi. Hook berjalan dengan otoritas daemon, jadi kueri yang teledor adalah masalah yang lebih luas daripada satu baris log yang salah.
Diagnosis tanpa membuang lingkungan
Catat nama mana yang ada, tahap mana yang berjalan dan interpreter mana yang dipakai. Jangan cetak seluruh lingkungan, karena proses hook bisa mewarisi nilai tak berkaitan yang tidak seharusnya masuk ke berkas log.
Verifikasi satu koneksi dari ujung ke ujung: baca titik akhir luar, baca alamat yang dialokasikan, dan pastikan keduanya terhadap pandangan server sendiri tentang sesi itu. Setelah pasangan itu terkonfirmasi untuk satu klien, asosiasinya bisa dipercaya di tempat lain.