Prečo Port-Share robí zo všetkých návštevníkov webu localhost
Backend vidí skok presmerovania, nie prehliadač. Skontrolujte, kde sa stráca zdrojová adresa, a potom rozhodnite, ktorý komponent za ňu smie ručiť.
Každý riadok v prístupovom logu ukazuje rovnakú adresu loopback, zatiaľ čo stránka sa načíta a certifikát sa overí správne. Nič nie je pokazené v zmysle nedostupnosti, a práve preto to vydrží mesiace. Pokazilo sa priradenie: webový backend zaznamenáva adresu skoku, ktorý spojenie presmeroval, a každé neskoršie rozhodnutie, ktoré logu verilo, zdedilo tú istú nesprávnu odpoveď.
Kontroly nižšie idú od kábla dovnútra. Zastavte sa pri prvej, ktorá vysvetľuje hodnotu, ktorú vidíte, pretože každý ďalší krok predpokladá, že predchádzajúce už platia. Žiadna z nich nevyžaduje hádať konfiguráciu front-endu.
Sledujte dve spojenia, nie riadok logu
Port-Share multiplexuje dva protokoly na jednom TCP listeneri. OpenVPN skontroluje prvé bajty prichádzajúceho spojenia, ponechá si ho, keď vyzerá ako jeho vlastný protokol, a všetko ostatné odovzdá druhému cieľu. Tým cieľom je zvyčajne webový server na rovnakom hoste, takže prijatý socket webového servera má ako partnera proces OpenVPN.
ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'
Prvý príkaz ukazuje, kto vlastní verejný listener. Druhý ukazuje spojenia prichádzajúce na port backendu a adresa ich partnera je tá, ktorú vypíše prístupový log. Ak je tým partnerom loopback, log je presný a informácia sa stratila o vrstvu skôr. Premenovanie poľa v logu alebo zapnutie modulu pre IP klienta nezíska späť adresu, ktorú spojenie nikdy neneslo.
Toto je kontrola, ktorá rozhoduje všetko ostatné. Ak je partnerom backendu adresa prehliadača, zdieľanie portu nie je váš problém a formát logu áno.
Presmerovanie transportu nie je vkladanie hlavičiek
Presmerovávač prenáša bajty. Neparsuje HTTP, takže nemôže vložiť hlavičku do požiadavky, ktorú nikdy nečíta ako požiadavku, a nemôže nič pridať do TLS toku, ktorý prepúšťa nedotknutý. Modul očakávajúci proxy hlavičku bude ďalej čakať na takú, ktorú žiadny komponent nevytvára.
Pôvodnú adresu môžu niesť dva mechanizmy a oba vyžadujú súhlas na oboch stranách. Protokol PROXY pridáva na začiatok spojenia malú hlavičku a backend musí byť nakonfigurovaný, aby ju očakával; backend, ktorý ju neočakáva, bude tie bajty považovať za začiatok požiadavky a zlyhá matúcim spôsobom. Dôveryhodné proxy hlavičky ako X-Forwarded-For fungujú, keď ich nastaví proxy, ktorá rozumie HTTP, a backendu sa povie, ktorí partneri ich smú tvrdiť.
Ani jedno nie je automatické a ani jedno nie je predvolene bezpečné. Backend, ktorý verí každej prichádzajúcej presmerovanej hlavičke, umožňuje klientovi zvoliť si vlastnú adresu, čo mení nepresnosť v logu na obchádzanie kontroly prístupu. Spustite ukážku raz na testovacom hoste, skôr než uveríte nejakej hlavičke na produkčnej ceste.
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
Voliteľný adresár mapovania zdrojov
Zdieľanie portu má voliteľný argument adresára, ktorý zaznamenáva mapovanie medzi pôvodnou zdrojovou adresou a presmerovacím spojením, na platformách, kde je funkcia implementovaná. Očakáva sa, že webová strana toto mapovanie bude konzultovať; nie je to hlavička a nevkladá sa do požiadavky.
Ten dizajn stojí za to poznať, pretože vysvetľuje, prečo niektoré nasadenia hlásia skutočné adresy a iné nie, pri zdanlivo identickej konfigurácii front-endu. Rozdiel je na prijímajúcej strane a zvyčajne žije v module alebo záplate, ktorú väčšina balených webových serverov predvolene nezapína. Prečítajte si dokumentáciu svojho webového servera, aký presný hook ponúka, a potvrďte, že modul je načítaný, namiesto toho, aby ste to predpokladali.
Ak pôjdete touto cestou, berte to ako integráciu dvoch polovíc: mapovanie, ktoré zapisuje presmerovávač, a vyhľadávanie, ktoré robí backend. Overte oboje a potvrďte, že adresár prežije reštart a na vyťaženom listeneri nerastie bez obmedzenia.
Rozhodnite, ktorý komponent za adresu ručí
Pred zmenou konfigurácie pomenujte komponent, ktorému je dovolené tvrdiť adresu klienta, a komponenty, ktorým je dovolené tomu veriť. Jedna zapísaná odpoveď bráni obvyklému posunu, keď tri rôzne vrstvy veria každá inému zdroju.
Tri dizajny pokrývajú väčšinu potrieb. Nechajte verejný listener a webový listener oddelené, aby webový server videl skutočných partnerov a nevznikol problém s priradením. Postavte dopredu reverznú proxy, ktorá rozumie HTTP, ukončite alebo parsujte požiadavku tam a nechajte ju nastaviť presmerovanú hlavičku pre backend, ktorý verí len tejto proxy. Alebo ponechajte zdieľanie portu a prijmite, že logy ukazujú skok, s pravidlami prístupu písanými proti identite aplikácie, nie proti adrese.
Čo nefunguje, je považovať presmerovanú adresu loopback za dôkaz, že požiadavka vznikla na tomto stroji. Ten záver je presne opačný: adresa je prítomná práve preto, že spojenie vytvoril miestny komponent. Pravidlo napísané takto pustí každého, kto sa k listeneru dostane.
Testujte pravidlo, nie stránku
Stránka, ktorá sa načíta, dokazuje, že cesta presmerovania funguje, a o priradení nehovorí nič. Testujte konzumenta adresy: pravidlo prístupu, limit rýchlosti, záznam auditu, geo vyhľadávanie.
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
Porovnajte povolenú externú požiadavku so záznamami front-endu aj backendu a potvrďte, že pravidlo, ktoré má odmietnuť, stále odmieta, a to, ktoré má pustiť, stále púšťa. Ak je riadok logu správny, ale pravidlo sa stále správa, akoby všetci boli miestni, pravidlo číta iné pole než to, ktoré ste opravili.
Skončite tým, že reťazec priradenia zapíšete do poznámok k nasadeniu: ktorý listener, ktorý presmerovávač, ktorá hlavička alebo mapovanie a ktorý backend je nakonfigurovaný, aby mu veril. Ďalší človek, ktorý prečíta riadok logu, bude potrebovať všetky štyri, a neprítomnosť tejto poznámky je dôvod, prečo sa ten istý tiket o rok znova otvorí. Majte ju vedľa konfigurácie, nie vo vlákne chatu.