Below is the bare-bones stripped down Nginx config that demonstrates the problem I'm having directly. The "real-world" setup has multiple upstreams and multiple conditional checks that are omitted for clarity.
upstream barhost {
server example.com;
}
server {
listen 8080;
location / {
# this works fine if used directly:
# proxy_pass http://example.com/;
# this doesn't work, returns 404:
proxy_pass http://barhost/;
}
}
Results:
- Using
proxy_pass http://example.com/;
works perfectly fine, returns 200 - Using
proxy_pass http://barhost/;
(usingupstream
) it returns 404
Some background info:
- The whole point of this dynamic upstream is to act as an alternative workaround for this bountied and unsolved issue.
- I cannot use
if()
to accomplish this particular goal, as explained in a response to that related question, which is why I am going down this route (The idea is to use amap
to decide on anupstream
) - It appears I cannot use
map
with the hostnames in it because Nginx will not resolve DNS if in amap
, that's why I'm usingupstream
. I'm essentially trying to mimic this config.
What am I doing wrong here?
Somewhat related posts:
- nginx proxy_pass with dynamic upstream servers
- nginx dynamic proxy_pass with variable between redirections
- https://stackoverflow.com/questions/50121492/using-nginx-map-directive-to-dynamically-set-proxy-upstream
UPDATE:
Thanks to a helpful user in the comments, I've investigated the request header that is proxied to example.com in this scenario. It's being set to barhost
which the server will give an invalid response to. This is the root cause of the issue.
So, with that known, I would like to set the Host
header properly.
Setting the upstream name to match the desired Host
header name does work:
upstream example.com {
server example.com:80;
}
Hard coding Host
header with proxy_set_header
also seems to work:
upstream barhost {
server example.com;
}
server {
listen 8080;
location / {
# This works:
proxy_set_header Host example.com;
# None of these work:
# proxy_set_header Host $host;
# proxy_set_header Host $http_upstream_host;
# proxy_set_header Host $proxy_host;
proxy_pass http://barhost/;
}
}
However, in my particular use-case it would ideal to instead set it dynamically using proxy_set_header
using a variable - is that possible?