nginx-proxy-manager
nginx-proxy-manager copied to clipboard
Allow forward with the Host header equaling the target server
It appears that the contents of /etc/nginx/conf.d/include/proxy.conf are incorrect and result in the wrong host header being set in proxied requests. The file currently contains:
add_header X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass $forward_scheme://$server:$port;
It should probably contain:
add_header X-Served-By $server;
proxy_set_header Host $server;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass $forward_scheme://$server:$port;
The problem is in the first two lines where the variable being used $host which resolves to the SOURCE URL for the proxy rather than the destination which is incorrectly setting the Host header of the proxied request rather than the destination (in $server).
I disagree. The Host header should normally be the same domain that you'll see in your browser, no matter how many proxies it passes through. If you require the Host to be different because your upstream server is expecting something different, that is outside of the norm and you can choose to override the default behaviour with the advanced configuration in the UI.
The Host header that is sent to the destination site needs to match the destination domain. If it does not and the destination site is using a shared IP then the request will fail or you may receive a default/unexpected page. The purpose of the Host header in to indicate to the remote server which website you are trying to access and is critical if an IP address is being shared with multiple sites. Go ahead and try it for yourself. One of the several pages I tested with was "http://neverssl.com". If you try to proxy that without making the indicated it won't work correctly.
I should clarify that when I say "destination site", "destination domain" and "remote" I am referring to the site being proxied ("Forward Hostname" in the UI). The way proxy.conf is currently configured you are passing the domain being assigned as the proxy host (the value in "Domain Names" in the UI) as the Host header which is incorrect.
I think you're missing the point of this project. It's not to proxy to other peoples public domains.
The host header being sent to upstream services listed here tells those services to use that host in various ways including but not limited to links being sent in emails.
But like I've said, you can change the configuration to match your circumstance.
In my case I'm not trying to proxy an external site, I just suggested that as an example to illustrate my point. Basically as long as the source and destination hostnames of the proxy match then it works fine the way it is BUT if your internal site is configured with a different hostname then it will not work. If I create an Apache site as "www.mydomain.local" and want to expose it publicly as "www.myexternaldomain.com" that won't work. The way it is working now forces the "internal" and "external" names to be the same where what I am suggesting works fine whether they match or not (including links; as long as they don't include the full URL). Having read your last comment I understand that forcing the names to match is the way you intend it to work but I believe this approach is more flexible and does not affect the current functionality.
@jc21
There is a lot of use cases that needs to change the domain name. I do not know what are you talking about! This is so common that every CDN in the market has this feature.
Also adding proxy_set_header Host ... will not work since another one exists in the default configuration and cannot be removed.
This should really be implemented.. Just a simple toggle in the UI called "Override hostname" would be enough..
People really need it, just a toggle to make it target server or override field. In my case, I've spent several hours to understand why my proxy returns 404 instead of site that is working everywhere. The problem was, I was trying to proxy k8s nginx-ingress resource, and ingress does it's dispatch based on host header. So initial target was discarded and ProxyManager placed current browser url to the host, which does absolutely no sense to k8s nginx ingress, so it returned 404. Thanks I've managed to fix it in advanced overrides, but that was not straightforward at all...
Adding another proxy_set_header Host into Custom locations doesn't help because it produces 2 Host headers as result.
@12ozCode would you mind sharing how you were able to set the Host header to the target server? It seems like I just need to delete the line "proxy_set_header Host $host;" from "/etc/nginx/conf.d/include/proxy.conf" (since by default Nginx puts the target server in the Host header) but I don't know how to do that.
For now, I just manually edited 1.conf to remove the line "include conf.d/include/proxy.conf;" and add "proxy_pass [target domain]." But I'm afraid NPM is going to overwrite 1.conf at some point (maybe at cert renewal?). Thanks!
Wow I wasted a lot of time to find this. There should be a way to override it.
Hello,
I suppose after all these years this is still not addressed?
@m33ts4k0z Yes, the people here seem to be really arrogant.
I start to use caddy to replace NPM because of this stupid problem.
@12ozCode would you mind sharing how you were able to set the Host header to the target server? It seems like I just need to delete the line "proxy_set_header Host $host;" from "/etc/nginx/conf.d/include/proxy.conf" (since by default Nginx puts the target server in the Host header) but I don't know how to do that.
For now, I just manually edited 1.conf to remove the line "include conf.d/include/proxy.conf;" and add "proxy_pass [target domain]." But I'm afraid NPM is going to overwrite 1.conf at some point (maybe at cert renewal?). Thanks!
Here is my way:
1, edit the /app/templates/_location.conf,change
proxy_set_header Host $host;
to
proxy_set_header Host $myhost;
2, Set $myhost variable when you add Proxy Host on popover form.
set $myhost "www.example.com";
on Advanced -> Custom Nginx Configuration.
This worked for me with version 2.9.17. Under Advanced -> Custom Nginx Configuration you specify the whole "location"-block. https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2076#issuecomment-1553988175
This worked for me with version 2.9.17. Under Advanced -> Custom Nginx Configuration you specify the whole "location"-chunk. #2076 (comment)
Get your mean, just write the whole location block in "Under Advanced -> Custom Nginx Configuration" right?
This worked for me with version 2.9.17. Under Advanced -> Custom Nginx Configuration you specify the whole "location"-chunk. #2076 (comment)
Get your mean, just write the whole location block in "Under Advanced -> Custom Nginx Configuration" right? Correct!
Issue is now considered stale. If you want to keep it open, please comment :+1: