Någon pekar en publik HAProxy-värd mot en lokal applikation och frågar varför webbläsaren inte kan följa med. Proxyn når appen via sin VPN, omdirigeringen returnerar en Location-rubrik och webbläsaren försöker sedan en adress som bara finns inne i tunneln. Utifrån ser sidan bara ut att hänga. Beslutet handlar om vilken part som öppnar den andra anslutningen, och det är vad som skiljer en omdirigering från en backend.

Två vägar som ser lika ut i konfigurationen

En omdirigering avslutar utbytet med ett svar. Klienten läser Location och startar en ny begäran varifrån klienten råkar befinna sig, alltså i nätverket du aldrig kontrollerade. Proxyn är inte längre inblandad. Allt som följer beror på klientens egen DNS, rutt och tillit, så resultatet varierar beroende på var användaren öppnade webbläsaren:

GET /app        client -> proxy
302 Location    proxy  -> client   (http://10.40.0.20:8080/)
GET /app        client -> 10.40.0.20:8080   client network, no route

En backend i proxyn behåller andra etappen på serversidan. Proxyn öppnar den över den väg den redan har, och klienten fortsätter prata med ett enda publikt namn. Om tunneln faller får klienten ett fel i stället för en URL den inte kan följa. Den skillnaden är också det som gör felet diagnoserbart, eftersom felet dyker upp där loggarna finns:

GET /app        client -> proxy
GET /app        proxy  -> 10.40.0.20:8080   over the VPN
response        proxy  -> client

HAProxy:s dokumentation om omdirigeringar drar exakt den gränsen: att svara klienten med en omdirigering är en annan handling än att vidarebefordra begäran till en backend. De två direktiven ligger några rader ifrån varandra i en konfigurationsfil och beter sig inte alls likadant. Det ena avslutar begäran, det andra börjar en ny som proxyn äger.

Vad webbläsaren behöver som serverns VPN inte ger den

Webbläsarens egen begäran behöver fyra saker som den kanske inte har: ett DNS-svar för det privata namnet, en rutt till adressen, tillstånd att nå den lyssnande tjänsten och tillit till vilket certifikat den tjänsten än presenterar. Proxyvärden har alla fyra genom sin tunnel. Ingen av dem följer med till en klient som aldrig var i den tunneln, eftersom tunneln är en egenskap hos värden, inte hos URL:en.

Det gapet förklarar symtomet som nästan fungerar. Den första begäran lyckas, adressfältet ändras och anslutningen hänger sig eller misslyckas sedan medan proxyn är frisk hela tiden. Inget är trasigt i proxykonfigurationen, och att justera den kan inte hjälpa en klient som saknar väg till 10.40.0.20. Antingen får klienten en rutt, eller så måste proxyn göra anslutningen åt den.

När bara proxyn kan nå appen

Ta bort omdirigeringsåtgärden och skicka de begärandena till en backend som pekar på den privata adressen. Frontend behåller sitt publika namn medan backend avgör vart begäran faktiskt tar vägen. Inget i klientens väg ändras, eftersom proxyn slutar beskriva ett mål och börjar vara ett. För en applikation som medvetet lyssnar på den interna porten 8080 är serverblocket kort:

backend private_app
    mode http
    option httpchk GET /health
    server app1 10.40.0.20:8080 check

Läs det blocket som ett påstående om proxyns routingtabell: 10.40.0.20 måste vara nåbart från proxyvärden själv, vilket här betyder via VPN-gränssnittet och inte via standardrutten. Nyckelordet check rapporterar bara vad den rutten gör, och hälsosökvägen måste finnas i applikationen, annars markerar varje sond servern som nere. En godkänd kontroll bevisar ingenting om klienten och ersätter inte policyn som avgör vem som får använda backend.

Fragmentet är inte en komplett frontend. Behåll lyssnaren, autentiseringen, valet av tillåten värd och sökväg samt regeln som avgör vem som alls får nå applikationen. Matcha även backend-protokollet, eftersom en HTTPS-backend behöver certifikatverifiering och en serveridentitetskonfiguration, och att hoppa över den kontrollen förvandlar en privat anslutning till en overifierad.

Bekräfta returvägen i båda riktningarna innan du utropar seger. Applikationen ser nu en anslutning från proxyn, så dess loggar och all klientadressmetadata beskriver proxyn om du inte ordnar något annat. Bestäm hur identitet och vidarebefordrade adresser hanteras, och testa beslutet i stället för att anta det.

Appens egna omdirigeringar pekar fortfarande inåt

Att vidarebefordra den första begäran är bara halva integrationen. Applikationen kan skicka absoluta omdirigeringar, hårdkodade resurs-URL:er eller cookies knutna till namnet den känner till internt, och var och en av dem skickar webbläsaren tillbaka till en adress den inte kan nå. En Location-rubrik som pekar på det interna namnet ser identisk ut med det ursprungliga problemet, och därför feldiagnostiseras det som ett proxyfel.

Ställ in applikationens dokumenterade externa URL och dess proxyalternativ och låt sedan Host-rubriken stämma med den virtuella värden och certifikatförväntningarna. En cookie knuten till det interna namnet kommer inte tillbaka via det publika namnet, och inloggningsloopen som följer läses som en autentiseringsbugg. Ändra den externa URL:en först, testa om från en ren webbläsarprofil och räkna med att halvflyttade inställningar ger en inloggning som lyckas och en session som dör direkt.

Lita på vidarebefordrad metadata bara från den utsedda proxyn. En rubrik som vilken klient som helst kan sätta får aldrig bli ett auktoriseringsvärde, annars blir proxyn ett sätt för en anropare att göra anspråk på någon annans identitet. Den regeln är oberoende av omdirigeringsfrågan och överlever varje senare omdesign.

Avgör vilken design du faktiskt har

Om alla användare redan har auktoriserad VPN-åtkomst kan en omdirigering till en privat URL vara en medveten design. Bekräfta det kravet uttryckligen i stället för att anta det, eftersom de två designerna betjänar helt olika grupper. En av dem fungerar inte alls från ett hotellnätverk, och den andra exponerar applikationen för alla som kan ladda den publika URL:en. Den skillnaden hör hemma i designanteckningen.

Kör kontrollen från en maskin i användarnas nätverk och följ varje hopp webbläsaren gör, inte bara det första svaret. Håll koll på adressfältet och på varje efterföljande begäran, eftersom en enda absolut URL i en resurstagg räcker för att bryta ett flöde som det första hoppet klarade. Inloggning måste fungera via det publika namnet, och resurser som ska nekas måste förbli nekade.

Att publicera en omvänd proxy är ett separat åtkomstbeslut, inte en transparent förlängning av proxyns egen VPN till alla som kan ladda dess publika URL. De två ser likadana ut i ett diagram, och de skiljer sig i vem som släpps in. Att avgöra den frågan efter driftsättningen är hur en intern applikation av misstag blir publik.

Skriv ner vilken av dem du byggde och varför. Nästa person som rör konfigurationen kommer att anta den andra. En enda omdirigering som lagts till för bekvämlighets skull räcker för att återskapa det ursprungliga felet, och symtomet kommer att se ut precis som det du just fixade.

Relaterade artiklar