nginx adiciona cabeçalho condicional a uma variável upstream_http_

19

Eu tenho um proxy reverso no nginx que proxies alguns sites. Recentemente, habilitei a HTTP Strict Transport Security para todos os sites habilitados para SSL. Agora tenho um site que não deseja que isso esteja ativado.

Eu pensei em fazer uma verificação simples se o meu upstream já me enviou um Strict-Transport-Securitycabeçalho e, se não, basta adicionar uma. Dessa forma, meu upstream poderia enviar um cabeçalho STS contendo max-age=0para evitar que o HSTS fosse ativado pelo proxy.

Eu pensei em mudar minha configuração da seguinte maneira:

location / {
        proxy_pass http://webservers;

        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto "https";

        if ($upstream_http_strict_transport_security = "") {
                add_header Strict-Transport-Security "max-age=15552000";
        }
}

Mas, provavelmente porque se é mau , isso não funciona. Eu tentei várias coisas diferentes para garantir que a variável realmente exista (qual é o caso), mas nada parece ajudar.

Como eu poderia fazer isso funcionar?

Gerry
fonte

Respostas:

22

Isso não funciona porque o if é avaliado antes que a solicitação seja passada para o back-end; portanto, as variáveis ​​$ upstream_http_ ainda não possuem valores. add_header com um valor vazio é ignorado; portanto, você pode usar um mapa para adicionar condicionalmente o cabeçalho da seguinte maneira:

map $upstream_http_strict_transport_security $sts {
  '' max-age=15552000;
}

server {
  location / {
    add_header Strict-Transport-Security $sts;
  }
}
kolbyjack
fonte
1
Uso inteligente do mapa!
Alexey Dez
ok, eu tenho tentado fazer algo um pouco diferente, mas não consegui descobrir o nginx. Você pode me dizer onde posso aprender o nginx formalmente. E também pode me ajudar aqui: serverfault.com/questions/678521/…
Muhammad Umer
5

Isso ifocorre porque é executado antes do proxy ocorrer e, neste momento, não há variável $upstream_http_strict_transport_security.

Você pode usar a header_filter_by_luadiretiva do módulo Lua. Por exemplo

header_filter_by_lua 'if not ngx.header["X-Test"] then ngx.header["X-Test"] = "blah" end';
Alexey Ten
fonte
1
Isso funciona. No Debian 7, você pode obter suporte à LUA usando o Nginx via backports via apt-get -t wheezy-backports install nginx-extras.
Pieter Ennes