Editar

Compartir a través de


Conservar el nombre de host HTTP original entre un proxy inverso y su aplicación web back-end

Azure API Management
Azure App Service
Azure Application Gateway
Azure Front Door
Azure Spring Apps

Se recomienda conservar el nombre de host HTTP original al usar un proxy inverso delante de una aplicación web. Tener un nombre de host diferente en el proxy inverso que el que se proporciona al servidor de aplicaciones back-end puede provocar cookies o redirigir direcciones URL que no funcionan correctamente. Por ejemplo, el estado de sesión puede perderse, la autenticación puede producir errores o las direcciones URL de back-end se pueden exponer accidentalmente a los usuarios finales. Puede evitar estos problemas conservando el nombre de host de la solicitud inicial para que el servidor de aplicaciones vea el mismo dominio que el explorador web.

Esta guía se aplica especialmente a las aplicaciones hospedadas en ofertas de plataforma como servicio (PaaS), como Azure App Service y Azure Spring Apps. En este artículo se proporcionan instrucciones de implementación de específicas para Azure Application Gateway, Azure Front Doory Azure API Management, que se usan habitualmente servicios de proxy inverso.

Nota

Las API web suelen ser menos sensibles a los problemas causados por errores de coincidencia de nombres de host. Normalmente no dependen de cookies, a menos que use cookies para proteger las comunicaciones entre una aplicación de página única y su API de back-end, por ejemplo, en un patrón conocido como back-end back-ends for Frontends. Las API web a menudo no devuelven direcciones URL absolutas a sí mismas, excepto en determinados estilos de API, como open Data Protocol (OData) y HATEOAS. Si la implementación de la API depende de las cookies o genera direcciones URL absolutas, se aplica la guía proporcionada en este artículo.

Si necesita TLS/SSL de un extremo a otro (la conexión entre el proxy inverso y el servicio back-end usa HTTPS), el servicio back-end también necesita un certificado TLS coincidente para el nombre de host original. Este requisito agrega complejidad operativa al implementar y renovar certificados, pero muchos servicios paaS ofrecen certificados TLS gratuitos que están totalmente administrados.

Contexto

Host de una solicitud HTTP

En muchos casos, el servidor de aplicaciones o algún componente de la canalización de solicitudes necesita el nombre de dominio de Internet que usó el explorador para acceder a él. Este es el host de de la solicitud. Puede ser una dirección IP, pero normalmente es un nombre como contoso.com (que el explorador resuelve en una dirección IP mediante DNS). Normalmente, el valor de host se determina a partir del componente host del URI de solicitud, que el explorador envía a la aplicación como encabezado HTTP Host.

Importante

Nunca use el valor del host en un mecanismo de seguridad. El explorador proporciona el valor o algún otro agente de usuario y un usuario final puede manipularlo fácilmente.

En algunos escenarios, especialmente cuando hay un proxy inverso HTTP en la cadena de solicitudes, el encabezado de host original puede cambiarse antes de llegar al servidor de aplicaciones. Un proxy inverso cierra la sesión de red del cliente y configura una nueva conexión al back-end. En esta nueva sesión, puede transferir el nombre de host original de la sesión de cliente o establecer uno nuevo. En este último caso, el proxy a menudo sigue enviando el valor de host original en otros encabezados HTTP, como Forwarded o X-Forwarded-Host. Este valor permite a las aplicaciones determinar el nombre de host original, pero solo si están codificados para leer estos encabezados.

¿Por qué las plataformas web usan el nombre de host?

Los servicios PaaS multiinquilino suelen requerir un nombre de host registrado y validado para enrutar una solicitud entrante al servidor back-end del inquilino adecuado. Esto se debe a que normalmente hay un grupo compartido de equilibradores de carga que aceptan solicitudes entrantes para todos los inquilinos. Los inquilinos suelen usar el nombre de host entrante para buscar el back-end correcto para el inquilino del cliente.

Para facilitar la introducción, estas plataformas suelen proporcionar un dominio predeterminado preconfigurado para enrutar el tráfico a la instancia implementada. Para App Service, este dominio predeterminado es azurewebsites.net. Cada aplicación web que cree obtiene su propio subdominio, por ejemplo, contoso.azurewebsites.net. Del mismo modo, el dominio predeterminado es azuremicroservices.io para Azure Spring Apps y azure-api.net para API Management.

