Cada línea del registro de acceso muestra la misma dirección de loopback, mientras la página carga y el certificado se valida correctamente. Nada está roto en el sentido de ser inaccesible, y por eso esto sobrevive durante meses. Lo que se rompió es la atribución: el backend web registra la dirección del salto que reenvió la conexión, y cada decisión posterior que confió en el registro heredó la misma respuesta equivocada.

Las comprobaciones siguientes van del cable hacia dentro. Deténgase en la primera que explique el valor que ve, porque cada paso posterior supone que los anteriores ya son ciertos. Ninguna de ellas requiere adivinar la configuración del front-end.

Siga las dos conexiones, no la línea del registro

Port-Share multiplexa dos protocolos en un único escucha TCP. OpenVPN inspecciona los primeros bytes de una conexión entrante, la conserva cuando parece de su propio protocolo y entrega cualquier otra cosa a un segundo destino. Ese destino suele ser un servidor web en el mismo host, así que el socket aceptado del servidor web tiene el proceso OpenVPN como par.

ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'

El primer comando muestra quién posee el escucha público. El segundo muestra las conexiones que llegan al puerto del backend, y la dirección de su par es la que imprimirá el registro de acceso. Si ese par es loopback, el registro es exacto y la información se perdió una capa antes. Renombrar el campo del registro o activar un módulo de IP de cliente no recuperará una dirección que la conexión nunca llevó.

Esta es la comprobación que decide todo lo demás. Si el par del backend es la dirección del navegador, compartir el puerto no es su problema y el formato del registro sí lo es.

El reenvío de transporte no es inyección de cabeceras

El reenviador mueve bytes. No analiza HTTP, así que no puede insertar una cabecera en una petición que nunca lee como petición, ni puede añadir nada a un flujo TLS que deja pasar intacto. Un módulo que espera una cabecera de proxy seguirá esperando una que ningún componente produce.

Dos mecanismos pueden portar la dirección original, y ambos requieren acuerdo en ambos extremos. El protocolo PROXY antepone una cabecera pequeña a la conexión, y el backend debe estar configurado para esperarla; un backend que no la espera tratará esos bytes como el inicio de la petición y fallará de forma confusa. Las cabeceras de proxy de confianza como X-Forwarded-For funcionan cuando un proxy que entiende HTTP las establece y al backend se le dice qué pares pueden afirmarlas.

Ninguno de los dos es automático, y ninguno es seguro por defecto. Un backend que cree cualquier cabecera reenviada entrante permite que un cliente elija su propia dirección, lo que convierte una imprecisión del registro en una elusión del control de acceso. Ejecute la demostración una vez en un host de pruebas antes de confiar en cualquier cabecera en una ruta de producción.

curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3

El directorio opcional de asignación de origen

Compartir el puerto tiene un argumento de directorio opcional que registra una asignación entre la dirección de origen original y la conexión de reenvío, en plataformas donde la función está implementada. Se espera que el lado web consulte esa asignación; no es una cabecera y no se inyecta en la petición.

Ese diseño merece conocerse porque explica por qué algunos despliegues informan direcciones reales y otros no, con una configuración de front-end aparentemente idéntica. La diferencia está en el lado receptor, y suele vivir en un módulo o parche que la mayoría de los servidores web empaquetados no activan por defecto. Lea la documentación de su servidor web para conocer el gancho exacto que ofrece y confirme que el módulo está cargado en lugar de suponerlo.

Si sigue este camino, trátelo como una integración de dos mitades: la asignación que escribe el reenviador y la consulta que hace el backend. Verifique ambas y confirme que el directorio sobrevive a un reinicio y no crece sin límite en un escucha ocupado.

Decida qué componente avala la dirección

Antes de cambiar la configuración, nombre el componente al que se permite afirmar una dirección de cliente y los componentes a los que se permite creerla. Una única respuesta escrita evita la deriva habitual, en la que tres capas distintas confían cada una en una fuente distinta.

Tres diseños cubren la mayoría de las necesidades. Mantenga separados el escucha público y el escucha web, de modo que el servidor web vea pares reales y no exista problema de atribución. Ponga delante un proxy inverso que entienda HTTP, termine o analice la petición allí y déjele establecer una cabecera reenviada para un backend que solo confía en ese proxy. O mantenga el puerto compartido y acepte que los registros muestran el salto, con reglas de acceso escritas contra la identidad de la aplicación en lugar de una dirección.

Lo que no funciona es tratar una dirección de loopback reenviada como prueba de que la petición se originó en esta máquina. Esa inferencia es exactamente al revés: la dirección está presente precisamente porque un componente local hizo la conexión. Una regla escrita así admite a cualquiera que pueda alcanzar el escucha.

Pruebe la regla, no la página

Una página que carga demuestra que el camino de reenvío funciona y no dice nada sobre la atribución. Pruebe el consumidor de la dirección: la regla de acceso, el límite de tasa, la entrada de auditoría, la consulta geográfica.

curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log

Compare una petición externa autorizada con los registros tanto del front-end como del backend y confirme que una regla que debería denegar sigue denegando y una que debería admitir sigue admitiendo. Si la línea del registro es correcta pero la regla sigue comportándose como si todos fueran locales, la regla lee un campo distinto del que usted corrigió.

Termine escribiendo la cadena de atribución en las notas de despliegue: qué escucha, qué reenviador, qué cabecera o asignación y qué backend está configurado para confiar en ella. La siguiente persona que lea una línea de registro necesitará las cuatro, y la ausencia de esa nota es cómo el mismo ticket se reabre un año después. Manténgala junto a la configuración y no en un hilo de chat.

Artículos relacionados