nginx добавляет условный заголовок для переменной upstream_http_

19

У меня есть обратный прокси-сервер на Nginx, который прокси-сервер довольно много сайтов. Недавно я включил HTTP Strict Transport Security для всех сайтов с поддержкой SSL. Теперь у меня есть один сайт, который не хочет, чтобы это было включено.

Я подумал, что просто сделаю простую проверку, если мой апстрим уже отправил мне Strict-Transport-Securityзаголовок, а если нет, просто добавлю. Таким образом, мой апстрим мог послать заголовок STS, содержащий, max-age=0чтобы избежать включения HSTS прокси.

Я думал, что я просто изменил бы мою конфигурацию следующим образом:

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

Но, вероятно, потому что, если это зло , это не работает. Я пробовал кучу разных вещей, чтобы убедиться, что переменная действительно существует (что имеет место), но ничего не помогает.

Как я мог сделать эту работу?

Gerry
источник

Ответы:

22

Это не работает, потому что if вычисляется до того, как запрос передан бэкэнду, поэтому переменные $ upstream_http_ еще не имеют никаких значений. add_header с пустым значением игнорируется, поэтому вы можете использовать карту для условного добавления заголовка следующим образом:

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

server {
  location / {
    add_header Strict-Transport-Security $sts;
  }
}
kolbyjack
источник
1
Умное использование карты!
Алексей Тен
хорошо, я пытался сделать что-то немного другое, но я не мог понять nginx. Можете ли вы сказать мне, где я могу узнать nginx формально. А также вы можете помочь мне здесь: serverfault.com/questions/678521/…
Мухаммед Умер
5

Это потому, что ifвыполняется до того, как прокси будет иметь место, и в этот момент нет никакой переменной $upstream_http_strict_transport_security.

Вы можете использовать header_filter_by_luaдирективу из модуля Lua. Например

header_filter_by_lua 'if not ngx.header["X-Test"] then ngx.header["X-Test"] = "blah" end';
Алексей Тен
источник
1
Это работает. В Debian 7 вы можете получить поддержку LUA, используя Nginx из backports через apt-get -t wheezy-backports install nginx-extras.
Питер Эннес