¿Cómo agregar un encabezado de respuesta en nginx cuando se usa proxy_pass?

92

Quiero agregar un encabezado personalizado para la respuesta recibida del servidor detrás de nginx.

Si bien add_headerfunciona para respuestas procesadas por nginx, no hace nada cuando proxy_passse usa.

sorin
fuente
Entonces, pasa la solicitud al proxy y esa respuesta del conjunto de proxy y en esta respuesta le gustaría agregar su encabezado personalizado antes de que se envíe al usuario, ¿es correcto?
emka86

Respuestas:

31

Hay un módulo llamado HttpHeadersMoreModule que le brinda más control sobre los encabezados. No viene con Nginx y requiere instalación adicional. Con él, puede hacer algo como esto:

location ... {
  more_set_headers "Server: my_server";
}

Eso "establecerá el encabezado de salida del servidor en el valor personalizado para cualquier código de estado y cualquier tipo de contenido". Reemplazará los encabezados que ya están configurados o los agregará si no están configurados.

Sebastián Goodman
fuente
¿Es posible agregar Securey HttpOnlybanderas en una cookie de respuesta ? Sin embargo, la cookie de respuesta de destino solo tiene la cookie namey los expireatributos.
JPaulPunzalan
2
No necesariamente necesita una biblioteca para poder cambiar o agregar encabezados de respuesta y, al contrario de la respuesta más votada, puede anular un encabezado, simplemente debe eliminarlo primero. Verifique mi respuesta a continuación para obtener más detalles.
March
162

add_headerfunciona tan bien con proxy_passcomo sin. Hoy realicé una configuración en la que he usado exactamente esa directiva. Sin embargo, tengo que admitir que también he tenido problemas para configurar esto sin recordar exactamente la razón.

Ahora mismo tengo una configuración que funciona y contiene lo siguiente (entre otros):

server {
    server_name  .myserver.com
    location / {
        proxy_pass  http://mybackend;
        add_header  X-Upstream  $upstream_addr;
    }
}

Antes, nginx 1.7.5 add_header funcionaba solo en respuestas exitosas, en contraste con HttpHeadersMoreModule mencionado por Sebastian Goodman en su respuesta .

Desde nginx 1.7.5, puede usar la palabra clave alwayspara incluir encabezados personalizados incluso en respuestas de error. Por ejemplo:

add_header X-Upstream $upstream_addr always;

Limitación: no puede anular el servervalor del encabezado utilizando add_header.

Oliver
fuente
41
Desde nginx 1.7.5, puede usar "siempre" para incluir encabezados personalizados en las respuestas de error usando add_header:add_header X-Upstream $upstream_addr always;
Shane
De todos modos, ¿tener una funcionalidad similar sin exponer la combinación de IP / puerto del servidor proxy? ej. X-Upstream: 10.10.10.10vs X-Upstream: 53c2d28edefdf501ab7c92e02a0c1687(md5 probablemente no sea útil para enmascarar la infraestructura, pero transmite la idea).
Zamnuts
@zamnuts: Pasar la IP ascendente y los números de puerto es solo un ejemplo del uso de la add_headerdirectiva. No tiene que enviarlos en absoluto.
Oliver
@Oliver, soy consciente de eso, pero estaba preguntando sobre un identificador ascendente alternativo individual / único que no sean los números de IP / puerto, o una ofuscación del mismo. Quizás mi pregunta está fuera de alcance y debería crear una nueva publicación :)
zamnuts
@zamnuts: Sugeriría hacer una nueva pregunta también :-)
Oliver
25

Como escribe Oliver:

add_headerfunciona tan bien con proxy_passcomo sin.

Sin embargo, como escribe Shane, a partir de Nginx 1.7.5, debe aprobar alwayspara obteneradd_header trabajar con respuestas de error, así:

add_header  X-Upstream  $upstream_addr always;
Dmitry Minkovsky
fuente
5
Pasé mucho tiempo preguntándome por qué no se mostraban mis encabezados, tratando de moverlos en el bloque del servidor, el bloque de ubicación, ... y aquí estaba la razón: nginx no los agrega en las respuestas de error: F Gracias
Shautieh
Yo también :) y a pesar de esta respuesta, esto me sucedió el otro día nuevamente. Tuve que revisar mi propia respuesta.
Dmitry Minkovsky
15

Ocultar el encabezado de respuesta y luego agregar un nuevo valor de encabezado personalizado

Agregar un encabezado con add_header funciona bien con el pase de proxy, pero si hay un valor de encabezado existente en la respuesta, apilará los valores.

Si desea establecer o reemplazar un valor de encabezado (por ejemplo, reemplazar el Access-Control-Allow-Originencabezado para que coincida con su cliente para permitir el uso compartido de recursos de origen cruzado), puede hacer lo siguiente:

# 1. hide the Access-Control-Allow-Origin from the server response
proxy_hide_header Access-Control-Allow-Origin;
# 2. add a new custom header that allows all * origins instead
add_header Access-Control-Allow-Origin *;

Entonces proxy_hide_header combinado con add_headerle da el poder de establecer / reemplazar valores de encabezado de respuesta.

Se puede encontrar una respuesta similar aquí en ServerFault

ACTUALIZAR:

Nota: proxy_set_header sirve para configurar los encabezados de la solicitud antes de que la solicitud se envíe más, no para configurar los encabezados de respuesta (estos atributos de configuración para los encabezados pueden ser un poco confusos).

Marchitar
fuente
Gracias, gran ayuda
Lancer.Yan
14

Puedes probar esta solución:

En su locationbloque cuando use proxy_passhaga algo como esto:

location ... {

  add_header yourHeaderName yourValue;
  proxy_pass xxxx://xxx_my_proxy_addr_xxx;

  # Now use this solution:
  proxy_ignore_headers yourHeaderName // but set by proxy

  # Or if above didn't work maybe this:
  proxy_hide_header yourHeaderName // but set by proxy

}

No estoy seguro de que sea exactamente lo que necesita, pero intente manipular este método y tal vez el resultado se ajuste a su problema.

También puedes usar esta combinación:

proxy_hide_header headerSetByProxy;
set $sent_http_header_set_by_proxy yourValue;
emka86
fuente
6
Tuve que usar este método ya que nginx estaba agregando un encabezado duplicado en lugar de sobrescribir el existente. location / { proxy_pass http://127.0.0.1:8080/; proxy_hide_header "Access-Control-Allow-Origin"; if ($http_origin ~* "^https://(example.com|www.example.com)$") { add_header Access-Control-Allow-Origin "$http_origin"; } }
ether6