En el caso de las implementaciones de producción, no se usan estos dominios predeterminados. En su lugar, proporcione su propio dominio para alinearse con la marca de su organización o aplicación. Por ejemplo, contoso.com podría resolverse en segundo plano en la aplicación web contoso.azurewebsites.net en App Service, pero este dominio no debería ser visible para un usuario final que visite el sitio web. Sin embargo, este nombre de host personalizado contoso.com debe registrarse con el servicio PaaS, por lo que la plataforma puede identificar el servidor back-end que debe responder a la solicitud.

Diagrama que ilustra el enrutamiento basado en host en App Service.

¿Por qué las aplicaciones usan el nombre de host?

Dos razones comunes por las que un servidor de aplicaciones necesita el nombre de host son construir direcciones URL absolutas y emitir cookies para un dominio específico. Por ejemplo, cuando el código de la aplicación necesita:

  • Devuelve una dirección URL absoluta en lugar de una dirección URL relativa en su respuesta HTTP (aunque generalmente los sitios web tienden a representar vínculos relativos siempre que sea posible).
  • Genere una dirección URL que se usará fuera de su respuesta HTTP donde no se pueden usar direcciones URL relativas, como para enviar por correo electrónico un vínculo al sitio web a un usuario.
  • Genere una dirección URL de redirección absoluta para un servicio externo. Por ejemplo, en un servicio de autenticación como Microsoft Entra ID para indicar dónde debe devolver el usuario después de la autenticación correcta.
  • Emita cookies HTTP restringidas a un determinado host, tal como se define en el atributo Domain de la cookie.

Puede cumplir todos estos requisitos agregando el nombre de host esperado a la configuración de la aplicación y usando ese valor definido estáticamente en lugar del nombre de host entrante en la solicitud. Sin embargo, este enfoque complica el desarrollo y la implementación de aplicaciones. Además, una única instalación de la aplicación puede servir a varios hosts. Por ejemplo, se puede usar una sola aplicación web para varios inquilinos de aplicación que tienen sus propios nombres de host únicos (como tenant1.contoso.com y tenant2.contoso.com).

Y a veces los componentes que están fuera del código de la aplicación o en middleware en el servidor de aplicaciones en el que no tiene control total. Estos son algunos ejemplos:

  • En App Service, puede aplicar HTTPS para la aplicación web. Si lo hace, las solicitudes HTTP que no son seguras se redirigen a HTTPS. En este caso, el nombre de host entrante se usa para generar la dirección URL absoluta para el encabezado de Location de redirección HTTP.
  • Azure Spring Apps usa una característica similar a aplicar https. También usa el host entrante para generar la dirección URL HTTPS.
  • App Service tiene un configuración de afinidad de ARR para habilitar las sesiones permanentes, de modo que las solicitudes de la misma instancia del explorador siempre las atiende el mismo servidor back-end. Esto se realiza mediante los front-ends de App Service, que agregan una cookie a la respuesta HTTP. El Domain de la cookie se establece en el host entrante.
  • App Service proporciona funcionalidades de autenticación y autorización para permitir a los usuarios iniciar sesión y acceder fácilmente a los datos en las API.

¿Por qué podría ser tentado a invalidar el nombre de host?

Supongamos que crea una aplicación web en App Service que tiene un dominio predeterminado de contoso.azurewebsites.net. (O en otro servicio como Azure Spring Apps). No ha configurado un dominio personalizado en App Service. Para colocar un proxy inverso como Application Gateway (o cualquier servicio similar) delante de esta aplicación, establezca el registro DNS de contoso.com para resolverlo en la dirección IP de Application Gateway. Por lo tanto, recibe la solicitud de contoso.com desde el explorador y está configurada para reenviar esa solicitud a la dirección IP a la que se resuelve contoso.azurewebsites.net: este es el servicio back-end final para el host solicitado. Sin embargo, en este caso, App Service no reconoce el contoso.com dominio personalizado y rechaza todas las solicitudes entrantes para este nombre de host. No puede determinar dónde enrutar la solicitud.

