Nginx – n nginx variable for the unresolved upstream server address

nginx

When using nginx as a reverse proxy to a group of servers in an upstream block, is there a variable that corresponds to the unresolved server name? For example, consider the following configuration:

http {
    upstream foo {
        server foo1.example.com:8080;
        server foo1.example.com:8081;
        server foo2.example.com:8080;
        server foo2.example.com:8081;
    }
    server {
        server_name foo.example.com;
        location / {
            proxy_pass http://foo;
        }
    }
}

Let foo.example.com, foo1.example.com, and foo2.example.com be defined names that resolve to 192.0.2.1, 192.0.2.2, and 192.0.2.3 respectively.

Suppose a request comes in for foo.example.com and nginx decides to choose foo2.example.com port 8080 as the upstream server and the request succeeds. Then, to my knowledge, these will be the values of some relevant variables:

  • $host = foo.example.com
  • $proxy_host = foo
  • $upstream_addr = 192.0.2.3:8080 (*)

However, none of these match the value given in the configuration for the upstream server. So, more specifically, my question is: which variable, if any, will have the value of foo2.example.com:8080 in this case?

To avoid the X-Y problem, these are the things I'm trying to accomplish:

  1. to log the upstream server by hostname rather than by IP address, since resolved IP address may be temporary or may not support 1:1 reverse lookup
  2. to map the upstream server to another piece of information that's more useful, also for logging purposes
  3. to configure hostname verification (e.g., via proxy_ssl_name) for upstream SSL when the servers don't share the same certificate (this might warrant a question of its own, but it's not the only use case)

(*) = The variable $upstream_addr does not seem to be available at all stages of the request, e.g. adding proxy_set_header Upstream-Addr $upstream_addr; to the location block seems to have no effect, implying the variable is empty

Best Answer

Proxies can be tricky. Nginx's proxy_set_header is what you want. Nginx Docs

proxy_set_header    Host            $host;

Look here for an example of a more detailed config for proxies