Nogen peger en offentlig HAProxy-vært på en intern applikation og spørger, hvorfor browseren ikke kan følge med. Proxyen når appen gennem sin VPN, omdirigeringen returnerer et Location-header, og browseren forsøger derefter en adresse, der kun findes inde i tunnelen. Udefra hænger siden ganske enkelt. Beslutningen handler om, hvilken part der åbner den anden forbindelse, og det er netop det, der adskiller en omdirigering fra et backend.

To veje der ser ens ud i konfigurationen

En omdirigering afslutter udvekslingen med et svar. Klienten læser Location og starter en ny anmodning fra det sted, hvor klienten befinder sig, altså det netværk, du aldrig har kontrolleret. Proxyen er ikke længere involveret. Alt, hvad der følger, afhænger af klientens egen DNS, rute og tillid, så resultatet varierer efter, hvor brugeren åbnede browseren:

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

Et proxy-backend holder det andet ben på serversiden. Proxyen åbner det ad den vej, den allerede har, og klienten bliver ved med at tale med ét offentligt navn. Falder tunnelen, får klienten en fejl i stedet for en URL, den ikke kan følge. Den forskel er også det, der gør fejlen diagnosticerbar, fordi fejlen optræder der, hvor loggene er:

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

HAProxy’s dokumentation om omdirigeringer drager netop denne grænse: at svare klienten med en omdirigering er en anden handling end at videresende anmodningen til et backend. De to direktiver står få linjer fra hinanden i en konfigurationsfil og opfører sig helt forskelligt. Det ene afslutter anmodningen, det andet begynder en anden, som proxyen ejer.

Hvad browseren har brug for, og serverens VPN ikke giver den

Browserens egen anmodning har brug for fire ting, som den måske ikke har: et DNS-svar på det private navn, en rute til den adresse, tilladelse til at nå den lyttende tjeneste og tillid til det certifikat, som tjenesten fremviser. Proxy-værten har alle fire gennem sin tunnel. Ingen af dem overføres til en klient, der aldrig har været på den tunnel, fordi tunnelen er en egenskab ved værten, ikke ved URL’en.

Det gab forklarer symptomet næsten-virker. Den første anmodning lykkes, adresselinjen ændrer sig, og derefter hænger eller fejler forbindelsen, mens proxyen er sund hele tiden. Der er intet i stykker i proxy-konfigurationen, og det hjælper ikke at justere den for en klient uden rute til 10.40.0.20. Enten får klienten en rute, eller også må proxyen etablere forbindelsen på dens vegne.

Når kun proxyen kan nå appen

Fjern omdirigeringshandlingen, og send de anmodninger til et backend, der peger på den private adresse. Frontend beholder sit offentlige navn, mens backend bestemmer, hvor anmodningen faktisk går hen. Intet ændrer sig i klientens vej, fordi proxyen holder op med at beskrive en destination og begynder at være en. For en applikation, der med vilje lytter på den interne port 8080, er serverblokken kort:

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

Læs den blok som en udtalelse om proxyens routingtabel: 10.40.0.20 skal være tilgængelig fra selve proxy-værten, hvilket her betyder gennem VPN-interfacet og ikke gennem standardruten. Nøgleordet check rapporterer kun, hvad den rute gør, og sundhedsstien skal findes på applikationen, ellers markerer hvert probe serveren som nede. En bestået kontrol beviser intet om klienten og erstatter ikke den politik, der afgør, hvem der må bruge backend.

Fragmentet er ikke et komplet frontend. Behold listeneren, godkendelsen, valget af tilladte værter og stier samt reglen, der afgør, hvem der overhovedet må nå applikationen. Afstem også backend-protokollen, fordi et HTTPS-backend kræver certifikatbekræftelse og en serveridentitetskonfiguration, og springer du den kontrol over, bliver en privat forbindelse til en ubekræftet.

Bekræft returvejen i begge retninger, før du erklærer sejr. Applikationen ser nu en forbindelse fra proxyen, så dens logge og alle metadata om klientadressen beskriver proxyen, medmindre du arrangerer andet. Beslut, hvordan identitet og videresendte adresser håndteres, og test beslutningen i stedet for at antage den.

Appens egne omdirigeringer peger stadig indad

At videresende den første anmodning er kun halvdelen af integrationen. Applikationen kan udsende absolutte omdirigeringer, hårdkodede asset-URL’er eller cookies afgrænset til det navn, den kender internt, og hver af dem sender browseren tilbage til en adresse, den ikke kan nå. Et Location-header, der peger på det interne navn, ser identisk ud med det oprindelige problem, og derfor fejldiagnosticeres det som en proxy-fejl.

Sæt applikationens dokumenterede eksterne URL og dens proxy-indstillinger, og få derefter Host-headeren til at passe med den virtuelle vært og certifikatets forventninger. En cookie afgrænset til det interne navn kommer ikke tilbage gennem det offentlige navn, og den login-løkke, der følger, læses som en godkendelsesfejl. Skift den eksterne URL først, test igen fra en ren browserprofil, og forvent at halvt migrerede indstillinger giver et login, der lykkes, og en session, der dør med det samme.

Stol kun på videresendte metadata fra den udpegede proxy. Et header, som enhver klient kan sætte, må aldrig blive en autorisationsværdi, ellers bliver proxyen en måde, hvorpå en kaldende kan påberåbe sig en andens identitet. Den regel er uafhængig af omdirigeringsspørgsmålet og overlever enhver senere redesign.

Beslut, hvilket design du faktisk har

Hvis hver bruger allerede har autoriseret VPN-adgang, kan en omdirigering til en privat URL være et bevidst design. Bekræft det krav eksplicit i stedet for at antage det, fordi de to designs betjener helt forskellige befolkningsgrupper. Det ene virker slet ikke fra et hotelnetværk, og det andet blotlægger applikationen for enhver, der kan indlæse den offentlige URL. Den sondring hører til i designnotatet.

Kør kontrollen fra en maskine på brugernes netværk, og følg hvert hop, browseren tager, ikke kun det første svar. Hold øje med adresselinjen og hver efterfølgende anmodning, fordi en enkelt absolut URL i et asset-tag er nok til at bryde et flow, som det første hop bestod. Login skal virke gennem det offentlige navn, og ressourcer, der bør afvises, skal blive afvist.

At offentliggøre en reverse proxy er en særskilt adgangsbeslutning, ikke en gennemsigtig udvidelse af proxyens egen VPN til enhver, der kan indlæse dens offentlige URL. De to ligner hinanden på et diagram, og de adskiller sig i, hvem der får lov at komme ind. At beslutte det spørgsmål efter udrulningen er måden, hvorpå en intern applikation ved et uheld bliver offentlig.

Skriv ned, hvilket af de to du byggede, og hvorfor. Den næste person, der rører konfigurationen, vil antage det andet. En enkelt omdirigering tilføjet for nemheds skyld er nok til at genskabe den oprindelige fejl, og symptomet vil se præcis ud som det, du lige har rettet.

Relaterede artikler