Una petición que llega a su aplicación lleva dos tipos de pruebas sobre la dirección: el par que abrió la conexión de red y un campo HTTP que afirma la dirección de un cliente anterior. Responden a preguntas distintas. El par de socket se observa, mientras que la cabecera la afirma quien la escribió, y ninguno debería sustituir en silencio al otro en un registro o en una regla de acceso. La comparación siguiente los mantiene separados y después muestra la única disposición en la que la cabecera resulta utilizable.

Describa la ruta antes de comparar nada:

Client -> approved reverse proxy -> application origin

En esa disposición, el par de socket del origen suele ser el proxy, y una cabecera de reenvío puede llevar la afirmación del proxy sobre el cliente. Su valor procede de la relación controlada con ese proxy, no del nombre de la cabecera.

Dos tipos de pruebas sobre la dirección

El par de socket es un hecho sobre una conexión TCP: algo completó un saludo desde esa dirección. No es necesariamente la persona, el dispositivo o la cuenta que le importa, porque una VPN o una salida de Tor pueden ser legítimamente la fuente que observa un servicio. Aun así, es la única dirección que el propio host verificó, y en eso consiste todo su valor.

Un campo de reenvío son metadatos sobre una cadena. X-Forwarded-For, X-Real-IP y el campo estandarizado Forwarded puede escribirlo cualquier cliente que llegue a un punto final que los reproduzca, así que su fiabilidad depende por completo de a quién se le permitió establecerlos.

Mantenga ambos en el contexto de la petición con nombres distintos. Una aplicación que sobrescribe el par con la cabecera pierde la capacidad de reconstruir más tarde un error de confianza, y eso es justo cuando lo necesita.

Una cabecera nunca redirige la conexión

Escribir una dirección en un campo de reenvío no cambia el origen de la conexión TCP que llega al servidor, ni altera el enrutamiento en ningún punto de la ruta. El enrutamiento VPN ordinario o NAT de origen entrega el tráfico sin ninguna cabecera HTTP. Del mismo modo, una pasarela de tránsito no reescribe un intercambio HTTPS bien protegido sin cambiar la disposición del punto final TLS.

El error inverso es igual de común: HTTPS no vuelve veraz una cabecera de reenvío proporcionada por el cliente. Protege el transporte de una afirmación falsa exactamente igual que el de una verdadera.

Si un colega propone un cambio de cabecera para arreglar un problema de enrutamiento, el diagnóstico ya se ha torcido. Arregle la ruta o arregle la configuración del proxy que escribe la cabecera.

Nombre el proxy autorizado a afirmar

Dos reglas hacen utilizable un campo de reenvío, y ambas son configuración y no código. El borde normaliza o descarta todo lo que llega de fuera, siguiendo su propio comportamiento documentado para esos campos. Después el origen toma una dirección de sustitución de la ruta de proxy que usted nombró y de ningún otro sitio. Esa segunda regla solo se sostiene mientras los clientes no puedan llegar al origen por otra vía, ya que un origen que responde tanto a peticiones directas como a través de proxy no sabe cuál de las dos está sirviendo.

El módulo de IP real de NGINX muestra la división con claridad. set_real_ip_from nombra los remitentes cuya afirmación cuenta, y real_ip_header dice qué campo la porta; el primero ejerce la confianza, el segundo solo dice dónde mirar.

set_real_ip_from 10.20.0.0/24;
real_ip_header X-Forwarded-For;
# real_ip_recursive off - take the rightmost value in the field
# real_ip_recursive on  - walk the list back past every trusted address

Una directiva de selección de cabecera por sí sola sigue sin establecer nada sobre quién envió el valor.

La seguridad del transporte debe recorrer todo el camino entre los componentes en los que confía. Un borde que normaliza correctamente pierde ese valor en el momento en que un salto no protegido más abajo permite que otro edite la afirmación mientras viaja.

Gestione con deliberación las cadenas de varios saltos

Varios proxys necesitan un modelo de cadena explícito. No tome el valor más a la izquierda o más a la derecha separado por comas porque algún artículo de blog lo hiciera; averigüe cuál de sus proxys añade, cuál sustituye y cuál conserva el campo entrante. NGINX, por ejemplo, puede recorrer la lista hacia atrás contra su conjunto de confianza y detenerse en la primera dirección que no posee, y esa es la regla de ese producto, no una ley que siga cada marco de trabajo. Lea la documentación de su propio proxy con las mismas dos preguntas: qué valor selecciona y en qué remitentes cree.

Escriba la cadena: orden de saltos, qué salto establece el campo y qué salto elimina las copias entrantes. Después guarde esa nota junto a la configuración del proxy, no solo en el tique. Después pruébelo enviando una petición con una cabecera falsificada por el proceso de validación aprobado y confirmando que el origen la ignora.

Cuando añada un salto, revise ese documento. Un nuevo balanceador de carga insertado delante del proxy de confianza puede cambiar qué dirección gana sin que nadie edite la aplicación.

Mantenga ambas observaciones en el registro

Donde el diagnóstico esté autorizado, registre el par de la conexión y la dirección de cliente normalizada como dos campos separados, y añada solo los metadatos de reenvío que el propósito realmente necesite. Después demuestre el despliegue con dos peticiones: una a través del proxy que debería registrar ambos valores con sensatez, y un intento directo al origen que debe ser rechazado.

Recuerde qué significa la pareja. La cabecera añade contexto proporcionado por un componente que usted eligió confiar; el par sigue siendo la única dirección que su host vio realmente. Ninguna de las dos es prueba de identidad individual, y un diseño que trate cualquiera de ellas como prueba se equivocará respecto a alguien.

Artículos relacionados