Puede parecer que la manera sencilla de hacer que esta configuración funcione es invalidar o reescribir el encabezado Host de la solicitud HTTP en Application Gateway y establecerlo en el valor de contoso.azurewebsites.net. Si lo hace, la solicitud saliente de Application Gateway hace que parezca que la solicitud original estaba pensada para contoso.azurewebsites.net en lugar de contoso.com:

Diagrama que muestra una configuración con el nombre de host invalidado.

En este momento, App Service reconoce el nombre de host y acepta la solicitud sin necesidad de configurar un nombre de dominio personalizado. De hecho, Application Gateway facilita la invalidación del encabezado de host con el host del grupo de back-end. Azure Front Door lo hace de forma predeterminada.

Sin embargo, el problema con esta solución es que puede provocar varios problemas cuando la aplicación no ve el nombre de host original.

Posibles problemas

Direcciones URL absolutas incorrectas

Si el nombre de host original no se conserva y el servidor de aplicaciones usa el nombre de host entrante para generar direcciones URL absolutas, el dominio back-end podría revelarse a un usuario final. El código de la aplicación podría generar estas direcciones URL absolutas o, como se indicó anteriormente, mediante características de plataforma como la compatibilidad con el redireccionamiento HTTP a HTTPS en App Service y Azure Spring Apps. En este diagrama se muestra el problema:

Diagrama que ilustra el problema de direcciones URL absolutas incorrectas.

  1. El explorador envía una solicitud de contoso.com al proxy inverso.
  2. El proxy inverso vuelve a escribir el nombre de host para contoso.azurewebsites.net en la solicitud a la aplicación web back-end (o a un dominio predeterminado similar para otro servicio).
  3. La aplicación genera una dirección URL absoluta basada en el nombre de host de contoso.azurewebsites.net entrante, por ejemplo, https://contoso.azurewebsites.net/.
  4. El explorador sigue esta dirección URL, que va directamente al servicio back-end en lugar de volver al proxy inverso en contoso.com.

Esto puede incluso suponer un riesgo de seguridad en el caso común en el que el proxy inverso también actúa como firewall de aplicaciones web. El usuario recibe una dirección URL que va directamente a la aplicación back-end y omite el proxy inverso.

Importante

Debido a este riesgo de seguridad, debe asegurarse de que la aplicación web back-end solo acepta directamente el tráfico de red del proxy inverso (por ejemplo, mediante el uso de restricciones de acceso en App Service). Si lo hace, incluso si se genera una dirección URL absoluta incorrecta, al menos no funciona y no puede ser utilizado por un usuario malintencionado para omitir el firewall.

Direcciones URL de redirección incorrectas

Un caso común y más específico del escenario anterior se produce cuando se generan direcciones URL de redirección absolutas. Estos servicios de identidad requieren estas direcciones URL, como Microsoft Entra ID, cuando se usan protocolos de identidad basados en explorador como OpenID Connect, Open Authorization (OAuth) 2.0 o Security Assertion Markup Language (SAML) 2.0. Estas direcciones URL de redireccionamiento podrían generarse mediante el propio servidor de aplicaciones o el middleware, o bien, como se indicó anteriormente, por características de plataforma como app service funcionalidades de autenticación y autorización. En este diagrama se muestra el problema:

Diagrama que muestra el problema de direcciones URL de redirección incorrectas.

  1. El explorador envía una solicitud de contoso.com al proxy inverso.
  2. El proxy inverso vuelve a escribir el nombre de host para contoso.azurewebsites.net en la solicitud a la aplicación web back-end (o a un dominio predeterminado similar para otro servicio).
  3. La aplicación genera una dirección URL de redirección absoluta basada en el nombre de host de contoso.azurewebsites.net entrante, por ejemplo, https://contoso.azurewebsites.net/.
  4. El explorador va al proveedor de identidades para autenticar al usuario. La solicitud incluye la dirección URL de redireccionamiento generada para indicar dónde devolver el usuario después de la autenticación correcta.
  5. Normalmente, los proveedores de identidades requieren que las direcciones URL de redirección se registren por adelantado, por lo que, en este momento, el proveedor de identidades debe rechazar la solicitud porque la dirección URL de redireccionamiento proporcionada no está registrada. (No se suponía que se usara). Sin embargo, si por algún motivo se registra la dirección URL de redireccionamiento, el proveedor de identidades redirige el explorador a la dirección URL de redireccionamiento especificada en la solicitud de autenticación. En este caso, la dirección URL es https://contoso.azurewebsites.net/.
  6. El explorador sigue esta dirección URL, que va directamente al servicio back-end en lugar de volver al proxy inverso.

