Bevara det ursprungliga HTTP-värdnamnet mellan en omvänd proxy och dess serverdelswebbprogram

API Management
App Service
Application Gateway
Front Door
Spring Apps

Vi rekommenderar att du bevarar det ursprungliga HTTP-värdnamnet när du använder en omvänd proxy framför ett webbprogram. Om du har ett annat värdnamn på den omvända proxyn än det som tillhandahålls till serverdelsprogramservern kan det leda till cookies eller omdirigerings-URL:er som inte fungerar korrekt. Sessionstillstånd kan till exempel gå förlorat, autentiseringen kan misslyckas eller så kan serverdels-URL:er oavsiktligt exponeras för slutanvändare. Du kan undvika dessa problem genom att bevara värdnamnet för den första begäran så att programservern ser samma domän som webbläsaren.

Den här vägledningen gäller särskilt för program som finns i PaaS-erbjudanden (plattform som en tjänst), till exempel Azure App Service och Azure Spring Apps. Den här artikeln innehåller specifik implementeringsvägledning för Azure Application Gateway, Azure Front Door och Azure API Management, som ofta används för omvända proxytjänster.

Anteckning

Webb-API:er är vanligtvis mindre känsliga för de problem som orsakas av matchningsfel för värdnamn. De är vanligtvis inte beroende av cookies, såvida du inte använder cookies för att skydda kommunikationen mellan en ensidesapp och dess serverdels-API, till exempel i ett mönster som kallas serverdelar för klientdelar. Webb-API:er returnerar ofta inte absoluta URL:er tillbaka till sig själva, förutom i vissa API-format, till exempel OData och HATEOAS. Om API-implementeringen är beroende av cookies eller genererar absoluta URL:er gäller vägledningen i den här artikeln.

Om du behöver TLS/SSL från slutpunkt till slutpunkt (anslutningen mellan den omvända proxyn och serverdelstjänsten använder HTTPS) behöver serverdelstjänsten även ett matchande TLS-certifikat för det ursprungliga värdnamnet. Det här kravet ökar driftskomplexiteten när du distribuerar och förnyar certifikat, men många PaaS-tjänster erbjuder kostnadsfria TLS-certifikat som är fullständigt hanterade.

Kontext

Värden för en HTTP-begäran

I många fall behöver programservern eller någon komponent i pipelinen för begäran det Internetdomännamn som användes av webbläsaren för att få åtkomst till den. Det här är värd för begäran. Det kan vara en IP-adress, men vanligtvis är det ett namn som contoso.com (som webbläsaren sedan matchar till en IP-adress med hjälp av DNS). Värdvärdet bestäms vanligtvis från värdkomponenten i begärande-URI:n, som webbläsaren skickar till programmet som Host HTTP-huvud.

Viktigt

Använd aldrig värdens värde i en säkerhetsmekanism. Värdet tillhandahålls av webbläsaren eller någon annan användaragent och kan enkelt ändras av en slutanvändare.

I vissa fall, särskilt när det finns en omvänd HTTP-proxy i begärandekedjan, kan den ursprungliga värdrubriken ändras innan den når programservern. En omvänd proxy stänger klientnätverkssessionen och konfigurerar en ny anslutning till serverdelen. I den här nya sessionen kan den antingen överföra det ursprungliga värdnamnet för klientsessionen eller ange ett nytt. I det senare fallet skickar proxyn ofta fortfarande det ursprungliga värdvärdet i andra HTTP-huvuden, till exempel Forwarded eller X-Forwarded-Host. Det här värdet gör att program kan fastställa det ursprungliga värdnamnet, men bara om de är kodade för att läsa dessa huvuden.

Varför webbplattformar använder värdnamnet

PaaS-tjänster för flera klientorganisationer kräver ofta ett registrerat och validerat värdnamn för att dirigera en inkommande begäran till lämplig klients serverdelsserver. Det beror på att det vanligtvis finns en delad pool med lastbalanserare som accepterar inkommande begäranden för alla klienter. Klienterna använder ofta det inkommande värdnamnet för att leta upp rätt serverdel för kundens klientorganisation.

För att göra det enkelt att komma igång tillhandahåller dessa plattformar vanligtvis en standarddomän som är förkonfigurerad för att dirigera trafik till din distribuerade instans. För App Service är azurewebsites.netden här standarddomänen . Varje webbapp som du skapar får en egen underdomän, contoso.azurewebsites.nettill exempel . På samma sätt är azuremicroservices.io standarddomänen för Spring Apps och azure-api.net för API Management.

