Varför Port-Share får alla webbplatsbesökare att se ut som localhost
Backenden ser vidarebefordringshoppet, inte webbläsaren. Kontrollera var källadressen försvinner och bestäm sedan vilken komponent som får garantera den.
Varje rad i åtkomstloggen visar samma loopback-adress, medan sidan själv laddas och certifikatet valideras korrekt. Ingenting är trasigt i betydelsen oåtkomligt, och det är därför detta överlever i månader. Det som gick sönder är tillskrivningen: webb-backenden registrerar adressen för det hopp som vidarebefordrade anslutningen, och varje senare beslut som litade på loggen ärvde samma felaktiga svar.
Kontrollerna nedan går från kabeln och inåt. Stanna vid den första som förklarar det värde du ser, eftersom varje senare steg förutsätter att de tidigare redan är sanna. Ingen av dem kräver att du gissar frontend-konfigurationen.
Följ de två anslutningarna, inte loggraden
Port-Share multiplexar två protokoll på en enda TCP-lyssnare. OpenVPN inspekterar de första byten i en inkommande anslutning, behåller den när den ser ut som dess eget protokoll och lämnar allt annat till en andra destination. Den destinationen är vanligtvis en webbserver på samma värd, så webbserverns accepterade socket har OpenVPN-processen som motpart.
ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'
Det första kommandot visar vem som äger den publika lyssnaren. Det andra visar anslutningarna som anländer till backend-porten, och deras motpartsadress är den som åtkomstloggen kommer att skriva ut. Om den motparten är loopback är loggen korrekt och informationen gick förlorad ett lager tidigare. Att byta namn på loggfältet eller aktivera en klient-IP-modul återställer inte en adress som anslutningen aldrig bar.
Detta är kontrollen som avgör allt annat. Om backendens motpart är webbläsarens adress är portdelning inte ditt problem och loggformatet är det.
Transportvidarebefordran är inte header-injektion
Vidarebefordraren flyttar byte. Den parsar inte HTTP, så den kan inte infoga en header i en begäran som den aldrig läser som en begäran, och den kan inte lägga till något i en TLS-ström som den släpper igenom orörd. En modul som väntar på en proxy-header fortsätter att vänta på en som ingen komponent producerar.
Två mekanismer kan bära den ursprungliga adressen, och båda kräver enighet i båda ändar. PROXY-protokollet sätter en liten header framför anslutningen, och backenden måste vara konfigurerad att förvänta sig den; en backend som inte förväntar sig den behandlar dessa byte som början på begäran och misslyckas på ett förvirrande sätt. Betrodda proxy-headers som X-Forwarded-For fungerar när en HTTP-medveten proxy sätter dem och backenden får veta vilka motparter som får hävda dem.
Ingen av dem är automatisk, och ingen av dem är säker som standard. En backend som tror på varje inkommande vidarebefordrad header låter en klient välja sin egen adress, vilket förvandlar en felaktighet i loggen till ett kringgående av åtkomstkontrollen. Kör demonstrationen en gång på en testvärd innan du litar på någon header på en produktionsväg.
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
Den valfria mappen för källmappning
Portdelning har ett valfritt mappargument som registrerar en mappning mellan den ursprungliga källadressen och vidarebefordringsanslutningen, på plattformar där funktionen är implementerad. Webbsidan förväntas konsultera den mappningen; det är inte en header, och den injiceras inte i begäran.
Den designen är värd att känna till eftersom den förklarar varför vissa installationer rapporterar riktiga adresser och andra inte, med till synes identisk frontend-konfiguration. Skillnaden ligger på mottagarsidan, och den bor vanligtvis i en modul eller en patch som de flesta paketerade webbservrar inte aktiverar som standard. Läs dokumentationen för din webbserver för den exakta hook den erbjuder, och bekräfta att modulen är laddad i stället för att anta det.
Om du går den här vägen, behandla det som en integration med två halvor: mappningen som vidarebefordraren skriver och sökningen som backenden gör. Verifiera båda, och bekräfta att mappen överlever en omstart och inte växer obegränsat på en upptagen lyssnare.
Bestäm vilken komponent som garanterar adressen
Innan du ändrar konfigurationen, namnge den komponent som får hävda en klientadress och de komponenter som får tro på den. Ett enda nedskrivet svar förhindrar den vanliga driften, där tre olika lager litar var och en på en olika källa.
Tre designer täcker de flesta behov. Håll den publika lyssnaren och webbslyssnaren åtskilda, så att webbservern ser riktiga motparter och inget tillskrivningsproblem uppstår. Sätt en HTTP-medveten omvänd proxy framför, avsluta eller parsa begäran där, och låt den sätta en vidarebefordrad header för en backend som bara litar på den proxyn. Eller behåll portdelningen och acceptera att loggarna visar hoppet, med åtkomstregler skrivna mot applikationsidentitet i stället för en adress.
Det som inte fungerar är att behandla en vidarebefordrad loopback-adress som bevis för att begäran uppstod på den här maskinen. Den slutsatsen är precis omvänd: adressen finns just för att en lokal komponent skapade anslutningen. En regel skriven så släpper in alla som kan nå lyssnaren.
Testa regeln, inte sidan
En sida som laddas bevisar att vidarebefordringsvägen fungerar och säger ingenting om tillskrivning. Testa adressens konsument: åtkomstregeln, hastighetsgränsen, revisionsposten, geo-uppslagningen.
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
Jämför en auktoriserad extern begäran med både frontend- och backendposterna, och bekräfta att en regel som borde neka fortfarande nekar och en som borde tillåta fortfarande tillåter. Om loggraden är korrekt men regeln fortfarande beter sig som om alla vore lokala, läser regeln ett annat fält än det du rättade.
Avsluta med att skriva tillskrivningskedjan i driftsättningsanteckningarna: vilken lyssnare, vilken vidarebefordrare, vilken header eller mappning och vilken backend som är konfigurerad att lita på den. Nästa person som läser en loggrad behöver alla fyra, och avsaknaden av den anteckningen är hur samma ärende öppnas igen ett år senare. Håll den bredvid konfigurationen i stället för i en chattråd.