9

I am trying to set up a bunch of virtual hosts on Nginx and I want to set some headers before passing the request upstream. I have some headers that I always want to set and then I have some headers that I want to set for selected location blocks.

Unfortunately, it seems that Nginx does not allow the proxy_set_header directive on multiple levels and as a result, it just clears any headers set in the http block.

Nginx documentation states the following on proxy_set_header:

Allows redefining or appending fields to the request header passed to the proxied server. The value can contain text, variables, and their combinations. These directives are inherited from the previous level if and only if there are no proxy_set_header directives defined on the current level.

So the question is... either Nginx has a disappointing limitation or I am thinking about this problem in the wrong way.

Any ideas on an idiomatic solution to this problem?

2 Answers 2

2

Create a file to include in each block that sets the headers you want. (So a common inc-http-headers.conf) that you include in the http block and all of the location blocks that need the common headers.

0
0

If you are using OpenResty or at least its headers-more-nginx-module, you can do this with the more_set_input_headers directive.

For example, the following will do what you expect:

http {
    # ...
    more_set_input_headers "Foo: 1";
    server {
        # ...
        more_set_input_headers "Bar: 2";
        location / {
            more_set_input_headers "Qux: 3";
            proxy_pass http://some-server;
            # request to some-server has Foo: 1, Bar: 2, and Qux: 3
        }
    }
}

There are some quirks to this approach however. You cannot alter the Connection or Host headers this way and you may need to be careful when nginx's own caching is enabled and you're modifying cache-related headers. If you aren't concerned with cache-related headers, then the biggest places these limitations crop up are: 1) getting WebSockets to work and 2) with upstreams that use the Host header in a nontrivial way.

Consequentially, a good rule of thumb I've found is to use proxy_set_header for Connection and Host and more_set_input_headers for everything else.

4
  • I don't think Host is listed on the limitations of github.com/openresty/headers-more-nginx-module#limitations Aug 29, 2022 at 21:32
  • @ArianFaurtosh It's not listed, but it probably should be. It doesn't seem to be possible to override the Host header for a proxied request using more_set_input_headers at all. I've tried setting it to $host, $http_host, and dummy and it always looks instead like the value of $proxy_host on the receiving end. I think this is because nginx always sets Host and Connection and does so after the headers_more module hook runs.
    – kbolino
    Aug 29, 2022 at 23:22
  • I found a related GitHub issue regarding the Host header at github.com/openresty/headers-more-nginx-module/issues/129
    – kbolino
    Aug 29, 2022 at 23:44
  • Thanks for sending the link, ya actually I'm running into the same issues with the host as well. Aug 30, 2022 at 19:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .