Nous vous recommandons de conserver le nom d’hôte HTTP d’origine lorsque vous utilisez un proxy inverse devant une application web. Le fait d’avoir un autre nom d’hôte au proxy inverse que celui fourni au serveur d’applications back-end peut entraîner des cookies ou des URL de redirection qui ne fonctionnent pas correctement. Par exemple, l’état de session peut être perdu, l’authentification peut échouer ou les URL principales peuvent être exposées par inadvertance aux utilisateurs finaux. Vous pouvez éviter ces problèmes en conservant le nom d’hôte de la requête initiale afin que le serveur d’applications voit le même domaine que le navigateur web.
Ces conseils s’appliquent en particulier aux applications hébergées dans des offres PaaS (Platform as a Service), comme Azure App Service et Azure Spring Apps. Cet article fournit des instructions d’implémentation spécifiques pour Azure Application Gateway, Azure Front Dooret gestion des API Azure, qui sont couramment utilisés pour les services de proxy inverse.
Note
Les API web sont généralement moins sensibles aux problèmes causés par les incompatibilités de nom d’hôte. Ils ne dépendent généralement pas des cookies, sauf si vous utiliser des cookies pour sécuriser les communications entre une application monopage et sond’API back-end, par exemple, dans un modèle connu sous le nom de serveurs principaux pour les serveurs frontaux. Les API web ne retournent souvent pas d’URL absolues à elles-mêmes, sauf dans certains styles d’API, comme Open Data Protocol (OData) et HATEOAS. Si votre implémentation d’API dépend des cookies ou génère des URL absolues, les instructions fournies dans cet article s’appliquent.
Si vous avez besoin de TLS/SSL de bout en bout (la connexion entre le proxy inverse et le service back-end utilise HTTPS), le service principal a également besoin d’un certificat TLS correspondant pour le nom d’hôte d’origine. Cette exigence ajoute une complexité opérationnelle lorsque vous déployez et renouvelez des certificats, mais de nombreux services PaaS offrent des certificats TLS gratuits entièrement gérés.
Contexte
Hôte d’une requête HTTP
Dans de nombreux cas, le serveur d’applications ou un composant du pipeline de requête a besoin du nom de domaine Internet utilisé par le navigateur pour y accéder. Il s’agit de l’hôte de la requête. Il peut s’agir d’une adresse IP, mais il s’agit généralement d’un nom tel que contoso.com
(que le navigateur résout ensuite en adresse IP à l’aide de DNS). La valeur de l’hôte est généralement déterminée à partir du composant hôte de l’URI de requête, que le navigateur envoie à l’application en tant qu’en-tête HTTP Host
.
Important
N’utilisez jamais la valeur de l’hôte dans un mécanisme de sécurité. La valeur est fournie par le navigateur ou un autre agent utilisateur et peut facilement être manipulée par un utilisateur final.
Dans certains scénarios, en particulier lorsqu’il existe un proxy inverse HTTP dans la chaîne de requêtes, l’en-tête d’hôte d’origine peut être modifié avant d’atteindre le serveur d’applications. Un proxy inverse ferme la session réseau cliente et configure une nouvelle connexion au serveur principal. Dans cette nouvelle session, elle peut porter le nom d’hôte d’origine de la session cliente ou en définir une nouvelle. Dans ce dernier cas, le proxy envoie souvent la valeur d’hôte d’origine dans d’autres en-têtes HTTP, comme Forwarded
ou X-Forwarded-Host
. Cette valeur permet aux applications de déterminer le nom d’hôte d’origine, mais uniquement s’ils sont codés pour lire ces en-têtes.
Pourquoi les plateformes web utilisent le nom d’hôte
Les services PaaS multilocataires nécessitent souvent un nom d’hôte inscrit et validé pour acheminer une requête entrante vers le serveur principal du locataire approprié. Cela est dû au fait qu’il existe généralement un pool partagé d’équilibreurs de charge qui acceptent les demandes entrantes pour tous les locataires. Les locataires utilisent généralement le nom d’hôte entrant pour rechercher le serveur principal approprié pour le client client.
Pour faciliter la prise en main, ces plateformes fournissent généralement un domaine par défaut préconfiguré pour router le trafic vers votre instance déployée. Pour App Service, ce domaine par défaut est azurewebsites.net
. Chaque application web que vous créez obtient son propre sous-domaine, par exemple, contoso.azurewebsites.net
. De même, le domaine par défaut est azuremicroservices.io
pour Azure Spring Apps et azure-api.net
pour gestion des API.
Pour les déploiements de production, vous n’utilisez pas ces domaines par défaut. Vous fournissez plutôt votre propre domaine pour vous aligner sur la marque de votre organisation ou de votre application. Par exemple, contoso.com
pourrait résoudre en arrière-plan l’application web contoso.azurewebsites.net
sur App Service, mais ce domaine ne doit pas être visible pour un utilisateur final qui visite le site web. Ce nom d’hôte personnalisé contoso.com
doit être inscrit auprès du service PaaS. Toutefois, la plateforme peut identifier le serveur principal qui doit répondre à la demande.
Pourquoi les applications utilisent le nom d’hôte
Deux raisons courantes pour lesquelles un serveur d’applications a besoin du nom d’hôte sont de construire des URL absolues et de émettre des cookies pour un domaine spécifique. Par exemple, lorsque le code de l’application doit :
- Retourne une URL absolue plutôt qu’une URL relative dans sa réponse HTTP (bien que généralement les sites web aient tendance à afficher des liens relatifs lorsque cela est possible).
- Générez une URL à utiliser en dehors de sa réponse HTTP, où les URL relatives ne peuvent pas être utilisées, comme pour envoyer un lien vers le site web à un utilisateur.
- Générez une URL de redirection absolue pour un service externe. Par exemple, vers un service d’authentification tel que Microsoft Entra ID pour indiquer où il doit retourner l’utilisateur après l’authentification réussie.
- Émettez des cookies HTTP qui sont limités à un certain hôte, comme défini dans l’attribut
Domain
du cookie.
Vous pouvez répondre à toutes ces exigences en ajoutant le nom d’hôte attendu à la configuration de l’application et en utilisant cette valeur définie statiquement au lieu du nom d’hôte entrant sur la demande. Toutefois, cette approche complique le développement et le déploiement des applications. En outre, une seule installation de l’application peut servir plusieurs hôtes. Par exemple, une application web unique peut être utilisée pour plusieurs locataires d’application qui ont tous leurs propres noms d’hôte uniques (tels que tenant1.contoso.com
et tenant2.contoso.com
).
Le nom d’hôte entrant est parfois utilisé par des composants en dehors du code de l’application ou dans le middleware sur le serveur d’applications sur lequel vous n’avez pas de contrôle total. Voici quelques exemples :
- Dans App Service, vous pouvez appliquer des HTTPS pour votre application web. Cela entraîne la redirection vers HTTPS des requêtes HTTP qui ne sont pas sécurisées. Dans ce cas, le nom d’hôte entrant est utilisé pour générer l’URL absolue de l’en-tête de redirection HTTP
Location
. - Azure Spring Apps utilise une fonctionnalité similaire pour appliquer leHTTPS. Il utilise également l’hôte entrant pour générer l’URL HTTPS.
- App Service a un paramètre d’affinité ARR pour activer les sessions sticky, afin que les requêtes provenant de la même instance de navigateur soient toujours traitées par le même serveur principal. Cette opération est effectuée par les serveurs frontaux App Service, qui ajoutent un cookie à la réponse HTTP. Le
Domain
du cookie est défini sur l’hôte entrant. - App Service fournit fonctionnalités d’authentification et d’autorisation pour permettre facilement aux utilisateurs de se connecter et d’accéder aux données dans les API.
- Le nom d’hôte entrant est utilisé pour construire l’URL de redirection vers laquelle le fournisseur d’identité doit retourner l’utilisateur après l’authentification réussie.
- L’activation de cette fonctionnalité par défaut active également la redirection HTTP-to-HTTPS. Là encore, le nom d’hôte entrant est utilisé pour générer l’emplacement de redirection.
Pourquoi vous pourriez être tenté de remplacer le nom d’hôte
Supposons que vous créez une application web dans App Service qui a un domaine par défaut de contoso.azurewebsites.net
. (Ou dans un autre service comme Azure Spring Apps.) Vous n’avez pas configuré de domaine personnalisé sur App Service. Pour placer un proxy inverse comme Application Gateway (ou tout service similaire) devant cette application, vous définissez l’enregistrement DNS pour contoso.com
à résoudre en adresse IP d’Application Gateway. Il reçoit donc la demande de contoso.com
à partir du navigateur et est configuré pour transférer cette requête à l’adresse IP à laquelle contoso.azurewebsites.net
se résout : il s’agit du service principal final de l’hôte demandé. Dans ce cas, Toutefois, App Service ne reconnaît pas le domaine personnalisé contoso.com
et rejette toutes les demandes entrantes pour ce nom d’hôte. Il ne peut pas déterminer où acheminer la requête.
Il peut sembler facile de faire fonctionner cette configuration consiste à remplacer ou à réécrire l’en-tête Host
de la requête HTTP dans Application Gateway et à le définir sur la valeur de contoso.azurewebsites.net
. Si vous le faites, la demande sortante d’Application Gateway le rend comme si la demande d’origine était vraiment destinée à contoso.azurewebsites.net
au lieu de contoso.com
:
À ce stade, App Service reconnaît le nom d’hôte et accepte la demande sans exiger qu’un nom de domaine personnalisé soit configuré. En fait, Application Gateway facilite le remplacement de l’en-tête de l’hôte avec l’hôte du pool principal. Azure Front Door le fait même par défaut.
Toutefois, le problème avec cette solution est qu’il peut entraîner différents problèmes lorsque l’application ne voit pas le nom d’hôte d’origine.
Problèmes potentiels
URL absolues incorrectes
Si le nom d’hôte d’origine n’est pas conservé et que le serveur d’applications utilise le nom d’hôte entrant pour générer des URL absolues, le domaine principal peut être divulgué à un utilisateur final. Ces URL absolues peuvent être générées par le code de l’application ou, comme indiqué précédemment, par des fonctionnalités de plateforme telles que la prise en charge de la redirection HTTP-to-HTTPS dans App Service et Azure Spring Apps. Ce diagramme illustre le problème :
- Le navigateur envoie une demande de
contoso.com
au proxy inverse. - Le proxy inverse réécrit le nom d’hôte pour
contoso.azurewebsites.net
dans la requête adressée à l’application web principale (ou à un domaine par défaut similaire pour un autre service). - L’application génère une URL absolue basée sur le nom d’hôte
contoso.azurewebsites.net
entrant, par exemple,https://contoso.azurewebsites.net/
. - Le navigateur suit cette URL, qui passe directement au service back-end plutôt qu’au proxy inverse à
contoso.com
.
Cela peut même poser un risque de sécurité dans le cas courant où le proxy inverse sert également de pare-feu d’application web. L’utilisateur reçoit une URL qui passe directement à l’application back-end et contourne le proxy inverse.
Important
En raison de ce risque de sécurité, vous devez vous assurer que l’application web principale accepte uniquement directement le trafic réseau du proxy inverse (par exemple, en utilisant des restrictions d’accès dans App Service). Si vous le faites, même si une URL absolue incorrecte est générée, au moins elle ne fonctionne pas et ne peut pas être utilisée par un utilisateur malveillant pour contourner le pare-feu.
URL de redirection incorrectes
Un cas courant et plus spécifique du scénario précédent se produit lorsque des URL de redirection absolues sont générées. Ces URL sont requises par les services d’identité tels que Microsoft Entra ID lorsque vous utilisez des protocoles d’identité basés sur un navigateur tels qu’OpenID Connect, Open Authorization (OAuth) 2.0 ou SAML (Security Assertion Markup Language) 2.0. Ces URL de redirection peuvent être générées par le serveur d’applications ou le middleware lui-même, ou, comme indiqué précédemment, par des fonctionnalités de plateforme telles que l’authentification et les fonctionnalités d’autorisation app service. Ce diagramme illustre le problème :
- Le navigateur envoie une demande de
contoso.com
au proxy inverse. - Le proxy inverse réécrit le nom d’hôte pour
contoso.azurewebsites.net
sur la demande à l’application web principale (ou à un domaine par défaut similaire pour un autre service). - L’application génère une URL de redirection absolue basée sur le nom d’hôte
contoso.azurewebsites.net
entrant, par exemple,https://contoso.azurewebsites.net/
. - Le navigateur accède au fournisseur d’identité pour authentifier l’utilisateur. La demande inclut l’URL de redirection générée pour indiquer où renvoyer l’utilisateur après l’authentification réussie.
- Les fournisseurs d’identité nécessitent généralement l’inscription préalable des URL de redirection. Par conséquent, à ce stade, le fournisseur d’identité doit rejeter la demande, car l’URL de redirection fournie n’est pas inscrite. (Il n’était pas censé être utilisé.) Si, pour une raison quelconque, l’URL de redirection est inscrite, le fournisseur d’identité redirige le navigateur vers l’URL de redirection spécifiée dans la demande d’authentification. Dans ce cas, l’URL est
https://contoso.azurewebsites.net/
. - Le navigateur suit cette URL, qui passe directement au service back-end plutôt qu’au proxy inverse.
Cookies rompus
Une incompatibilité de nom d’hôte peut également entraîner des problèmes lorsque le serveur d’applications émet des cookies et utilise le nom d’hôte entrant pour construire l’attribut Domain
du cookie. L’attribut Domaine garantit que le cookie sera utilisé uniquement pour ce domaine spécifique. Ces cookies peuvent être générés par le code de l’application ou, comme indiqué précédemment, par des fonctionnalités de plateforme telles que le paramètre d’affinité APP Service ARR. Ce diagramme illustre le problème :
- Le navigateur envoie une demande de
contoso.com
au proxy inverse. - Le proxy inverse réécrit le nom d’hôte à
contoso.azurewebsites.net
dans la requête à l’application web back-end (ou à un domaine par défaut similaire pour un autre service). - L’application génère un cookie qui utilise un domaine basé sur le nom d’hôte entrant
contoso.azurewebsites.net
. Le navigateur stocke le cookie pour ce domaine spécifique plutôt que le domainecontoso.com
que l’utilisateur utilise réellement. - Le navigateur n’inclut pas le cookie sur une demande ultérieure de
contoso.com
, car le domainecontoso.azurewebsites.net
du cookie ne correspond pas au domaine de la demande. L’application ne reçoit pas le cookie qu’elle a émis précédemment. Par conséquent, l’utilisateur peut perdre l’état censé se trouver dans le cookie, ou des fonctionnalités telles que l’affinité ARR ne fonctionnent pas. Malheureusement, aucun de ces problèmes ne génère une erreur ou est directement visible par l’utilisateur final. Cela les rend difficiles à résoudre.
Conseils d’implémentation pour les services Azure courants
Pour éviter les problèmes potentiels abordés ici, nous vous recommandons de conserver le nom d’hôte d’origine dans l’appel entre le proxy inverse et le serveur d’applications back-end :
Configuration back-end
De nombreuses plateformes d’hébergement web nécessitent de configurer explicitement les noms d’hôtes entrants autorisés. Les sections suivantes décrivent comment implémenter cette configuration pour les services Azure les plus courants. D’autres plateformes fournissent généralement des méthodes similaires pour configurer des domaines personnalisés.
Si vous hébergez votre application web dans App Service, vous pouvez attacher un nom de domaine personnalisé à l’application web et éviter d’utiliser le nom d’hôte azurewebsites.net
par défaut vers le serveur principal. Vous n’avez pas besoin de modifier votre résolution DNS lorsque vous attachez un domaine personnalisé à l’application web : vous pouvez vérifier le domaine à l’aide d’un enregistrement TXT
sans affecter vos enregistrements de CNAME
ou de A
standard. (Ces enregistrements sont toujours résolus en adresse IP du proxy inverse.) Si vous avez besoin de TLS/SSL de bout en bout, vous pouvez importer un certificat existant à partir de Key Vault ou utiliser un certificat App Service pour votre domaine personnalisé. (Notez que le certificat managé App Service gratuit ne peut pas être utilisé dans ce cas, car il nécessite que l’enregistrement DNS du domaine soit résolu directement vers App Service, et non sur le proxy inverse.)
De même, si vous utilisez Spring Apps, vous pouvez utiliser un domaine personnalisé pour votre application pour éviter d’utiliser le nom d’hôte azuremicroservices.io
. Vous pouvez importer un certificat existant ou auto-signé si vous avez besoin de TLS/SSL de bout en bout.
Si vous avez un proxy inverse devant
Si vous hébergez vos applications sur d’autres plateformes, comme sur Kubernetes ou directement sur des machines virtuelles, il n’existe aucune fonctionnalité intégrée qui dépend du nom d’hôte entrant. Vous êtes responsable de l’utilisation du nom d’hôte dans le serveur d’applications lui-même. La recommandation de conserver le nom d’hôte s’applique généralement aux composants de votre application qui en dépendent, sauf si vous tenez spécifiquement compte des proxys inverses et respectez les en-têtes forwarded
ou X-Forwarded-Host
, par exemple.
Configuration du proxy inverse
Lorsque vous définissez les back-ends dans le proxy inverse, vous pouvez toujours utiliser le domaine par défaut du service principal, par exemple, https://contoso.azurewebsites.net/
. Cette URL est utilisée par le proxy inverse pour résoudre l’adresse IP correcte pour le service back-end. Si vous utilisez le domaine par défaut de la plateforme, l’adresse IP est toujours garantie d’être correcte. En règle générale, vous ne pouvez pas utiliser le domaine public, comme contoso.com
, car il doit être résolu à l’adresse IP du proxy inverse lui-même. (Sauf si vous utilisez des techniques de résolution DNS plus avancées, comme dns à horizon fractionné).
Important
Si vous disposez d’un pare-feu de nouvelle génération comme Pare-feu Azure Premium entre le proxy inverse et le serveur principal final, vous devrez peut-être utiliser dns à horizon fractionné. Ce type de pare-feu peut vérifier explicitement si l’en-tête http Host
est résolu en adresse IP cible. Dans ces cas, le nom d’hôte d’origine utilisé par le navigateur doit être résolu en adresse IP du proxy inverse lorsqu’il est accessible à partir de l’Internet public. Du point de vue du pare-feu, toutefois, ce nom d’hôte doit être résolu en adresse IP du service principal final. Pour plus d’informations, consultez réseau confiance zéro pour les applications web avec le Pare-feu Azure et application Gateway.
La plupart des proxys inverses vous permettent de configurer le nom d’hôte passé au service principal. Les informations suivantes expliquent comment garantir, pour les services Azure les plus courants, que le nom d’hôte d’origine de la requête entrante est utilisé.
Note
Dans tous les cas, vous pouvez également choisir de remplacer le nom d’hôte par un domaine personnalisé explicitement défini plutôt que de le prendre à partir de la requête entrante. Si l’application utilise un seul domaine, cette approche peut fonctionner correctement. Si le même déploiement d’application accepte les requêtes provenant de plusieurs domaines (par exemple, dans des scénarios multilocataires), vous ne pouvez pas définir statiquement un seul domaine. Vous devez prendre le nom d’hôte de la requête entrante (à nouveau, sauf si l’application est explicitement codée pour prendre en compte d’autres en-têtes HTTP). Par conséquent, la recommandation générale est que vous ne devez pas remplacer le nom d’hôte du tout. Transmettez le nom d’hôte entrant non modifié au serveur principal.
Application Gateway
Si vous utilisez application Gateway comme proxy inverse, vous pouvez vous assurer que le nom d’hôte d’origine est conservé en désactivant Remplacer par le nouveau nom d’hôte sur le paramètre HTTP principal. Cela désactive les deux Choisir le nom d’hôte à partir de l’adresse principale et remplacer par un nom de domaine spécifique. (Ces deux paramètres remplacent le nom d’hôte.) Dans les propriétés Azure Resource Manager pour application Gateway, cette configuration correspond à la définition de la propriété hostName
sur null
et pickHostNameFromBackendAddress
sur false
.
Étant donné que les sondes d’intégrité sont envoyées en dehors du contexte d’une requête entrante, elles ne peuvent pas déterminer dynamiquement le nom d’hôte correct. Au lieu de cela, vous devez créer une sonde d’intégrité personnalisée, désactiver Choisir le nom d’hôte à partir des paramètres HTTP principaux, et spécifier explicitement le nom d’hôte. Pour ce nom d’hôte, vous devez également utiliser un domaine personnalisé approprié pour assurer la cohérence. (Toutefois, vous pouvez utiliser le domaine par défaut de la plateforme d’hébergement ici, car les sondes d’intégrité ignorent les cookies incorrects ou les URL de redirection dans la réponse.)
Azure Front Door
Si vous utilisez Azure Front Door, vous pouvez conserver le nom d’hôte en laissant l’en-tête de l’hôte d’origine vide dans la définition d’origine. Dans la définition Resource Manager de l'd’origine, cette configuration correspond à la définition originHostHeader
sur null
.
Gestion des API
Par défaut, Gestion des API remplace le nom d’hôte envoyé au serveur principal par le composant hôte de l’URL du service web de l’API (qui correspond à la valeur serviceUrl
de la définition Resource Manager de l’API).
Vous pouvez forcer la gestion des API à utiliser au lieu de cela le nom d’hôte de la requête entrante en ajoutant un en-tête inbound
Définir l’en-tête stratégie, comme suit :
<inbound>
<base />
<set-header name="Host" exists-action="override">
<value>@(context.Request.OriginalUrl.Host)</value>
</set-header>
</inbound>
Comme indiqué précédemment, les API sont moins sensibles aux problèmes causés par les incompatibilités de nom d’hôte. Cette configuration peut donc ne pas être aussi importante.
Étapes suivantes
- app Service
- Spring Apps
- Application Gateway
- Azure Front Door
- gestion des API