Izinkan koneksi TLS passthrough di konteks stream NGINX
NGINX dapat menolak relay TCP TLS tanpa mengakhiri TLS. Letakkan aturan izin di stream, bukan di location HTTP, dan periksa alamat peer mana yang datang.
Meneruskan byte terenkripsi tanpa pernah memegang sertifikat adalah yang dilakukan relay TLS passthrough, dan pengaturan ini nyaman sekaligus sedikit membingungkan. Karena tidak ada yang didekripsi, tidak ada apa pun berbentuk HTTP untuk difilter, sehingga blok location biasa dan aturan aksesnya tidak berguna di sini. Keputusan yang tersedia bagi NGINX menyangkut koneksi itu sendiri: peer jaringan mana yang mengetuk, dan apakah peer itu harus diteruskan sama sekali.
Keputusan ada di stream, bukan HTTP
Dalam konteks stream, NGINX bekerja dengan sesi TCP. Ia melihat alamat peer koneksi dan dapat menerapkan aturan allow dan deny yang berurutan padanya sebelum byte apa pun mencapai backend. Itu keputusan penerimaan yang lengkap dan tidak memerlukan kunci privat, sertifikat, atau penguraian HTTP.
| Mechanism | What it decides | Where it lives |
|---|---|---|
| stream allow/deny | Whether this TCP peer is relayed | stream server block |
| ssl_preread map | Which backend a named connection goes to | stream, with the preread module |
| HTTP location rule | Whether an HTTP request is served | http server block |
Ketiga baris itu tidak pernah saling menggantikan. Menyalin direktif akses HTTP ke file mana pun yang menyebut port 443 tidak mengubah apa pun, karena server stream tidak pernah membaca konteks http.
Terima koneksi sebelum meneruskannya
Anggaplah ada instalasi yang sudah berjalan dengan modul stream dan stream-access tersedia, klien VPN menyimpan alamat sumber di 10.90.0.0/24, dan backend di 192.168.50.20:443 yang sudah menyajikan identitas HTTPS yang dimaksud.
stream {
server {
listen 443;
allow 10.90.0.0/24;
deny all;
proxy_pass 192.168.50.20:443;
}
}
Bacalah ini sebagai fragmen listener baru, bukan pengganti langsung konfigurasi yang berjalan. Tinjau listener dan include yang ada lebih dulu, karena listener kedua pada port yang sudah terikat gagal saat reload, bukan saat permintaan.
Perhatikan apa yang tidak ada: tidak ada listen ... ssl, tidak ada direktif sertifikat. NGINX meneruskan aliran terenkripsi, dan backend mengakhiri TLS serta menyajikan sertifikat yang divalidasi klien. Klien yang gagal di allowlist mendapatkan sesi TCP-nya ditolak, bukan halaman HTTP 403, dan alat apa pun yang mengharapkan kode status akan melaporkan sesuatu yang tidak berguna.
Apa yang dicakup allowlist dan apa yang tidak
Jika relay sudah memilih backend berdasarkan nama server, ssl_preread dan map dapat terus melakukan pekerjaan itu, asalkan modulnya tersedia. Nama tetap dipasok oleh klien, dan tidak ada dalam penyajian nama yang membuktikan klien telah bergabung dengan VPN.
Aturan contoh mencakup seluruh listener stream. Itu membuatnya tidak cocok untuk satu titik masuk yang melayani campuran situs publik dan situs khusus VPN, di mana pengecualian per nama akan diperlukan; listener terpisah biasanya lebih jelas daripada kebijakan yang bergantung pada nama yang tidak dapat dibaca siapa pun.
Dua celah lain layak disebut. Kecocokan prefiks tidak mengatakan apa pun tentang antarmuka mana paket itu datang, dan aturan HTTP di tempat lain tidak dapat membatasi listener ini. Keduanya adalah alasan untuk menjaga kebijakan ingress tingkat host tetap dalam gambaran alih-alih memperlakukan satu baris allow sebagai seluruh batas. Tuliskan batas itu sebagai dua kontrol yang harus sepakat, agar perubahan pada salah satunya ditinjau.
Alamat siapa yang sebenarnya dilihat NGINX?
Penyeimbang beban, proxy lain, atau source NAT dapat menempatkan perantara di depan NGINX, sehingga peer yang diamati bukan alamat internal klien VPN. Periksa jalur sebenarnya sebelum memilih prefiks, karena allowlist yang ditulis untuk alamat yang salah entah mengizinkan semua orang di belakang penerjemah atau tidak seorang pun.
Protokol PROXY dan penanganan IP sebenarnya adalah jawaban yang sah, dan hanya boleh dikonfigurasi untuk pengirim yang kompatibel dan secara eksplisit tepercaya. Kedua mekanisme percaya pada apa yang dikatakan pengirim, dan itulah sebabnya daftar pengirim harus singkat. Mempercayai header identitas dari klien internet mana pun tidak membuat informasi sumber kembali tepercaya; itu mengubah penolakan yang benar menjadi penerimaan palsu.
Uji kedua hasil sebelum reload
Validasi konfigurasi, lakukan reload, lalu uji dua kali: sesi baru yang diizinkan yang harus berfungsi, dan yang ditolak yang tidak boleh. Pertahankan verifikasi sertifikat backend normal dalam uji yang diizinkan, karena relay yang terhubung tetapi tidak dapat memvalidasi backend telah memperbaiki satu masalah dan menciptakan masalah lain.
nginx -t
ss -tnp | grep ':443'
Periksa juga rute ke backend dan balasannya secara terpisah. Lolos allowlist hanya membuktikan bahwa NGINX menerima sesi; itu tidak dapat membuat backend yang tidak terjangkau menjawab, dan tidak dapat memperbaiki jalur balik yang hilang sebelum Anda mulai.