Proč Port-Share dělá ze všech návštěvníků webu localhost
Backend vidí hop přesměrování, ne prohlížeč. Zjistěte, kde se ztrácí zdrojová adresa, a pak rozhodněte, která komponenta za ni smí ručit.
Každý řádek v přístupovém logu ukazuje stejnou adresu loopback, zatímco stránka se načítá a certifikát se ověřuje správně. Nic není rozbité ve smyslu nedostupnosti, a právě proto to vydrží měsíce. Rozbilo se přiřazení: webový backend zaznamenává adresu hopu, který spojení přesměroval, a každé následné rozhodnutí, které logu věřilo, zdědilo stejnou špatnou odpověď.
Kontroly níže jdou od kabelu dovnitř. Zastavte se u první, která vysvětluje hodnotu, kterou vidíte, protože každý další krok předpokládá, že předchozí už platí. Žádná z nich nevyžaduje hádat konfiguraci front-endu.
Sledujte dvě spojení, ne řádek logu
Port-Share multiplexuje dva protokoly na jednom TCP listeneru. OpenVPN zkontroluje první bajty příchozího spojení, ponechá si ho, když vypadá jako jeho vlastní protokol, a vše ostatní předá druhému cíli. Tím cílem je obvykle webový server na stejném hostu, takže přijatý socket webového serveru má jako protějšek proces OpenVPN.
ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'
První příkaz ukazuje, kdo vlastní veřejný listener. Druhý ukazuje spojení přicházející na port backendu a adresa jejich protějšku je ta, kterou vypíše přístupový log. Pokud je tím protějškem loopback, log je přesný a informace se ztratila o vrstvu dřív. Přejmenování pole v logu nebo zapnutí modulu pro IP klienta nezíská zpět adresu, kterou spojení nikdy neneslo.
Tohle je kontrola, která rozhoduje všechno ostatní. Pokud je protějškem backendu adresa prohlížeče, sdílení portu není váš problém a formát logu ano.
Přesměrování transportu není vkládání hlaviček
Přesměrovávač přenáší bajty. Neparsuje HTTP, takže nemůže vložit hlavičku do požadavku, který nikdy nečte jako požadavek, a nemůže nic přidat do TLS streamu, který propouští nedotčený. Modul očekávající proxy hlavičku bude dál čekat na takovou, kterou žádná komponenta nevytváří.
Původní adresu mohou nést dva mechanismy a oba vyžadují souhlas na obou stranách. Protokol PROXY přidává na začátek spojení malou hlavičku a backend musí být nakonfigurován, aby ji očekával; backend, který ji neočekává, bude tyto bajty považovat za začátek požadavku a selže matoucím způsobem. Důvěryhodné proxy hlavičky jako X-Forwarded-For fungují, když je nastavuje proxy, která rozumí HTTP, a backendu se řekne, kteří protějšci je smějí tvrdit.
Ani jedno není automatické a ani jedno není ve výchozím nastavení bezpečné. Backend, který věří každé příchozí přesměrované hlavičce, umožňuje klientovi zvolit si vlastní adresu, což mění nepřesnost v logu v obejití kontroly přístupu. Spusťte ukázku jednou na testovacím hostu, než nějaké hlavičce na produkční cestě uvěříte.
curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3
Volitelný adresář mapování zdrojů
Sdílení portu má volitelný argument adresáře, který zaznamenává mapování mezi původní zdrojovou adresou a přesměrovávacím spojením, na platformách, kde je funkce implementována. Očekává se, že webová strana toto mapování vyhledá; není to hlavička a nevkládá se do požadavku.
Ten návrh stojí za to znát, protože vysvětluje, proč některá nasazení hlásí skutečné adresy a jiná ne, při zdánlivě stejné konfiguraci front-endu. Rozdíl je na přijímající straně a obvykle žije v modulu nebo záplatě, kterou většina balených webových serverů ve výchozím nastavení nezapíná. Přečtěte si dokumentaci svého webového serveru, jaký přesný hook nabízí, a potvrďte, že modul je načtený, místo abyste to předpokládali.
Pokud touto cestou půjdete, berte to jako integraci o dvou polovinách: mapování, které zapisuje přesměrovávač, a vyhledávání, které provádí backend. Ověřte obojí a potvrďte, že adresář přežije restart a na vytíženém listeneru neroste bez omezení.
Rozhodněte, která komponenta za adresu ručí
Než změníte konfiguraci, pojmenujte komponentu, která smí tvrdit adresu klienta, a komponenty, které jí smějí věřit. Jediná zapsaná odpověď brání obvyklému posunu, kdy tři různé vrstvy věří každá jinému zdroji.
Tři návrhy pokrývají většinu potřeb. Nechte veřejný listener a webový listener oddělené, aby webový server viděl skutečné protějšky a žádný problém s přiřazením neexistoval. Postavte dopředu reverzní proxy, která rozumí HTTP, ukončete nebo parsujte požadavek tam a nechte ji nastavit přesměrovanou hlavičku pro backend, který věří jen této proxy. Nebo sdílení portu ponechte a přijměte, že logy ukazují hop, s pravidly přístupu psanými proti identitě aplikace, ne proti adrese.
Co nefunguje, je považovat přesměrovanou adresu loopback za důkaz, že požadavek vznikl na tomto stroji. Ten závěr je přesně obrácený: adresa je přítomná právě proto, že spojení vytvořila místní komponenta. Pravidlo napsané takto pustí každého, kdo se ke listeneru dostane.
Testujte pravidlo, ne stránku
Stránka, která se načte, dokazuje, že cesta přesměrování funguje, a o přiřazení neříká nic. Testujte konzumenta adresy: pravidlo přístupu, limit rychlosti, záznam auditu, geo vyhledávání.
curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log
Porovnejte povolený externí požadavek se záznamy front-endu i backendu a potvrďte, že pravidlo, které má odmítnout, stále odmítá, a to, které má pustit, stále pouští. Pokud je řádek logu správný, ale pravidlo se stále chová, jako by všichni byli místní, čte pravidlo jiné pole než to, které jste opravili.
Skončete tím, že řetězec přiřazení zapíšete do poznámek k nasazení: který listener, který přesměrovávač, která hlavička nebo mapování a který backend je nakonfigurován mu věřit. Příští člověk, který přečte řádek logu, bude potřebovat všechny čtyři, a nepřítomnost této poznámky je způsob, jakým se stejný tiket za rok znovu otevře. Mějte ji vedle konfigurace, ne ve vlákně chatu.