nginx ajouter un en-tête conditionnel à une variable upstream_http_

19

J'ai un proxy inverse sur nginx qui proxie pas mal de sites. J'ai récemment activé HTTP Strict Transport Security pour tous les sites Web compatibles SSL. J'ai maintenant un site qui ne veut pas que cela soit activé.

Je pensais que je ferais simplement une simple vérification si mon amont m'a déjà envoyé un en- Strict-Transport-Securitytête, et sinon, j'en ajouterais un. De cette façon, mon amont pourrait envoyer un en-tête STS contenant max-age=0pour éviter d'avoir HSTS activé par le proxy.

Je pensais que je changerais simplement ma configuration comme suit:

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";
        }
}

Mais, probablement parce que si c'est mal , cela ne fonctionne pas. J'ai essayé un tas de choses différentes pour m'assurer que la variable existe réellement (ce qui est le cas), mais rien ne semble aider.

Comment pourrais-je faire fonctionner cela?

Gerry
la source

Réponses:

22

Cela ne fonctionne pas car le if est évalué avant que la requête ne soit transmise au backend, donc les variables $ upstream_http_ n'ont pas encore de valeurs. add_header avec une valeur vide est ignoré, vous pouvez donc utiliser une carte pour ajouter conditionnellement l'en-tête comme suit:

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

server {
  location / {
    add_header Strict-Transport-Security $sts;
  }
}
kolbyjack
la source
1
Utilisation intelligente de la carte!
Alexey Ten
ok j'ai essayé de faire quelque chose de peu différent mais je n'ai pas pu comprendre nginx. Pouvez-vous me dire où puis-je apprendre formellement nginx. Et pouvez-vous aussi m'aider ici: serverfault.com/questions/678521/…
Muhammad Umer
5

C'est parce que ifest exécuté avant que le proxy ait lieu et à ce moment il n'y a pas de variable $upstream_http_strict_transport_security.

Vous pouvez utiliser la header_filter_by_luadirective du module Lua. Par exemple

header_filter_by_lua 'if not ngx.header["X-Test"] then ngx.header["X-Test"] = "blah" end';
Alexey Ten
la source
1
Cela marche. Sur Debian 7, vous pouvez obtenir le support LUA en utilisant Nginx depuis les rétroportages via apt-get -t wheezy-backports install nginx-extras.
Pieter Ennes