Jälgi üht päringut rongis olevast telefonist backendini, mis eksisteerib ainult privaatvõrgus. Telefon lahendab avaliku nime, ühendub avaliku aadressiga pordil 443 ja sooritab tavalise TLS-kätluse. Nginx võtab selle ühenduse vastu ja avab seejärel teise, täiesti eraldiseisva ühenduse aadressiga, kuhu ta pääseb ainult VPN-liidese kaudu. Telefoni juures ei muutu midagi ja telefon ei saa kunagi teada, et tunnel oli mängus.

Jälgi üht päringut läbi kahe ühenduse

Sisenev osa on avalik HTTP-tehing. Sellel on avalik nimi, avalik sertifikaat ja vastusetee, mis peab toimima iga aadressi jaoks, mis külastajal parasjagu on. Iga muudatus, mis seda teed häirib, rikub kõik külastajad korraga. Seetõttu on avalik osa see, millega sa kõige vähem katsetada tahad.

Väljuv osa on privaatne. Nginxist saab klient, see lahendab sisemise nime või kasutab fikseeritud aadressi ning jõuab teenuseni, mis keelduks internetist tulevast ühendusest.

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

Hoia need peas eraldi ja konfiguratsioon muutub ilmselgeks. Ühenda need ja lõpuks üritad panna avalikku klienti tunnelis osalema, ja just sealt tuleb suurem osa selle disaini segadusest. Privaatne osa võib olla habras. Avalik osa mitte.

Enne kui midagi sellest ehitad, kinnita, et rakenduse avaldamine on kavatsuslik. Töötav puhverserver on ka töötav paljastus, ja autentimismudel peab olema otsus, mitte kõrvalmõju.

Lüüsi nimi peab tunnelist üle elama

Nimede lahendamises on peen lõks. Kui privaatne DNS kirjutab üle sama nime, mida VPN-profiil kasutab oma lüüsi jaoks, võib taasühendus lõpuks proovida seda lüüsi läbida tunnelist, mille ta ise peaks looma. Klient vajab, et see nimi lahendataks enne, kui tunnel olemas on. Kui see lahendatakse alles tunnelis, ei saa ühendust üldse luua.

Kasuta lüüsi ja backendi jaoks erinevaid kinnitatud nimesid ja piira lahendaja poliitikat nii, et iga nimi lahenduks aadressiks, mida selle tarbija vajab. Rakenduse Host-päise muutmine ei aita siin, sest otsingu teeb VPN-klient.

Seejärel mõtle ulatusele. Frontend vajab marsruuti backendi aadressile ja peab ka jätkama avalikele klientidele vastamist. Täistunnel sellel hostil võib täita esimese nõude ja rikkuda teise.

Kus poliitika seda lubab, on tunnel konkreetsesse sihtkohta puhtam lahendus. Kus poliitika nõuab täistunnelit, kuulub frontend eraldi võrgukonteksti, mitte ei paigata tuntud külastajate jaoks ad hoc marsruutidega.

Kirjuta serveriplokk nii, et mõlemad osad kontrollivad

Eelda, et backend esitab sertifikaadi nimele backend.corp.example ja vastab privaatsel aadressil. Aadressile ühendumine, kontrollides samal ajal nime, on täpselt see, mille jaoks puhverserveri mooduli SNI- ja nimevalikud on mõeldud.

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;
    }
}

Iga ülaltoodud tee ja aadress on kohatäide. Olulised on need osad, mis hoiavad kontrolli sisse lülitatud: nimi, mida kontrollida, usalduskimp, mille vastu seda kontrollida, ja sügavus, mis vastab kinnitatud ahelale.

proxy_set_header Host app.example.com on tahtlik. Backend tuleks seadistada seda avalikku päritolu aktsepteerima ja see peaks usaldama edastatud päiseid ainult sellelt frontendilt. Kirjutada üle X-Forwarded-For kliendi aadressiga on õige ühe puhverserveri puhul ja vale ahela puhul, seega mitme puhverserveriga juurutus vajab oma usaldusväärsete aadresside korraldust.

Panna avalik päritolu käituma nii nagu avalik päritolu

Rakendus peaks väljastama absoluutseid URL-e, ümbersuunamisi ja küpsiseid avaliku päritolu jaoks. Kui ta suunab külastaja aadressile backend.corp.example, saadetakse see külastaja nimele, mida ta ei suuda lahendada.

Paranda see rakenduse toetatud välise URL-i seade ja ülevaadatud ümbersuunamispoliitika kaudu, mitte hostinimede ümberkirjutamisega vastusekehandites. Stringide asendamine suvalises sisus rikub allkirjastatud koormused ja tekitab vigu, mida on raske jälgida.

Küpsised väärivad sama hoolt. Privaatse nimega seotud küpsist ei saada kunagi brauser, kes teab ainult avalikku nime.

Kinnita ka, et Nginx saab avalikku socketit tõesti omada. Olemasolev veebiteenus pordil 443 peab liikuma või frontend peab elama mujal, sest kaks protsessi ei saa siduda sama aadressi ja porti.

Kontrolli iga osa seal, kus see tegelikult töötab

Valideeri konfiguratsioon paigaldatud parseriga enne igat uuestilaadimist, et trükiviga ei kukuks maha praegu teenindavat kuulajat.

Seejärel testi backendi osa frontendi hostist endast, samas võrgukontekstis, mida Nginx kasutab. Ping läbi tunneli tõestab kättesaadavust ja mitte midagi TLS-i, autoriseerimise ega rakenduse kohta.

Lõpuks tee värske avalik päring tõelisele hostinimele tavalise sertifikaadikontrolliga ja jälgi vastusetee, mitte ainult vastusekehandit.

Hoia mõlemad tähelepanekud juurutatud konfiguratsiooni juures ja pane kirja, mis juhtub, kui tunnel pole saadaval. Frontend peaks tagastama kontrollitud upstream-vea, mitte vaikselt laskuma teisele backendile, mida keegi pole dokumenteerinud. 502 selge logireaga on hea tulemus. Vahemällu salvestatud leht soovimatust päritolust ei ole.

Seotud artiklid