Cookies rotas

Un error de coincidencia de nombres de host también puede provocar problemas cuando el servidor de aplicaciones emite cookies y usa el nombre de host entrante para construir el atributo Domain de la cookie. El atributo Domain garantiza que la cookie solo se usará para ese dominio específico. Estas cookies se pueden generar mediante el código de aplicación o, como se indicó anteriormente, mediante características de plataforma como app service configuración de afinidad de ARR. En este diagrama se muestra el problema:

Diagrama que ilustra un dominio de cookies incorrecto.

  1. El explorador envía una solicitud de contoso.com al proxy inverso.
  2. El proxy inverso vuelve a escribir el nombre de host que se va a contoso.azurewebsites.net en la solicitud a la aplicación web back-end (o a un dominio predeterminado similar para otro servicio).
  3. La aplicación genera una cookie que usa un dominio basado en el nombre de host de contoso.azurewebsites.net entrante. El explorador almacena la cookie para este dominio específico en lugar del dominio contoso.com que el usuario está usando realmente.
  4. El explorador no incluye la cookie en ninguna solicitud posterior de contoso.com porque el dominio contoso.azurewebsites.net de la cookie no coincide con el dominio de la solicitud. La aplicación no recibe la cookie que emitió anteriormente. Como consecuencia, el usuario podría perder el estado que se supone que está en la cookie, o las características como la afinidad de ARR no funcionan. Desafortunadamente, ninguno de estos problemas genera un error o está directamente visible para el usuario final. Esto dificulta la solución de problemas.

Guía de implementación para los servicios comunes de Azure

Para evitar los posibles problemas descritos aquí, se recomienda conservar el nombre de host original en la llamada entre el proxy inverso y el servidor de aplicaciones back-end:

Diagrama que muestra una configuración en la que se conserva el nombre de host.

Configuración de back-end

Muchas plataformas de hospedaje web requieren que configure explícitamente los nombres de host entrantes permitidos. En las secciones siguientes se describe cómo implementar esta configuración para los servicios de Azure más comunes. Otras plataformas suelen proporcionar métodos similares para configurar dominios personalizados.

Si hospeda la aplicación web en App Service, puede adjuntar un nombre de dominio personalizado a la aplicación web y evitar usar el nombre de host predeterminado azurewebsites.net hacia el back-end. No es necesario cambiar la resolución DNS al adjuntar un dominio personalizado a la aplicación web: puede comprobar el dominio mediante un registro de TXT sin afectar a los registros CNAME o A normales. (Estos registros se resolverán en la dirección IP del proxy inverso). Si necesita TLS/SSL de un extremo a otro, puede importar un certificado existente desde key Vault o usar un de certificado de App Service de para el dominio personalizado. (Tenga en cuenta que, en este caso, no se puede usar el certificado administrado de App Service gratuito, ya que requiere que el registro DNS del dominio se resuelva directamente en App Service, no en el proxy inverso).

Del mismo modo, si usa Spring Apps, puede usar un dominio personalizado para la aplicación para evitar usar el nombre de host de azuremicroservices.io. Puede importar un certificado existente o autofirmado si necesita TLS/SSL de un extremo a otro.

Si tiene un proxy inverso delante de API Management (que también actúa como proxy inverso), puede configurar un dominio personalizado en la instancia de API Management para evitar usar el nombre de host de azure-api.net. Puede importar un certificado administrado existente o gratuito si necesita TLS/SSL de un extremo a otro. Como se indicó anteriormente, las API son menos sensibles a los problemas causados por errores de coincidencia de nombres de host, por lo que es posible que esta configuración no sea tan importante.

Si hospeda las aplicaciones en otras plataformas, como en Kubernetes o directamente en máquinas virtuales, no hay ninguna funcionalidad integrada que dependa del nombre de host entrante. Es responsable de cómo se usa el nombre de host en el propio servidor de aplicaciones. La recomendación para conservar el nombre de host normalmente sigue siendo aplicable a los componentes de la aplicación que dependen de él, a menos que específicamente haga que la aplicación tenga en cuenta los servidores proxy inversos y respete los encabezados forwarded o X-Forwarded-Host, por ejemplo.

