Como adicionar um cabeçalho de resposta no nginx ao usar proxy_pass?

90

Quero adicionar um cabeçalho personalizado para a resposta recebida do servidor por trás do nginx.

Embora add_headerfuncione para respostas processadas por nginx, ele não faz nada quando o proxy_passé usado.

Sorin
fonte
Então você passa a solicitação ao proxy e a resposta do conjunto de proxy e nessa resposta você gostaria de adicionar seu cabeçalho personalizado antes de ser enviado ao usuário, correto?
emka86

Respostas:

29

Existe um módulo chamado HttpHeadersMoreModule que oferece mais controle sobre os cabeçalhos. Ele não vem com o Nginx e requer instalação adicional. Com ele, você pode fazer algo assim:

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

Isso "definirá o cabeçalho de saída do servidor para o valor personalizado para qualquer código de status e qualquer tipo de conteúdo". Ele substituirá os cabeçalhos que já estão definidos ou os adicionará se não estiverem definidos.

Sebastian Goodman
fonte
é possível adicionar Securee HttpOnlysinalizar em um cookie de resposta ? O cookie de resposta de destino possui apenas o cookie namee os expireatributos.
JPaulPunzalan
2
Você não precisa necessariamente de uma biblioteca para poder alterar ou adicionar cabeçalhos de resposta e, ao contrário da resposta mais votada, você pode substituir um cabeçalho, basta removê-lo primeiro. Verifique minha resposta abaixo para obter detalhes.
Wilt
155

add_headerfunciona bem com proxy_passou sem. Acabei de definir uma configuração em que usei exatamente essa diretiva. Tenho que admitir, porém, que também me esforcei ao configurar isso sem lembrar exatamente o motivo.

No momento, tenho uma configuração de trabalho e ela contém o seguinte (entre outros):

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

Antes, o nginx 1.7.5 add_header trabalhava apenas em respostas bem-sucedidas, em contraste com o HttpHeadersMoreModule mencionado por Sebastian Goodman em sua resposta .

Desde nginx, 1.7.5você pode usar a palavra always- chave para incluir cabeçalhos personalizados mesmo em respostas de erro. Por exemplo:

add_header X-Upstream $upstream_addr always;

Limitação: Você não pode substituir o servervalor do cabeçalho usando add_header.

Oliver
fonte
40
Desde o nginx 1.7.5, você pode usar "sempre" para incluir cabeçalhos personalizados em respostas de erro usando add_header:add_header X-Upstream $upstream_addr always;
Shane
De qualquer forma, ter funcionalidade semelhante sem expor a combinação IP / porta do servidor proxy? por exemplo, X-Upstream: 10.10.10.10vs X-Upstream: 53c2d28edefdf501ab7c92e02a0c1687(md5 provavelmente não é útil para mascarar a infraestrutura, mas transmite a ideia).
zamnuts,
@zamnuts: Passar o IP upstream e os números das portas é apenas um exemplo do uso da add_headerdiretiva. Você não precisa enviá-los.
Oliver,
@Oliver, estou ciente disso, mas estava perguntando sobre um identificador upstream único / individual alternativo diferente dos números de IP / porta ou um ofuscamento disso. Talvez minha pergunta esteja fora do escopo e eu deva criar uma nova postagem :)
zamnuts 05/10/2015
@zamnuts: Eu sugiro fazer uma nova pergunta também :-)
Oliver
25

Como escreve oliver:

add_headerfunciona bem com proxy_passou sem.

No entanto, como Shane escreve, a partir do Nginx 1.7.5, você deve passar alwayspara obter add_headerrespostas de erro, assim:

add_header  X-Upstream  $upstream_addr always;
Dmitry Minkovsky
fonte
5
Passei muito tempo me perguntando por que meus cabeçalhos não estavam aparecendo, tentando movê-los no bloco de servidor, bloco de localização, ... e aqui estava o motivo: o nginx não os adiciona em respostas de erro: F Obrigado
Shautieh
Eu também :) e, apesar dessa resposta, isso aconteceu comigo outro dia novamente. Tive que revisar minha própria resposta.
Dmitry Minkovsky de
Consulte nginx.org/en/docs/http/ngx_http_headers_module.html#add_header para obter detalhes
Steve Eynon de
14

Você pode tentar esta solução:

Em seu locationbloco, quando você usa, proxy_passfaça algo assim:

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

}

Não tenho certeza se seria exatamente o que você precisa, mas tente alguma manipulação desse método e talvez o resultado se encaixe no seu problema.

Você também pode usar esta combinação:

proxy_hide_header headerSetByProxy;
set $sent_http_header_set_by_proxy yourValue;
emka86
fonte
6
Tive que usar esse método porque o nginx estava adicionando um cabeçalho duplicado em vez de substituir o 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 de
11

Oculte o cabeçalho de resposta e, em seguida, adicione um novo valor de cabeçalho personalizado

Adicionar um cabeçalho com add_headerfunciona bem com o passe de proxy, mas se houver um valor de cabeçalho existente na resposta, ele empilhará os valores.

Se você deseja definir ou substituir um valor de cabeçalho (por exemplo, substitua o Access-Control-Allow-Origincabeçalho para corresponder ao seu cliente para permitir o compartilhamento de recursos de origem cruzada), você pode fazer o seguinte:

# 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 *;

Assim, proxy_hide_headercombinado com add_headerlhe dá o poder de definir / substituir os valores do cabeçalho de resposta.

Uma resposta semelhante pode ser encontrada aqui em ServerFault

ATUALIZAR:

Nota: proxy_set_header é para definir cabeçalhos de solicitação antes que a solicitação seja enviada, não para definir cabeçalhos de resposta (esses atributos de configuração para cabeçalhos podem ser um pouco confusos).

Wilt
fonte
Obrigado, ótima ajuda
Lancer.Yan