Firewall VPS: buka hanya port VPN, lalu buktikan
Satu port harus tetap publik atau tidak ada klien yang terhubung. Tolak sisanya, pisahkan penerusan dari masukan, dan sisakan jalur pemulihan yang sudah Anda uji sebelumnya.
Firewall yang hanya mengizinkan port VPN bukan satu aturan. Itu tiga keputusan terpisah yang kebetulan menyangkut nomor port yang sama: rantai masukan menentukan apa yang boleh mencapai proses lokal, rantai penerusan menentukan apa yang boleh melewati host atas nama klien tunnel, dan tabel NAT menulis ulang alamat sumber saat keluar. Salah satu saja keliru dan hasilnya jarang berupa gangguan yang bersih. Anda mendapat host yang menerima klien tetapi tidak memuat apa pun, atau host yang tampak tertutup sampai seseorang membaca urutan rantai.
Satu-satunya port yang tidak boleh ditutup
Pendengar VPN harus menerima koneksi dari alamat yang tidak dapat Anda prediksi, jadi menurut definisi ia layanan publik. Itulah satu-satunya pengecualian yang menjadi dasar rancangan ini: satu port UDP untuk OpenVPN, satu port UDP untuk WireGuard, satu port TCP untuk VPN SSL. Sisanya berada di balik tunnel, artinya layanan aplikasi sebaiknya mengikat ke alamat tunnel atau loopback, bukan ke semua antarmuka.
Mengikat, bagaimanapun, bukan penegakan. Proses yang terikat ke 0.0.0.0 hanya dapat dijangkau bila ada aturan yang mengizinkannya, dan kebijakan bawaan adalah cadangan bagi lalu lintas yang tidak cocok dengan aturan mana pun, bukan aturan yang mengatur port. Penerimaan yang diletakkan di atas penolakan Anda tetap penerimaan, dan memindahkan layanan dari alamat publik adalah perbaikan tersendiri, bukan pengganti rantai.
Masukan, penerusan, dan NAT menjawab pertanyaan berbeda
Lalu lintas masukan ditujukan ke host itu sendiri, jadi di sanalah pendengar VPN dan jalur administratif berada. Lalu lintas penerusan melewati host, dan klien tunnel membutuhkannya bersama net.ipv4.ip_forward=1. Konfigurasi klasik yang setengah rusak mengizinkan aliran keluar dan melupakan arah balik, sehingga klien menyelesaikan jabat tangan lalu tidak ada yang dimuat; aturan conntrack untuk lalu lintas yang terbentuk dan terkait menutup arah itu.
NAT adalah pertanyaan ketiga. Tanpa penulisan ulang di postrouting, paket yang diteruskan keluar dengan sumber privat tunnel dan dibuang di hulu, karena tidak ada jaringan di luar host yang tahu cara merutekan kumpulan itu kembali. Prefiks sumber pada aturan itu harus cocok dengan kumpulan VPN, bukan alamat host sendiri, dan hal yang sama berlaku untuk aturan penerusan yang menyebut subnet klien.
IPv6 adalah kebijakan kedua, bukan renungan belakangan. Host dengan rantai IPv4 yang ketat dan kebijakan ip6tables yang terbuka belum menutup apa pun; layanan masih dapat dijangkau lewat keluarga satunya. Entah cerminkan kumpulan aturan dengan ip6tables atau matikan IPv6 dengan sengaja pada antarmuka publik, dan tuliskan mana yang Anda pilih.
Dasar yang bisa dibaca dalam sekali jalan
Mulailah dari penolakan, lalu tambahkan hanya yang dibutuhkan host. Pertama loopback dan balasan, lalu jalur administratif, lalu pendengar tunnel, lalu kebijakan penerusan bagi klien:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m conntrack --ctstate NEW -j ACCEPT
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADENama antarmuka, port, dan kumpulan adalah penampung; bacalah dari server alih-alih menyalinnya. Menyimpan hasilnya sama pentingnya dengan menulisnya, karena kumpulan aturan yang hanya hidup di memori hilang pada reboot berikutnya dan diam-diam membuka kembali host. Jadikan ia menetap dengan mekanisme distribusi, dan simpan salinan di luar mesin untuk hari ketika mesin tidak mau boot.
Menutup port terakhir tanpa kehilangan host
Ada jebakan dalam rancangan. Jika SSH hanya ada melalui tunnel, layanan VPN yang gagal akan membawa SSH bersamanya, dan satu-satunya jalan kembali mungkin konsol yang belum pernah Anda buka. Sebelum menutup port publik terakhir, pastikan konsol itu ada dan benar-benar dapat Anda gunakan, atau pertahankan satu jalur administratif sempit yang tidak bergantung pada tunnel: SSH dari alamat tetap, hanya kunci, autentikasi kata sandi mati.
Terapkan perubahan dari sesi yang sudah terbentuk, bukan lewat koneksi yang akan Anda saring. Jadwalkan pengembalian agar kesalahan kedaluwarsa alih-alih menjadi permanen, misalnya tugas systemd-run --on-active=10min yang memulihkan kumpulan aturan sebelumnya, dan biarkan sesi SSH kedua terbuka selama Anda menguji yang pertama. Lalu pastikan tugas pengembalian benar-benar berjalan, karena pemulihan yang tidak diuji sama dengan tidak ada pemulihan.
Buktikan jalurnya, bukan skripnya
Baca aturan yang dimuat, bukan berkas yang seharusnya memuatnya. Dari host luar yang sah, pastikan bahwa hanya port yang dimaksud yang menjawab; dari dalam tunnel, pastikan layanan yang ingin Anda terbitkan dapat dijangkau. Kebijakan tolak-bawaan yang juga memblokir lalu lintas tunnel tampak identik dengan penguncian yang berfungsi sampai seseorang mencoba memakainya.
iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr showCatat port yang diizinkan, kumpulan klien, antarmuka tunnel, sumber administratif, dan prosedur konsol di samping konfigurasi. Perubahan berikutnya pada kumpulan atau nama antarmuka harus dicocokkan di filter maupun aturan NAT, atau host kembali ke keadaan setengah terbuka tanpa ada yang menyadarinya.
Satu kebiasaan lebih bernilai daripada kumpulan aturan: setelah setiap perubahan, buktikan jalur penerusan dengan permintaan klien dan buktikan jalur pemulihan dengan sesi kedua. Penguncian yang belum Anda pakai hanyalah hipotesis.