För produktionsdistributioner använder du inte dessa standarddomäner. Du kan i stället ange en egen domän som passar organisationens eller programmets varumärke. Kan till exempel contoso.com matcha webbappen contoso.azurewebsites.net i bakgrunden på App Service, men den här domänen bör inte vara synlig för slutanvändare som besöker webbplatsen. Det här anpassade contoso.com värdnamnet måste dock registreras med PaaS-tjänsten, så att plattformen kan identifiera den serverdelsserver som ska svara på begäran.

Diagram som illustrerar värdbaserad routning i App Service.

Varför program använder värdnamnet

Två vanliga orsaker till att en programserver behöver värdnamnet är att skapa absoluta URL:er och utfärda cookies för en specifik domän. När programkoden till exempel behöver:

  • Returnera en absolut snarare än en relativ URL i sitt HTTP-svar (även om webbplatser vanligtvis tenderar att återge relativa länkar när det är möjligt).
  • Generera en URL som ska användas utanför dess HTTP-svar där relativa URL:er inte kan användas, till exempel för att skicka en länk till webbplatsen till en användare via e-post.
  • Generera en absolut omdirigerings-URL för en extern tjänst. Till exempel till en autentiseringstjänst som Azure Active Directory (Azure AD) för att ange var den ska returnera användaren efter lyckad autentisering.
  • Utfärda HTTP-cookies som är begränsade till en viss värd enligt definitionen i cookiens Domain attribut.

Du kan uppfylla alla dessa krav genom att lägga till det förväntade värdnamnet i programmets konfiguration och använda det statiskt definierade värdet i stället för det inkommande värdnamnet på begäran. Den här metoden komplicerar dock programutveckling och distribution. Dessutom kan en enda installation av programmet hantera flera värdar. Till exempel kan en enda webbapp användas för flera programklienter som alla har sina egna unika värdnamn (som tenant1.contoso.com och tenant2.contoso.com).

Och ibland används det inkommande värdnamnet av komponenter utanför programkoden eller i mellanprogram på programservern som du inte har fullständig kontroll över. Här är några exempel:

  • I App Service kan du framtvinga HTTPS för din webbapp. Om du gör det blir alla HTTP-begäranden som inte är säkra att omdirigera till HTTPS. I det här fallet används det inkommande värdnamnet för att generera den absoluta URL:en för HTTP-omdirigeringens Location huvud.
  • Spring Apps använder en liknande funktion för att framtvinga HTTPS. Den använder också den inkommande värden för att generera HTTPS-URL:en.
  • App Service har en ARR-tillhörighetsinställning för att aktivera fästsessioner, så att begäranden från samma webbläsarinstans alltid hanteras av samma serverdelsserver. Detta utförs av App Service klientdelar, som lägger till en cookie i HTTP-svaret. Cookiens Domain är inställd på den inkommande värden.
  • App Service tillhandahåller funktioner för autentisering och auktorisering så att användarna enkelt kan logga in och komma åt data i API:er.

Varför du kan vara frestad att åsidosätta värdnamnet

Anta att du skapar en webbapp i App Service som har standarddomänen contoso.azurewebsites.net. (Eller i en annan tjänst som Spring Apps.) Du har inte konfigurerat en anpassad domän på App Service. Om du vill placera en omvänd proxy som Application Gateway (eller någon liknande tjänst) framför det här programmet anger du DNS-posten för som ska matchas till IP-adressen för contoso.com Application Gateway. Den tar därför emot begäran från webbläsaren och är konfigurerad för contoso.com att vidarebefordra den begäran till den IP-adress som contoso.azurewebsites.net matchas till: det här är den slutliga serverdelstjänsten för den begärda värden. I det här fallet känner App Service dock inte igen den contoso.com anpassade domänen och avvisar alla inkommande begäranden för det här värdnamnet. Det kan inte avgöra var begäran ska dirigeras.

Det kan verka som att det enkla sättet att få den här konfigurationen att fungera är att åsidosätta eller skriva om Host huvudet för HTTP-begäran i Application Gateway och ange värdet contoso.azurewebsites.netför . Om du gör det verkar den utgående begäran från Application Gateway det som om den ursprungliga begäran verkligen var avsedd för i stället contoso.comför contoso.azurewebsites.net :

Diagram som illustrerar en konfiguration där värdnamnet åsidosätts.

