Nginx elöl, privát backend a VPN mögött
A böngésző az Nginxszel beszél, és az Nginx nyit egy második kapcsolatot az alagútba. Irányítsd mindkettőt, ellenőrizd mindkét tanúsítványt, és tartsd nyilvánosnak a nyilvános átirányításokat.
Kövess végig egy kérést egy vonaton ülő telefonból egy backendig, amely csak egy privát hálózaton belül létezik. A telefon felold egy nyilvános nevet, csatlakozik egy nyilvános címhez a 443-as porton, és végrehajt egy normál TLS kézfogást. Az Nginx elfogadja ezt a kapcsolatot, majd nyit egy második, teljesen különálló kapcsolatot egy címhez, amelyet csak VPN-interfészen keresztül ér el. A telefonon semmi sem változik, és a telefon soha nem tudja meg, hogy egy alagút is részt vett benne.
Egy kérés követése két kapcsolaton keresztül
A bejövő szakasz nyilvános HTTP-tranzakció. Van nyilvános neve, nyilvános tanúsítványa és egy válaszútvonala, amelynek működnie kell bármely címhez, amely éppen a látogatónál van. Minden változtatás, amely zavarja ezt az útvonalat, egyszerre töri el az összes látogatót. Ezért a nyilvános szakasz az, amelyen a legkevésbé akarsz kísérletezni.
A kimenő szakasz privát. Az Nginx ügyféllé válik, felold egy belső nevet vagy fix címet használ, és elér egy szolgáltatást, amely elutasítaná az internetről jövő kapcsolatot.
Public client -> frontend public address:443 (TLS, public name)
Frontend -> VPN private backend 10.40.0.20:8443 (TLS, private name)
Tartsd őket külön a fejedben, és a konfiguráció magától értetődővé válik. Vond össze őket, és végül megpróbálod rávenni egy nyilvános ügyfelet, hogy részt vegyen egy alagútban, és ebből származik a tervezés zavarának nagy része. A privát szakasz lehet törékeny. A nyilvános nem.
Mielőtt bármit is építenél ebből, erősítsd meg, hogy az alkalmazás közzététele szándékos. Egy működő proxy egyben működő kitettség is, és a hitelesítési modellnek döntésnek kell lennie, nem mellékhatásnak.
Az átjáró nevének túl kell élnie az alagutat
A névfeloldásban finom csapda rejlik. Ha a privát DNS felülírja ugyanazt a nevet, amelyet a VPN-profil a saját átjárójához használ, az újracsatlakozás végül azon az alagúton keresztül próbálhatja elérni az átjárót, amelyet éppen létre kellene hoznia. Az ügyfélnek arra van szüksége, hogy ez a név az alagút létezése előtt feloldódjon. Ha csak az alagúton belül oldódik fel, a kapcsolat soha nem épülhet fel.
Használj külön jóváhagyott neveket az átjáróhoz és a backendhez, és korlátozd a feloldó szabályzatát úgy, hogy minden név arra a címre oldódjon fel, amelyre a fogyasztójának szüksége van. Egy alkalmazás Host fejlécének módosítása itt semmit sem segít, mert a keresést a VPN-ügyfél végzi.
Utána gondolj a hatókörre. A frontendnek útvonalra van szüksége a backend címéhez, és továbbra is válaszolnia kell a nyilvános ügyfeleknek. Egy teljes alagút ezen a gazdagépen teljesítheti az első követelményt, és elronthatja a másodikat.
Ahol a szabályzat engedi, a konkrét célra szóló alagút a tisztább megoldás. Ahol a szabályzat teljes alagutat ír elő, a frontend külön hálózati környezetbe tartozik, ahelyett hogy ad hoc útvonalakkal foltoznák az ismert látogatókhoz.
Úgy megírni a kiszolgálóblokkot, hogy mindkét szakasz ellenőrizzen
Tegyük fel, hogy a backend tanúsítványt mutat a következőhöz: backend.corp.example és privát címen válaszol. Címhez kapcsolódni úgy, hogy közben nevet ellenőrzünk, pontosan erre valók a proxy modul SNI- és név-beállításai.
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;
}
}
A fenti útvonalak és címek mind helyőrzők. A fontos részek azok, amelyek bekapcsolva tartják az ellenőrzést: egy ellenőrizendő név, egy bizalmi köteg, amelyhez ellenőrizni, és egy mélység, amely megfelel a jóváhagyott láncnak.
proxy_set_header Host app.example.com szándékos. A backendet úgy kell beállítani, hogy elfogadja ezt a nyilvános eredetet, és csak ettől a frontendtől fogadja el a továbbított fejléceket. Felülírni a X-Forwarded-For címét az ügyfél címével egyetlen proxy esetén helyes, lánc esetén hibás, ezért a több proxyból álló telepítésnek saját megbízható címkezelésre van szüksége.
Úgy viselkedni a nyilvános eredettel, mint ami nyilvános
Az alkalmazásnak abszolút URL-eket, átirányításokat és sütiket kell kibocsátania a nyilvános eredethez. Ha egy látogatót a következőre irányít: backend.corp.example, az a látogató egy olyan névre kerül, amelyet nem tud feloldani.
Javítsd ezt az alkalmazás által támogatott külső URL-beállítással és egy átnézett átirányítási szabályzattal, ne pedig hosztnevek átírásával a választörzsekben. Karakterlánc-csere tetszőleges tartalomban eltöri az aláírt adatcsomagokat, és nehezen követhető hibákat okoz.
A sütik ugyanilyen gondosságot érdemelnek. A privát névhez kötött süti soha nem lesz elküldve egy böngésző által, amely csak a nyilvánosat ismeri.
Azt is erősítsd meg, hogy az Nginx valóban birtokolhatja a nyilvános socketet. Egy meglévő webes szolgáltatásnak a 443-on el kell költöznie, vagy a frontendnek máshol kell élnie, mert két folyamat nem kötheti ugyanazt a címet és portot.
Minden szakaszt ott ellenőrizni, ahol valóban fut
Érvényesítsd a konfigurációt a telepített elemzővel minden újratöltés előtt, hogy egy elírás ne döntse le az éppen kiszolgáló figyelőt.
Ezután teszteld a backend szakaszt magáról a frontend gazdagépről, ugyanabban a hálózati környezetben, amelyet az Nginx használ. Egy ping az alagúton keresztül bizonyítja az elérhetőséget, és semmit a TLS-ről, az engedélyezésről vagy az alkalmazásról.
Végül indíts friss nyilvános kérést a valódi hosztnévre normál tanúsítvány-ellenőrzéssel, és figyeld a válaszútvonalat, ne csak a választörzset.
Tartsd meg mindkét megfigyelést a telepített konfiguráció mellett, és jegyezd fel, mi történik, amikor az alagút nem elérhető. A frontendnek ellenőrzött upstream hibát kell visszaadnia, nem pedig csendben átváltania egy másik backendre, amelyet senki sem dokumentált. Egy 502 világos naplósorral jó eredmény. Gyorsítótárazott oldal nem szándékolt eredettől nem az.