Protějšek soketu versus předávaná hlavička: které adrese věřit?
Protějšek soketu a předávaná hlavička jsou různé důkazy. Porovnejte, co každý z nich dokazuje, a hlavičce věřte jen přes řetězec proxy, který ovládáte.
Požadavek, který dorazí do vaší aplikace, nese dva druhy důkazů o adrese: protějšek, který otevřel síťové spojení, a pole HTTP, které tvrdí adresu dřívějšího klienta. Odpovídají na různé otázky. Protějšek soketu se pozoruje, kdežto hlavičku tvrdí ten, kdo ji napsal, a ani jedno by nemělo tiše nahradit druhé v záznamu nebo v pravidle přístupu. Srovnání níže je drží oddělené a poté ukazuje jediné uspořádání, v němž se hlavička stává použitelnou.
Popište cestu, než cokoli porovnáte:
Client -> approved reverse proxy -> application originV tomto uspořádání je protějšek soketu na straně původu obvykle proxy a předávací hlavička může nést tvrzení proxy o klientovi. Její hodnota pochází z řízeného vztahu s touto proxy, nikoli z názvu hlavičky.
Dva druhy důkazů o adrese
Protějšek soketu je fakt o jednom TCP spojení: něco dokončilo navázání spojení z této adresy. Nemusí to být člověk, zařízení ani účet, na kterém vám záleží, protože VPN nebo výstupní uzel Tor mohou být legitimně zdrojem, který služba pozoruje. Přesto je to jediná adresa, kterou samotný host ověřil, a v tom je celá její hodnota.
Pole předávání jsou metadata o řetězci. X-Forwarded-For, X-Real-IP a standardizované pole Forwarded může napsat každý klient, který dosáhne koncového bodu, jenž je vrací, takže jejich důvěryhodnost zcela závisí na tom, komu bylo dovoleno je nastavit.
Uchovávejte obojí v kontextu požadavku pod odlišnými názvy. Aplikace, která přepíše protějšek hlavičkou, ztrácí schopnost později rekonstruovat chybu důvěry, a to je právě okamžik, kdy ji potřebujete.
Hlavička nikdy nepřesměruje spojení
Zapsání adresy do pole předávání nemění zdroj TCP spojení přicházejícího na server a nemění směrování nikde na cestě. Běžné směrování VPN nebo zdrojový NAT doručí provoz zcela bez HTTP hlavičky. Stejně tak tranzitní brána nepřepisuje řádně chráněnou výměnu HTTPS, aniž by změnila uspořádání koncového bodu TLS.
Opačná chyba je stejně častá: HTTPS nedělá hlavičku předávání poskytnutou klientem pravdivou. Chrání přenos nepravdivého tvrzení přesně tak dobře jako pravdivého.
Pokud kolega navrhne změnu hlavičky pro opravu problému se směrováním, diagnóza už se ubrala špatným směrem. Opravte cestu, nebo opravte konfiguraci proxy, která hlavičku zapisuje.
Pojmenujte proxy, která smí tvrdit
Dvě pravidla činí pole předávání použitelným a obě jsou konfigurace, nikoli kód. Okraj normalizuje nebo zahazuje vše, co přichází zvenčí, podle vlastního dokumentovaného chování pro tato pole. Původ pak bere náhradní adresu z cesty proxy, kterou jste pojmenovali, a odnikud jinud. Druhé pravidlo platí jen tehdy, dokud se klienti nemohou k původu dostat jinak, protože původ, který odpovídá na přímé i proxy požadavky, neví, kterému z nich slouží.
Modul reálné IP adresy NGINX ukazuje rozdělení jasně. set_real_ip_from pojmenovává odesílatele, jejichž tvrzení se počítá, a real_ip_header říká, které pole ho nese; první provádí důvěru, druhé jen říká, kam se dívat.
set_real_ip_from 10.20.0.0/24;
real_ip_header X-Forwarded-For;
# real_ip_recursive off - take the rightmost value in the field
# real_ip_recursive on - walk the list back past every trusted address
Direktiva pro výběr hlavičky sama o sobě stále nic nestanoví o tom, kdo hodnotu poslal.
Zabezpečení přenosu musí působit po celé cestě mezi komponentami, kterým věříte. Okraj, který správně normalizuje, ztrácí tuto hodnotu v okamžiku, kdy nechráněný meziskok níže umožní někomu jinému upravit tvrzení na cestě.
Vědomě zacházejte s řetězci s více mezisky
Několik proxy vyžaduje výslovný model řetězce. Neberte nejlevější ani nejpravější hodnotu oddělenou čárkami jen proto, že to udělal nějaký blogový příspěvek; zjistěte, která z vašich proxy připojuje, která nahrazuje a která zachovává příchozí pole. Například NGINX může procházet seznam pozpátku proti své množině důvěryhodných a zastavit se na první adrese, kterou nevlastní, a to je pravidlo tohoto produktu, nikoli zákon, který dodržuje každý rámec. Čtěte dokumentaci vlastní proxy se stejnými dvěma otázkami: kterou hodnotu vybírá a kterým odesílatelům věří?
Zapište řetězec: pořadí meziskoků, který meziskok nastavuje pole a který meziskok odstraňuje příchozí kopie. Potom držte tuto poznámku vedle konfigurace proxy, nejen v tiketu. Pak to ověřte odesláním požadavku s padělanou hlavičkou přes schválený validační proces a potvrzením, že původ ji ignoruje.
Když přidáte meziskok, znovu projděte tento dokument. Nový nástroj pro vyrovnávání zátěže vložený před důvěryhodnou proxy může změnit, která adresa vyhraje, aniž by kdokoli upravoval aplikaci.
Uchovejte obě pozorování v záznamu
Tam, kde je diagnostika povolena, zaznamenávejte protějšek spojení a normalizovanou adresu klienta jako dvě samostatná pole a přidávejte jen metadata předávání, která účel skutečně potřebuje. Potom dokažte nasazení dvěma požadavky: jeden přes proxy, který má rozumně zaznamenat obě hodnoty, a jeden pokus přímo na původ, který musí být odmítnut.
Pamatujte, co dvojice znamená. Hlavička přidává kontext poskytnutý komponentou, které jste se rozhodli věřit; protějšek zůstává jedinou adresou, kterou váš host skutečně viděl. Ani jedno není důkazem individuální identity a návrh, který kterékoli z nich považuje za důkaz, se vůči někomu zmýlí.