I det här läget känner App Service igen värdnamnet och accepterar begäran utan att kräva att ett anpassat domännamn konfigureras. I själva verket gör Application Gateway det enkelt att åsidosätta värdhuvudet med värden för serverdelspoolen. Azure Front Door gör det även som standard.

Problemet med den här lösningen är dock att det kan leda till olika problem när appen inte ser det ursprungliga värdnamnet.

Potentiella problem

Felaktiga absoluta URL:er

Om det ursprungliga värdnamnet inte bevaras och programservern använder det inkommande värdnamnet för att generera absoluta URL:er, kan serverdelsdomänen avslöjas för en slutanvändare. Dessa absoluta URL:er kan genereras av programkoden eller, som tidigare nämnts, av plattformsfunktioner som stöd för HTTP-till-HTTPS-omdirigering i App Service och Spring Apps. Det här diagrammet illustrerar problemet:

Diagram som illustrerar problemet med felaktiga absoluta URL:er.

  1. Webbläsaren skickar en begäran om contoso.com till den omvända proxyn.
  2. Den omvända proxyn skriver om värdnamnet till contoso.azurewebsites.net i begäran till serverdelswebbprogrammet (eller till en liknande standarddomän för en annan tjänst).
  3. Programmet genererar en absolut URL som baseras på det inkommande contoso.azurewebsites.net värdnamnet, till exempel https://contoso.azurewebsites.net/.
  4. Webbläsaren följer den här URL:en, som går direkt till serverdelstjänsten i stället för tillbaka till den omvända proxyn på contoso.com.

Detta kan även utgöra en säkerhetsrisk i det vanliga fallet där den omvända proxyn också fungerar som en brandvägg för webbaserade program. Användaren får en URL som går direkt till serverdelsprogrammet och kringgår den omvända proxyn.

Viktigt

På grund av den här säkerhetsrisken måste du se till att serverdelswebbprogrammet endast accepterar nätverkstrafik direkt från den omvända proxyn (till exempel genom att använda åtkomstbegränsningar i App Service). Om du gör det, även om en felaktig absolut URL genereras, fungerar den åtminstone inte och kan inte användas av en obehörig användare för att kringgå brandväggen.

Felaktiga omdirigerings-URL:er

Ett vanligt och mer specifikt fall av föregående scenario inträffar när absoluta omdirigerings-URL:er genereras. Dessa URL:er krävs av identitetstjänster som Azure AD när du använder webbläsarbaserade identitetsprotokoll som OpenID Connect, OAuth 2.0 eller SAML 2.0. Dessa omdirigerings-URL:er kan genereras av själva programservern eller mellanprogrammet, eller, som tidigare nämnts, av plattformsfunktioner som App Service autentiserings- och auktoriseringsfunktioner. Det här diagrammet illustrerar problemet:

Diagram som illustrerar problemet med felaktiga omdirigerings-URL:er.

  1. Webbläsaren skickar en begäran om contoso.com till den omvända proxyn.
  2. Den omvända proxyn skriver om värdnamnet till contoso.azurewebsites.net på begäran till serverdelswebbprogrammet (eller till en liknande standarddomän för en annan tjänst).
  3. Programmet genererar en absolut omdirigerings-URL som baseras på det inkommande contoso.azurewebsites.net värdnamnet, till exempel https://contoso.azurewebsites.net/.
  4. Webbläsaren går till identitetsprovidern för att autentisera användaren. Begäran innehåller den genererade omdirigerings-URL:en för att ange var användaren ska returneras efter lyckad autentisering.
  5. Identitetsprovidrar kräver vanligtvis att omdirigerings-URL:er registreras i förväg, så i det här läget bör identitetsprovidern avvisa begäran eftersom den angivna omdirigerings-URL:en inte är registrerad. (Det skulle inte användas.) Om omdirigerings-URL:en av någon anledning är registrerad omdirigerar identitetsprovidern dock webbläsaren till den omdirigerings-URL som anges i autentiseringsbegäran. I det här fallet är https://contoso.azurewebsites.net/URL:en .
  6. Webbläsaren följer den här URL:en, som går direkt till serverdelstjänsten i stället för tillbaka till den omvända proxyn.

Brutna cookies

Ett matchningsfel för värdnamn kan också leda till problem när programservern utfärdar cookies och använder det inkommande värdnamnet för att konstruera Domain attributet för cookien. Attributet Domän säkerställer att cookien endast används för den specifika domänen. Dessa cookies kan genereras av programkoden eller, som tidigare nämnts, av plattformsfunktioner som inställningen App Service ARR-tillhörighet. Det här diagrammet illustrerar problemet:

