Iemand richt een openbare HAProxy-host op een interne applicatie en vraagt waarom de browser niet kan volgen. De proxy bereikt de app via zijn VPN, de redirect retourneert een Location-header, en de browser probeert dan een adres dat alleen binnen de tunnel bestaat. Van buiten blijft de pagina gewoon hangen. De beslissing gaat over welke partij de tweede verbinding opent, en dat is wat een redirect van een backend scheidt.

Twee paden die er in de configuratie hetzelfde uitzien

Een redirect beëindigt de uitwisseling met een antwoord. De client leest Location en start een nieuw verzoek vanaf waar de client zich bevindt, dus het netwerk dat u nooit hebt beheerd. De proxy is niet langer betrokken. Alles wat volgt hangt af van de eigen DNS, route en vertrouwen van de client, dus de uitkomst verschilt per plek waar de gebruiker de browser opende:

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

Een backend van de proxy houdt de tweede etappe aan de serverkant. De proxy opent die over het pad dat hij al heeft, en de client blijft met één openbare naam praten. Valt de tunnel weg, dan krijgt de client een fout in plaats van een URL die hij niet kan volgen. Dat verschil is ook wat de storing diagnoseerbaar maakt, omdat de fout verschijnt waar de logboeken staan:

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

HAProxy's documentatie over redirects trekt precies die grens: de client met een redirect antwoorden is een andere actie dan het verzoek naar een backend doorsturen. De twee richtlijnen staan een paar regels uit elkaar in een configuratiebestand en gedragen zich totaal verschillend. De ene beëindigt het verzoek, de andere begint een tweede dat de proxy bezit.

Wat de browser nodig heeft en de VPN van de server hem niet geeft

Het verzoek van de browser zelf heeft vier dingen nodig die hij misschien niet heeft: een DNS-antwoord voor de privénaam, een route naar dat adres, toestemming om de luisterende dienst te bereiken, en vertrouwen in het certificaat dat die dienst presenteert. De proxyhost bezit alle vier via zijn tunnel. Niets daarvan gaat over naar een client die nooit in die tunnel was, omdat de tunnel een eigenschap van de host is, niet van de URL.

Dat gat verklaart het bijna-werkt-symptoom. Het eerste verzoek slaagt, de adresbalk verandert, en daarna hangt of faalt de verbinding terwijl de proxy de hele tijd gezond is. Aan de proxyconfiguratie is niets kapot, en die aanpassen helpt een client zonder route naar 10.40.0.20 niet. Ofwel de client krijgt een route, ofwel de proxy moet de verbinding namens hem maken.

Wanneer alleen de proxy de app kan bereiken

Verwijder de redirectactie en stuur die verzoeken naar een backend die naar het privéadres wijst. De frontend houdt zijn openbare naam terwijl de backend bepaalt waar het verzoek werkelijk heen gaat. Aan het pad van de client verandert niets, omdat de proxy ophoudt een bestemming te beschrijven en er zelf een wordt. Voor een applicatie die bewust op de interne poort 8080 luistert, is het serverblok kort:

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

Lees dat blok als een uitspraak over de routingtabel van de proxy: 10.40.0.20 moet bereikbaar zijn vanaf de proxyhost zelf, wat hier betekent via de VPN-interface en niet via de standaardroute. Het trefwoord check meldt alleen wat die route doet, en het gezondheidspad moet op de applicatie bestaan, anders markeert elke controle de server als neer. Een geslaagde controle bewijst niets over de client en vervangt niet het beleid dat bepaalt wie de backend mag gebruiken.

Het fragment is geen complete frontend. Behoud de listener, de authenticatie, de keuze van toegestane host en pad, en de regel die bepaalt wie de applicatie überhaupt mag bereiken. Stem ook het backendprotocol af, want een HTTPS-backend vereist certificaatverificatie en een serveridentiteitsconfiguratie, en die controle overslaan maakt van een privéverbinding een ongeverifieerde.

Bevestig de terugweg in beide richtingen voordat u de overwinning uitroept. De applicatie ziet nu een verbinding van de proxy, dus de logboeken en alle metadata van het clientadres beschrijven de proxy, tenzij u het anders regelt. Bepaal hoe identiteit en doorgestuurde adressen worden behandeld, en test de beslissing in plaats van haar aan te nemen.

De eigen redirects van de app wijzen nog steeds naar binnen

Het eerste verzoek doorsturen is maar de helft van de integratie. De applicatie kan absolute redirects, hardgecodeerde asset-URL's of cookies uitsturen die beperkt zijn tot de naam die zij intern kent, en elk daarvan stuurt de browser terug naar een adres dat hij niet kan bereiken. Een Location-header die naar de interne naam wijst ziet er identiek uit als het oorspronkelijke probleem, en daarom wordt het verkeerd gediagnosticeerd als een proxyfout.

Stel de gedocumenteerde externe URL van de applicatie en haar proxyopties in, en laat de Host-header dan overeenkomen met de virtuele host en de verwachtingen van het certificaat. Een cookie die tot de interne naam beperkt is komt niet terug via de openbare naam, en de inloglus die volgt leest als een authenticatiefout. Wijzig eerst de externe URL, test opnieuw vanuit een schoon browserprofiel, en verwacht dat half gemigreerde instellingen een login opleveren die slaagt en een sessie die direct sterft.

Vertrouw doorgestuurde metadata alleen van de aangewezen proxy. Een header die elke client kan zetten mag nooit een autorisatiewaarde worden, anders wordt de proxy een manier waarop een beller de identiteit van een ander opeist. Die regel staat los van de redirectvraag en overleeft elke latere herziening.

Bepaal welk ontwerp u werkelijk heeft

Als elke gebruiker al geautoriseerde VPN-toegang heeft, kan een redirect naar een privé-URL een bewust ontwerp zijn. Bevestig die eis expliciet in plaats van haar aan te nemen, omdat de twee ontwerpen volledig verschillende groepen bedienen. Een ervan werkt helemaal niet vanaf een hotelnetwerk, en de andere stelt de applicatie bloot aan iedereen die de openbare URL kan laden. Dat onderscheid hoort in de ontwerpnotitie.

Voer de controle uit vanaf een machine op het netwerk van de gebruikers en volg elke sprong die de browser maakt, niet alleen het eerste antwoord. Houd de adresbalk en elk volgend verzoek in het oog, want één absolute URL in een asset-tag is genoeg om een stroom te breken die de eerste sprong doorstond. Inloggen moet via de openbare naam werken, en bronnen die geweigerd moeten worden moeten geweigerd blijven.

Een reverse proxy publiceren is een aparte toegangsbeslissing, geen transparante uitbreiding van de VPN van de proxy naar iedereen die zijn openbare URL kan laden. De twee lijken op een diagram op elkaar, en ze verschillen in wie er binnen mag. Die vraag na de uitrol beslissen is de manier waarop een interne applicatie per ongeluk openbaar wordt.

Schrijf op welke van de twee u hebt gebouwd en waarom. De volgende persoon die de configuratie aanraakt zal de andere aannemen. Eén enkele redirect die voor het gemak is toegevoegd is genoeg om de oorspronkelijke storing opnieuw te maken, en het symptoom zal er precies uitzien als hetgeen u zojuist hebt verholpen.

Gerelateerde artikelen