Configuración de proxy inverso

Al definir los back-ends dentro del proxy inverso, todavía puede usar el dominio predeterminado del servicio back-end, por ejemplo, https://contoso.azurewebsites.net/. El proxy inverso usa esta dirección URL para resolver la dirección IP correcta para el servicio back-end. Si usa el dominio predeterminado de la plataforma, siempre se garantiza que la dirección IP sea correcta. Normalmente no se puede usar el dominio orientado al público, como contoso.com, porque debe resolverse en la dirección IP del propio proxy inverso. (A menos que use técnicas de resolución de DNS más avanzadas, como DNS de horizonte dividido).

Importante

Si tiene un firewall de última generación como Azure Firewall Premium entre el proxy inverso y el back-end final, es posible que tenga que usar DNS de horizonte dividido. Este tipo de firewall podría comprobar explícitamente si el encabezado de Host HTTP se resuelve en la dirección IP de destino. En estos casos, el nombre de host original que usa el explorador debe resolverse en la dirección IP del proxy inverso cuando se accede desde la red pública de Internet. Sin embargo, desde el punto de vista del firewall, ese nombre de host debe resolverse en la dirección IP del servicio back-end final. Para más información, consulte red de confianza cero para aplicaciones web con Azure Firewall y Application Gateway.

La mayoría de los servidores proxy inversos permiten configurar el nombre de host que se pasa al servicio back-end. En la siguiente información se explica cómo asegurarse de que, para los servicios de Azure más comunes, se usa el nombre de host original de la solicitud entrante.

Nota

En todos los casos, también puede optar por invalidar el nombre de host con un dominio personalizado definido explícitamente en lugar de tomarlo de la solicitud entrante. Si la aplicación solo usa un dominio único, ese enfoque podría funcionar bien. Si la misma implementación de aplicaciones acepta solicitudes de varios dominios (por ejemplo, en escenarios multiinquilino), no puede definir estáticamente un solo dominio. Debe tomar el nombre de host de la solicitud entrante (de nuevo, a menos que la aplicación esté codificada explícitamente para tener en cuenta encabezados HTTP adicionales). Por lo tanto, la recomendación general es que no debe invalidar el nombre de host en absoluto. Pase el nombre de host entrante sin modificar al back-end.

Application Gateway

Si usa Application Gateway como proxy inverso, puede asegurarse de que el nombre de host original se conserva deshabilitando Invalidar con el nuevo nombre de host en la configuración HTTP de back-end. Al hacerlo, se deshabilitan ambos Seleccionar nombre de host de la dirección de back-end y Invalidar con un nombre de dominio específico. (Ambas opciones de configuración invalidan el nombre de host). En las propiedades de Azure Resource Manager para Application Gateway, esta configuración corresponde a establecer la propiedad hostName en null y pickHostNameFromBackendAddress en false.

Dado que los sondeos de estado se envían fuera del contexto de una solicitud entrante, no pueden determinar dinámicamente el nombre de host correcto. En su lugar, debe crear un sondeo de estado personalizado, deshabilitar Seleccionar nombre de host de la configuración HTTP de back-endy especificar explícitamente el nombre de host. Para este nombre de host, también debe usar un dominio personalizado adecuado para la coherencia. (Sin embargo, puede usar aquí el dominio predeterminado de la plataforma de hospedaje, ya que los sondeos de estado omiten las cookies incorrectas o las direcciones URL de redirección en la respuesta).

Azure Front Door

Si usa Azure Front Door, puede conservar el nombre de host dejando el encabezado de host de origen de en blanco en la definición de origen. En la definición de Resource Manager delde origen , esta configuración corresponde a establecer originHostHeader en null.

API Management

De forma predeterminada, API Management invalida el nombre de host que se envía al back-end con el componente host de la dirección URL del servicio web de la API (que corresponde al valor serviceUrl de la definición de Resource Manager de de la API).

Puede forzar a API Management a usar en su lugar el nombre de host de la solicitud entrante agregando una directiva de inboundEstablecer encabezado, como se indica a continuación:

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

Como se indicó anteriormente, las API son menos sensibles a los problemas causados por errores de coincidencia de nombres de host, por lo que es posible que esta configuración no sea tan importante.

Pasos siguientes