Diagram som illustrerar en felaktig cookiedomän.

  1. Webbläsaren skickar en begäran om contoso.com till den omvända proxyn.
  2. Den omvända proxyn skriver om värdnamnet som ska finnas contoso.azurewebsites.net i begäran till serverdelswebbprogrammet (eller till en liknande standarddomän för en annan tjänst).
  3. Programmet genererar en cookie som använder en domän baserat på det inkommande contoso.azurewebsites.net värdnamnet. Webbläsaren lagrar cookien för den här specifika domänen i stället för den contoso.com domän som användaren faktiskt använder.
  4. Webbläsaren inkluderar inte cookien för någon efterföljande begäran eftersom cookiens contoso.azurewebsites.net domän inte matchar domänen för contoso.com begäran. Programmet tar inte emot cookien som den utfärdade tidigare. Därför kan användaren förlora tillstånd som ska finnas i cookien, eller så fungerar inte funktioner som ARR-tillhörighet. Tyvärr genererar inget av dessa problem ett fel eller är direkt synliga för slutanvändaren. Det gör dem svåra att felsöka.

Implementeringsvägledning för vanliga Azure-tjänster

För att undvika de potentiella problem som beskrivs här rekommenderar vi att du bevarar det ursprungliga värdnamnet i anropet mellan den omvända proxyn och serverdelsprogramservern:

Diagram som visar en konfiguration där värdnamnet bevaras.

Serverdelskonfiguration

Många webbvärdplattformar kräver att du uttryckligen konfigurerar tillåtna inkommande värdnamn. I följande avsnitt beskrivs hur du implementerar den här konfigurationen för de vanligaste Azure-tjänsterna. Andra plattformar tillhandahåller vanligtvis liknande metoder för att konfigurera anpassade domäner.

Om du är värd för din webbapp i App Service kan du koppla ett anpassat domännamn till webbappen och undvika att använda standardvärdnamnet azurewebsites.net mot serverdelen. Du behöver inte ändra DNS-matchningen när du kopplar en anpassad domän till webbappen: du kan verifiera domänen med hjälp av en TXT post utan att påverka dina vanliga CNAME poster eller A poster. (Dessa poster matchar fortfarande IP-adressen för den omvända proxyn.) Om du behöver TLS/SSL från slutpunkt till slutpunkt kan du importera ett befintligt certifikat från Key Vault eller använda ett App Service-certifikat för din anpassade domän. (Observera att det kostnadsfria App Service hanterade certifikatet inte kan användas i det här fallet, eftersom domänens DNS-post måste matchas direkt till App Service, inte den omvända proxyn.)

Om du använder Spring Apps kan du på samma sätt använda en anpassad domän för din app för att undvika att använda azuremicroservices.io värdnamnet. Du kan importera ett befintligt eller självsignerat certifikat om du behöver TLS/SSL från slutpunkt till slutpunkt.

Om du har en omvänd proxy framför API Management (som också fungerar som en omvänd proxyserver) kan du konfigurera en anpassad domän på din API Management-instans för att undvika att använda azure-api.net värdnamnet. Du kan importera ett befintligt eller kostnadsfritt hanterat certifikat om du behöver TLS/SSL från slutpunkt till slutpunkt. Som tidigare nämnts är DOCK API:er mindre känsliga för de problem som orsakas av matchningar för värdnamn, så den här konfigurationen kanske inte är lika viktig.

Om du är värd för dina program på andra plattformar, till exempel på Kubernetes eller direkt på virtuella datorer, finns det inga inbyggda funktioner som är beroende av det inkommande värdnamnet. Du ansvarar för hur värdnamnet används på själva programservern. Rekommendationen att bevara värdnamnet gäller vanligtvis fortfarande för alla komponenter i ditt program som är beroende av det, såvida du inte specifikt gör ditt program medvetet om omvända proxyservrar och respekterar forwardedX-Forwarded-Host eller huvuden, till exempel.

Omvänd proxykonfiguration

När du definierar serverdelarna i den omvända proxyn kan du fortfarande använda standarddomänen för serverdelstjänsten, https://contoso.azurewebsites.net/till exempel . Den här URL:en används av den omvända proxyn för att matcha rätt IP-adress för serverdelstjänsten. Om du använder plattformens standarddomän är IP-adressen alltid korrekt. Du kan vanligtvis inte använda den offentliga domänen, till exempel contoso.com, eftersom den bör matcha ip-adressen för den omvända proxyn. (Såvida du inte använder mer avancerade DNS-matchningstekniker, till exempel DNS med delad horisont).

