Mengapa hook firewall VPN menambahkan aturan yang sama dua kali
Menyambung ulang dapat menjalankan hook Anda lagi, jadi rancang untuk keadaan yang diinginkan: rantai milik sendiri, uji sebelum menyisipkan, satu perubahan terserialisasi, dan pembongkaran yang sempit.
Hook bekerja pertama kali, dan setelah tiga sambung ulang rantai menyimpan tiga salinan aturan yang sama. Tidak ada yang gagal dengan berisik; skrip hanya melakukan apa yang diperintahkan setiap kali dijalankan. Hook VPN adalah operasi konfigurasi yang dapat berjalan lebih dari sekali, jadi ia memerlukan pemilik, keadaan yang diinginkan, dan perubahan terserialisasi. Ikuti urutan itu dan duplikatnya berhenti.
Beri aturan seorang pemilik sebelum menulis satu pun
Putuskan rantai atau tabel mana yang dimiliki integrasi ini sebelum Anda menulis satu aturan pun. Rantai khusus yang dibuat dan dikosongkan oleh hook adalah bentuk kepemilikan paling jelas, karena pembersihan kemudian dapat menghapus rantai itu tanpa menyentuh kebijakan orang lain. Jika Anda harus menambahkan aturan ke rantai bersama, tandai dengan komentar agar pencarian nanti menemukan persis milik Anda. Kepemilikan membuat pembongkaran aman, dan pembongkaran adalah bagian yang gagal diam-diam.
iptables -N VPN_HOOK 2>/dev/null || true
iptables -C INPUT -j VPN_HOOK 2>/dev/null || iptables -I INPUT -j VPN_HOOK
iptables -S VPN_HOOK
Komentar di sini bukan hiasan. Itu adalah perbedaan antara menghapus aturan Anda dan menghapus aturan yang kebetulan terlihat serupa, dan ia bertahan di kumpulan aturan yang disimpan. Tulis komentar sekali dalam variabel dan gunakan string yang sama di setiap perintah yang menambah, menguji, atau menghapus.
Uji keadaan yang diinginkan alih-alih menambahkan lagi
Tuliskan apa yang harus ada selama terowongan aktif: antarmuka mana, sumber dan tujuan mana, protokol mana dan port mana. Lalu nyatakan setiap aturan sebagai uji yang diikuti penyisipan, sehingga eksekusi kedua menemukan aturan itu dan tidak melakukan apa pun. Perintah pemeriksaan keluar dengan nol saat aturan ada, dan itulah tepatnya sinyal yang dibutuhkan skrip. Referensi iptables mendokumentasikan bentuk pemeriksaan, penambahan, dan penyisipan yang digunakan di sini.
iptables -C VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT ||
iptables -A VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
Hati-hati dengan posisi. Memeriksa aturan dan menyisipkannya di kepala dapat memindahkan izin ke depan penolakan sengaja yang sebelumnya datang lebih dulu, sehingga eksekusi kedua mengubah perilaku meskipun tidak menambahkan apa pun. Tambahkan di akhir di dalam rantai Anda sendiri, dan kendalikan urutan lewat posisi lompatan ke rantai itu. Jika urutan di dalam rantai penting, bangun ulang rantai dari daftar yang diketahui alih-alih menambalnya aturan demi aturan.
Berhenti jika aturan yang Anda butuhkan tidak dapat dinyatakan sebagai uji yang stabil. Itu biasanya berarti keadaan yang diinginkan masih samar.
Serialkan perubahan alih-alih berharap perubahan itu bertahan
Dua pemanggilan hook dapat tumpang tindih, dan keduanya dapat melihat aturan yang tidak ada sebelum salah satunya menambahkannya. Opsi tunggu xtables membuat perintah menunggu kunci, tetapi tidak membuat urutan periksa-lalu-tambah menjadi atomik pada dua perintah. Serialkan seluruh operasi dengan kunci Anda sendiri, atau gunakan pengelola yang menerapkan batch yang dideklarasikan sebagai satu transaksi. nftables dapat melakukan yang terakhir, dan itulah salah satu alasan untuk memilihnya pada host yang menyediakannya.
flock /run/vpn-hook.lock /usr/local/sbin/vpn-firewall-apply
nft -f /etc/nftables/vpn-hook.nft
Mekanisme apa pun yang Anda pilih, jaga bagian kritis tetap singkat dan buat dapat dimasuki ulang: hook yang gagal di tengah harus aman dijalankan lagi. Catat hasilnya agar eksekusi berulang terlihat di jurnal alih-alih disimpulkan dari jumlah aturan. Jika dua supervisor berbeda dapat memanggil hook, perbaiki itu dulu; tidak ada kunci yang memperbaiki dua pemilik.
Bongkar hanya yang Anda miliki
Pembongkaran harus membedakan koneksi pengganti dari koneksi yang dipensiunkannya, dan harus bertahan dari peristiwa yang tidak pernah mendapat pembersihan yang rapi. Hapus dengan pengenal yang sama yang Anda gunakan untuk menambah, dan jangan pernah mengosongkan rantai bersama untuk menyederhanakan pembersihan. Setelah penghentian keras, jalankan pemeriksaan rekonsiliasi pada awal berikutnya alih-alih mengasumsikan hook bawah sudah berjalan.
iptables -D VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
iptables -F VPN_HOOK
ip -brief link show type tun
Masa hidup antarmuka juga termasuk dalam desain. Sambung ulang dapat membuat perangkat dengan nama berbeda, sehingga aturan yang mengunci nama terowongan kedua menjadi usang sementara masih terlihat sah. Utamakan identitas yang ditampilkan koneksi itu sendiri, dan baca ulang pada setiap eksekusi. Uji ketiga peristiwa secara terpisah: koneksi berulang, koneksi pengganti, dan penghentian. Lalu lintas yang diizinkan harus bertahan dari ketiganya tanpa duplikat, dan layanan yang tidak terkait harus tetap tidak tersentuh.
Penelusuran berakhir ketika hook memiliki pemilik, uji untuk setiap aturan yang ditambahkannya, satu jalur terserialisasi, dan pembongkaran yang hanya menghapus keadaannya sendiri. Hook yang aman dijalankan dua kali lebih bernilai daripada hook yang pintar sekali.