En forespørsel som kommer inn til applikasjonen din, bærer to slags adressebevis: peeren som åpnet nettverksforbindelsen, og et HTTP-felt som hevder adressen til en tidligere klient. De svarer på forskjellige spørsmål. Socket-peeren observeres, mens headeren hevdes av den som skrev den, og ingen av dem bør stille erstatte den andre i en logg eller en tilgangsregel. Sammenligningen nedenfor holder dem adskilt og viser deretter det eneste arrangementet der headeren blir brukbar.

Beskriv stien før du sammenligner noe:

Client -> approved reverse proxy -> application origin

I det arrangementet er socket-peeren til opprinnelsen normalt proxyen, og en videresendt header kan bære proxyens påstand om klienten. Verdien kommer fra det kontrollerte forholdet til den proxyen, ikke fra headerens navn.

To slags adressebevis

Socket-peeren er et faktum om én TCP-forbindelse: noe fullførte et håndtrykk fra den adressen. Det er ikke nødvendigvis mennesket, enheten eller kontoen du bryr deg om, fordi en VPN eller en Tor-utgang legit kan være kilden en tjeneste observerer. Den er likevel den eneste adressen verten selv verifiserte, og det er hele verdien.

Et videresendingsfelt er metadata om en kjede. X-Forwarded-For, X-Real-IP og det standardiserte feltet Forwarded kan skrives av enhver klient som når et endepunkt som gjenspeiler dem, så påliteligheten deres avhenger helt av hvem som fikk lov til å sette dem.

Behold begge i forespørselskonteksten under forskjellige navn. En applikasjon som overskriver peeren med headeren, mister evnen til å rekonstruere en tillitsfeil senere, og det er nettopp da du trenger den.

En header omdirigerer aldri forbindelsen

Å skrive en adresse i et videresendingsfelt endrer ikke kilden til TCP-forbindelsen som kommer til serveren, og det endrer ikke rutingen noe sted langs stien. Vanlig VPN-ruting eller kilde-NAT leverer trafikk helt uten noen HTTP-header. På samme måte skriver en transittgateway ikke om en riktig beskyttet HTTPS-utveksling uten å endre arrangementet for TLS-endepunktet.

Den motsatte feilen er like vanlig: HTTPS gjør ikke en klientlevert videresendt header sann. Det beskytter transporten av en falsk påstand like godt som av en sann.

Hvis en kollega foreslår en headerendring for å løse et ruteproblem, har diagnosen allerede gått galt. Reparer stien, eller reparer proxykonfigurasjonen som skriver headeren.

Navngi proxyen som har lov til å hevde

To regler gjør et videresendingsfelt brukbart, og begge er konfigurasjon og ikke kode. Kanten normaliserer eller forkaster alt som kommer utenfra, etter sin egen dokumenterte oppførsel for disse feltene. Deretter tar opprinnelsen en erstatningsadresse fra proxystien du navnga, og ikke fra noe annet. Den andre regelen gjelder bare så lenge klienter ikke kan nå opprinnelsen på annen måte, fordi en opprinnelse som svarer på både direkte og proxyede forespørsler, ikke vet hvilken av dem den betjener.

NGINX-modulen for ekte IP viser delingen tydelig. set_real_ip_from navngir avsenderne hvis påstand teller, og real_ip_header sier hvilket felt som bærer den; den første utfører tilliten, den andre sier bare hvor man skal se.

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

En headerutvalgsdirektiv alene fastslår fortsatt ingenting om hvem som sendte verdien.

Transportsikkerhet må løpe hele veien mellom komponentene du stoler på. En kant som normaliserer riktig, mister den verdien i det øyeblikket et ubeskyttet hopp lenger ned lar noen andre redigere påstanden mens den reiser.

Håndter kjeder med flere hopp bevisst

Flere proxyer krever en eksplisitt kjedemodell. Ikke ta den venstre eller høyre kommaseparerte verdien fordi et blogginnlegg gjorde det; finn ut hvilken av proxyene dine som legger til, hvilken som erstatter og hvilken som bevarer det innkommende feltet. NGINX kan for eksempel gå listen baklengs gjennom sitt betrodde sett og stoppe ved den første adressen det ikke eier, og det er den produktets regel, ikke en lov som hvert rammeverk følger. Les dokumentasjonen til din egen proxy med de samme to spørsmålene: hvilken verdi velger den, og hvilke avsendere tror den på?

Skriv ned kjeden: hopprekkefølge, hvilket hopp som setter feltet, og hvilket hopp som fjerner innkommende kopier. Hold deretter notatet ved siden av proxykonfigurasjonen, ikke bare i billetten. Test det deretter ved å sende en forespørsel med en forfalsket header gjennom den godkjente valideringsprosessen og bekrefte at opprinnelsen ignorerer den.

Når du legger til et hopp, gjennomgå det dokumentet. En ny lastbalanserer som settes inn foran den betrodde proxyen, kan endre hvilken adresse som vinner uten at noen redigerer applikasjonen.

Behold begge observasjonene i loggen

Der diagnostikk er tillatt, logg forbindelsens peer og den normaliserte klientadressen som to separate felt, og legg bare til de videresendingsmetadataene som formålet faktisk trenger. Bevis deretter utrullingen med to forespørsler: en via proxyen som bør registrere begge verdiene fornuftig, og et forsøk direkte til opprinnelsen som må avvises.

Husk hva paret betyr. Headere legger til kontekst fra en komponent du valgte å stole på; peeren forblir den eneste adressen verten din faktisk så. Ingen av dem er bevis for individuell identitet, og et design som behandler en av dem som bevis, vil ta feil om noen.

Relaterte artikler