Viktigt

Om du har en nästa generations brandvägg som Azure Firewall Premium mellan den omvända proxyn och den sista serverdelen kan du behöva använda DNS med delad horisont. Den här typen av brandvägg kan uttryckligen kontrollera om HTTP-huvudet Host matchar mål-IP-adressen. I dessa fall bör det ursprungliga värdnamnet som används av webbläsaren matcha IP-adressen för den omvända proxyn när den nås från det offentliga Internet. Från brandväggens synvinkel bör dock värdnamnet matcha IP-adressen för den slutliga serverdelstjänsten. Mer information finns i Nätverk med noll förtroende för webbprogram med Azure Firewall och Application Gateway.

De flesta omvända proxyservrar låter dig konfigurera vilket värdnamn som skickas till serverdelstjänsten. Följande information förklarar hur du för de vanligaste Azure-tjänsterna ser till att det ursprungliga värdnamnet för den inkommande begäran används.

Anteckning

I samtliga fall kan du också välja att åsidosätta värdnamnet med en uttryckligen definierad anpassad domän i stället för att ta den från den inkommande begäran. Om programmet bara använder en enda domän kan den metoden fungera bra. Om samma programdistribution accepterar begäranden från flera domäner (till exempel i scenarier med flera klienter) kan du inte statiskt definiera en enda domän. Du bör ta värdnamnet från den inkommande begäran (igen, såvida inte programmet uttryckligen kodas för att ta hänsyn till ytterligare HTTP-huvuden). Därför är den allmänna rekommendationen att du inte ska åsidosätta värdnamnet alls. Skicka det inkommande värdnamnet oförändrad till serverdelen.

Application Gateway

Om du använder Application Gateway som omvänd proxy kan du se till att det ursprungliga värdnamnet bevaras genom att inaktivera Åsidosätt med nytt värdnamn i HTTP-inställningen för serverdelen. Om du gör det inaktiveras både Välj värdnamn från serverdelsadressen och Åsidosätt med ett specifikt domännamn. (Båda dessa inställningar åsidosätter värdnamnet.) I Egenskaperna för Azure Resource Manager för Application Gateway motsvarar den här konfigurationen hostName att egenskapen anges till null och pickHostNameFromBackendAddress till false.

Eftersom hälsoavsökningar skickas utanför kontexten för en inkommande begäran kan de inte dynamiskt fastställa rätt värdnamn. I stället måste du skapa en anpassad hälsoavsökning, inaktivera Välj värdnamn från HTTP-inställningarna för serverdelen och uttryckligen ange värdnamnet. För det här värdnamnet bör du också använda en lämplig anpassad domän för konsekvens. (Du kan dock använda standarddomänen för värdplattformen här, eftersom hälsoavsökningar ignorerar felaktiga cookies eller omdirigerings-URL:er i svaret.)

Azure Front Door

Om du använder Azure Front Door kan du undvika att åsidosätta värdnamnet genom att lämna serverdelens värdhuvud tomt i serverdelspooldefinitionen. I den Resource Manager definitionen av serverdelspoolen motsvarar den här konfigurationen inställningen backendHostHeader till null.

Om du använder Azure Front Door Standard eller Premium kan du bevara värdnamnet genom att lämna ursprungsvärdhuvudet tomt i ursprungsdefinitionen. I den Resource Manager definitionen av ursprunget motsvarar den här konfigurationen inställningen originHostHeader till null.

API Management

Som standard åsidosätter API Management värdnamnet som skickas till serverdelen med värdkomponenten i API:ets webbtjänst-URL (vilket motsvarar serviceUrl värdet för Resource Manager definition av API:et).

Du kan tvinga API Management att i stället använda värdnamnet för den inkommande begäran genom att lägga till en inboundprincip för Ange HTTP-huvud enligt följande:

<inbound>
  <base />
  <set-header name="Host" exists-action="override">
    <value>@(context.Request.OriginalUrl.Host)</value>
  </set-header>
</inbound>

Som tidigare nämnts är DOCK API:er mindre känsliga för de problem som orsakas av matchningar för värdnamn, så den här konfigurationen kanske inte är lika viktig.

Nästa steg