Sekvu unu peton de telefono en trajno ĝis malantaŭaĵo, kiu ekzistas nur ene de privata reto. La telefono solvas publikan nomon, konektiĝas al publika adreso sur pordo 443 kaj kompletigas normalan TLS-manpremon. Nginx akceptas tiun konekton kaj poste malfermas duan, tute apartan, al adreso, kiun ĝi atingas nur tra VPN-interfaco. Nenio pri la telefono ŝanĝiĝas, kaj la telefono neniam ekscias, ke tunelo partoprenis.

Sekvi unu peton tra du konektoj

La envena parto estas publika HTTP-transakcio. Ĝi havas publikan nomon, publikan atestilon kaj respondan vojon, kiu devas funkcii por ajna adreso, kiun la vizitanto hazarde havas. Ĉiu ŝanĝo, kiu perturbas tiun vojon, rompas ĉiujn vizitantojn samtempe. Tial la publika parto estas tiu, ĉe kiu vi plej malmulte volas eksperimenti.

La elvena parto estas privata. Nginx fariĝas kliento, solvas internan nomon aŭ uzas fiksan adreson, kaj atingas servon, kiu rifuzus konekton el la interreto.

Public client  -> frontend public address:443   (TLS, public name)
Frontend       -> VPN private backend 10.40.0.20:8443  (TLS, private name)

Tenu ilin aparte en la kapo kaj la agordo fariĝos evidenta. Kunfandu ilin, kaj vi finos provante igi publikan klienton partopreni en tunelo, kaj ĝuste de tio venas la plej granda parto de la konfuzo en ĉi tiu dezajno. La privata parto rajtas esti fragila. La publika ne.

Antaŭ ol konstrui ion ajn el tio, konfirmu, ke publikigo de la aplikaĵo estas intenca. Funkcianta prokura servilo ankaŭ estas funkcianta elmeto, kaj la aŭtentiga modelo devas esti decido, ne flanka efiko.

La pordega nomo devas postvivi la tunelon

Subtila kaptilo kuŝas en nomosolvado. Se privata DNS anstataŭigas la saman nomon, kiun la VPN-profila uzas por sia propra pordego, rekonekto povas fini provante atingi tiun pordegon tra la tunelo, kiun ĝi mem devus starigi. La kliento bezonas, ke tiu nomo solviĝu antaŭ ol la tunelo ekzistas. Post kiam ĝi solviĝas ene de la tunelo, la konekto neniam povas esti konstruita.

Uzu apartajn aprobitajn nomojn por la pordego kaj la malantaŭaĵo, kaj limigu la solvan politikon tiel, ke ĉiu nomo solviĝu al la adreso, kiun ĝia konsumanto bezonas. Ŝanĝi la kap-kaplinion Host de aplikaĵo tute ne helpas ĉi tie, ĉar la VPN-kliento faras la solvon.

Poste pensu pri la amplekso. La fronto bezonas itineron al la malantaŭa adreso, kaj ĝi ankaŭ devas daŭre respondi al publikaj klientoj. Plena tunelo sur tiu gastiganto povas plenumi la unuan postulon kaj rompi la duan.

Kie la politiko permesas, tunelo al specifa celo estas la pli pura dezajno. Kie la politiko devigas plenan tunelon, la fronto apartenas al aparta reta kunteksto anstataŭ esti flikita per okazaj itineroj por konataj vizitantoj.

Skribi la serversekcion tiel, ke ambaŭ partoj kontrolu

Supozu, ke la malantaŭaĵo prezentas atestilon por backend.corp.example kaj respondas sur privata adreso. Konekti al adreso dum kontrolado de nomo estas ĝuste la celo de la SNI- kaj nom-opcioj de la prokura modulo.

upstream private_app {
    server 10.40.0.20:8443;
}

server {
    listen 443 ssl;
    server_name app.example.com;

    ssl_certificate     /etc/nginx/tls/app-fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/app-key.pem;

    location / {
        proxy_pass https://private_app;
        proxy_ssl_server_name on;
        proxy_ssl_name backend.corp.example;
        proxy_ssl_trusted_certificate /etc/nginx/trust/backend-ca.pem;
        proxy_ssl_verify on;
        proxy_ssl_verify_depth 3;

        proxy_set_header Host app.example.com;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

Ĉiu vojo kaj adreso supre estas anstataŭigilo. La gravaj partoj estas tiuj, kiuj tenas la kontroladon ŝaltita: nomo por kontroli, fida pakaĵo por kontroli ĝin kaj profundo, kiu kongruas kun la aprobita ĉeno.

proxy_set_header Host app.example.com estas intenca. La malantaŭaĵo devus esti agordita akcepti tiun publikan originon, kaj ĝi devus fidi plusenditajn kapliniojn nur de ĉi tiu fronto. Anstataŭigi X-Forwarded-For per la klienta adreso estas ĝuste por unuopa prokura servilo kaj malĝuste por ĉeno, do pluroka prokura deplojo bezonas sian propran aranĝon de fidindaj adresoj.

Igi la publikan originon konduti kiel tia

La aplikaĵo devus elsendi absolutajn URL-ojn, alidirektadojn kaj kuketojn por la publika origino. Se ĝi alidirektas vizitanton al backend.corp.example, tiu vizitanto estas sendita al nomo, kiun li ne povas solvi.

Riparu tion per la subtenata agordo de ekstera URL de la aplikaĵo kaj reviziita alidirekta politiko, ne per reverkado de gastignomoj en respondaj korpoj. Ĉena anstataŭigo en arbitra enhavo rompas subskribitajn ŝarĝojn kaj kreas cimojn, kiujn malfacilas spuri.

Kuketoj meritas la saman zorgon. Kuketo limigita al la privata nomo neniam estos sendita de retumilo, kiu konas nur la publikan.

Ankaŭ konfirmu, ke Nginx povas efektive posedi la publikan konektilon. Ekzistanta reta servizo sur 443 devas translokiĝi aŭ la fronto devas loĝi aliloke, ĉar du procezoj ne povas ligi la saman adreson kaj pordon.

Kontroli ĉiun parton tie, kie ĝi efektive funkcias

Validigu la agordon per la instalita analizilo antaŭ ajna reŝargo, por ke tajperaro ne faligu la aŭskultilon, kiu nun servas.

Poste testu la malantaŭan parton de la fronta gastiganto mem, en la sama reta kunteksto, kiun Nginx uzas. Ping tra la tunelo pruvas atingeblon kaj nenion pri TLS, rajtigo aŭ la aplikaĵo.

Fine faru freŝan publikan peton al la reala gastignomo kun normala atestila kontrolado, kaj observu la respondan vojon anstataŭ nur la respondan korpon.

Konservu ambaŭ observojn kune kun la deplojita agordo, kaj notu, kio okazas, kiam la tunelo ne disponeblas. La fronto devus redoni kontrolitan malantaŭan eraron, ne silente fali al alia malantaŭaĵo, kiun neniu dokumentis. 502 kun klara loga linio estas bona rezulto. Kaŝmemorigita paĝo de neintencita origino ne estas.

Rilataj artikoloj