Plusendi ĉifritajn bitokojn sen iam teni la atestilon estas tio, kion faras TLS-passthrough-relajo, kaj la aranĝo estas oportuna kaj iom konfuza samtempe. Ĉar nenio malĉifriĝas, ekzistas nenio HTTP-forma por filtri, do la kutima location-bloko kaj ĝiaj alirreguloj estas senutilaj ĉi tie. La decido, kiun NGINX povas fari, koncernas la konekton mem: kiu reta peer frapis, kaj ĉu tiu peer entute plusendu.

La decido apartenas al stream, ne al HTTP

En la stream-kunteksto NGINX laboras kun TCP-sesioj. Ĝi vidas la peer-adreson de la konekto kaj povas apliki ordigitajn allow- kaj deny-regulojn al ĝi antaŭ ol iu bitoko atingas la backend. Tio estas kompleta akcepta decido, kaj ĝi postulas neniun privatan ŝlosilon, neniun atestilon kaj neniun HTTP-analizon.

MechanismWhat it decidesWhere it lives
stream allow/denyWhether this TCP peer is relayedstream server block
ssl_preread mapWhich backend a named connection goes tostream, with the preread module
HTTP location ruleWhether an HTTP request is servedhttp server block

Tiuj tri vicoj neniam anstataŭigas unu la alian. Kopii HTTP-alirdirektivon en tiun dosieron, kiu mencias pordon 443, ŝanĝas nenion, ĉar la stream-servilo neniam legas la http-kuntekston.

Akceptu la konekton antaŭ ol plusendi ĝin

Supozu ekzistantan instalon kun la moduloj stream kaj stream-access disponeblaj, VPN-klientoj tenas fontadresojn en 10.90.0.0/24, kaj backend ĉe 192.168.50.20:443 jam servas la celitan HTTPS-identecon.

stream {
    server {
        listen 443;

        allow 10.90.0.0/24;
        deny all;

        proxy_pass 192.168.50.20:443;
    }
}

Legu tion kiel fragmenton de nova listener, ne kiel rektan anstataŭon de funkcianta agordo. Unue revizu la ekzistantajn listener-ojn kaj include-ojn, ĉar dua listener sur jam okupita pordo malsukcesas ĉe reload, ne ĉe petotempo.

Rimarku, kio mankas: neniu listen ... ssl, neniu atestila direktivo. NGINX plusendas la ĉifritan fluon, kaj la backend finas TLS kaj prezentas la atestilon, kiun la kliento validigas. Kliento, kiu malsukcesas la allowlist, ricevas malakceptitan TCP-sesion, ne HTTP 403-paĝon, kaj ajna ilo, kiu atendas statkodon, raportos ion senutilan.

Kion la allowlist kovras kaj kion ne

Se la relajo jam elektas backend-ojn laŭ servila nomo, ssl_preread kaj map povas daŭrigi tiun laboron, kondiĉe ke la modulo estas disponebla. La nomon ankoraŭ provizas la kliento, kaj nenio en prezenti nomon pruvas, ke la kliento aliĝis al la VPN.

La ekzempla regulo kovras la tutan stream-listener. Tio faras ĝin netaŭga por unu enirpunkto, kiu servas miksaĵon de publikaj kaj nur-VPN-ejoj, kie oni bezonus escepton laŭ nomo; apartaj listener-oj kutime estas pli klaraj ol nomdependa politiko, kiun neniu povas legi.

Indas nomi du pliajn mankojn. Prefiksa kongruo diras nenion pri tio, per kiu interfaco la paketo alvenis, kaj HTTP-regulo aliloke ne povas limigi ĉi tiun listener. Ambaŭ estas kialoj teni la enirpolitikon je gastiga nivelo en la bildo anstataŭ trakti unu allow-linion kiel la tutan limon. Skribu la limon kiel du kontrolojn, kiuj devas kongrui, por ke ŝanĝo en iu ajn el ili estu reviziata.

Kies adreson NGINX fakte vidas?

Ŝarĝobalancilo, alia proxy aŭ source NAT povas meti peranton antaŭ NGINX, do la peer, kiun ĝi vidas, ne estas la interna adreso de la VPN-kliento. Esploru la realan vojon antaŭ ol elekti prefikson, ĉar allowlist skribita por malĝusta adreso aŭ permesas ĉiujn malantaŭ la tradukilo aŭ neniun.

La protokolo PROXY kaj traktado de reala IP estas legitimaj respondoj, kaj ili konfiguru nur por kongruaj, eksplicite fidataj sendantoj. Ambaŭ mekanismoj kredas tion, kion diras la sendanto, kaj ĝuste tial la sendolisto devas esti mallonga. Fidi identecan kaplinion de iu ajn interreta kliento ne refaras la fontinformojn fidindaj; ĝi transformas ĝustan rifuzon en falsitan akcepton.

Testu ambaŭ rezultojn antaŭ reload

Validigu la agordon, reload, poste testu dufoje: nova permesita sesio, kiu devas funkcii, kaj rifuzita, kiu ne devas. Konservu la normalan backend-atestilvalidigon en la permesita testo, ĉar relajo, kiu konektas sed ne povas validigi la backend, solvis unu problemon kaj kreis alian.

nginx -t
ss -tnp | grep ':443'

Kontrolu ankaŭ la backend-vojon kaj la respondon aparte. Trapasi la allowlist pruvas nur, ke NGINX akceptis la sesion; ĝi ne povas igi neatingeblan backend respondi, kaj ĝi ne povas ripari return-vojon, kiu mankis antaŭ ol vi komencis.

Rilataj artikoloj