nginx-proxy-manager icon indicating copy to clipboard operation
nginx-proxy-manager copied to clipboard

Cannot proxy to sites that require a correct Host header

Open bataras opened this issue 2 years ago • 11 comments

This line...

https://github.com/NginxProxyManager/nginx-proxy-manager/blame/develop/docker/rootfs/etc/nginx/conf.d/include/proxy.conf#L2

I believe should be...

proxy_set_header Host $proxy_host;

(I got the below to work by doing it)

Without that, proxy requests are being forwarded to websites with the original Host header and those sites are returning an error or a 404. For example, trying proxying data.example.com to an S3 bucket like mybucket.s3-website-us-east-1.amazonaws.com:80

S3 will reply with something like..

404 Not Found
Code: NoSuchBucket
Message: The specified bucket does not exist
BucketName: data.example.com
RequestId: J8K24Y80A04JNFY4
HostId: ksf8GNLOX46prb58795rY6bxvr81Lfm6xzKnWTJcXLEaomW69xYWmBJBvcWV4VMZJEZohq4CF4s=

Further, you cannot override this proxy_set_header command by adding it to the advanced custom config in the UI because it simply appends the value to the existing header. ie, S3 will reply as blow (note the BucketName)...

404 Not Found
Code: NoSuchBucket
Message: The specified bucket does not exist
BucketName: data.example.com mybucket.s3-website-us-east-1.amazonaws.com

Nor have I found a way to "unset" proxy_set_header Host. I tried using "Headers More" to no avail: https://www.nginx.com/resources/wiki/modules/headers_more/

bataras avatar Mar 13 '23 00:03 bataras

If I understand correctly, currently NPM passes the hostname from the original request through to the upstream server. In many use-cases (perhaps the majority) this is probably the desired behaviour.

Do you want the upstream server (S3 in your case) to see the value you entered in the UI for "Forward Hostname / IP"?

kabadisha avatar Mar 19 '23 21:03 kabadisha

I believe with reverese proxying, the target should not receive the original request's Host header. The target should receive a new Host header specific to the target (ie the s3 host example above) and it should additionally receive an X-Forwarded-For header indicating the original request's host header (actually XFF is a chain of forwarding headers beginning with the original request's Host header.

bataras avatar Mar 19 '23 22:03 bataras

You may just be right about that. I wonder if there is a public RFC which sets out the standard behaviour?

You could create a pull request for the change and see if the maintainers will accept it. You'd also need to check the same change is applied to custom location declarations too.

kabadisha avatar Mar 19 '23 23:03 kabadisha

I met the same problem, I needed to use $proxy_host because I aim to speed up visiting a website.

For example, I visit abc.com slowly, so I use my VPS and my domain abc.mydomain.com to proxy it. In this case, I should use $proxy_host instead of $host.

Solution: Edit Advanced - Custom Nginx Configuration like below.

location / {
  proxy_pass       $forward_scheme://$server:$port$request_uri;
#  The following line is the nginx default configuration, so there is no difference whether it is commented
#  proxy_set_header Host $proxy_host;
}

Further, you cannot override this proxy_set_header command by adding it to the advanced custom config in the UI because it simply appends the value to the existing header.

This is different from what I tested. The content in Advanced - Custom Nginx Configuration will replace config instead of appending

I highly recommend that developers add an option in the web page graphical configuration, proxy_set_header Host is followed by $host or $proxy_host. Give the users a choice.

qzydustin avatar Jul 05 '23 06:07 qzydustin

I'm having the same problem. In my case the proxied app redirects to $HOST/login.html, whereas it has to redirect to $HOST/location/login.html for login to work.

And you can indeed work around it by just pasting the custom nginx configuration, but thats kind of besides the point.

The nginx default for Host is $proxy_host (https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/), probably precisely for this reason:

By default, NGINX redefines two header fields in proxied requests, “Host” and “Connection”, and eliminates the header fields whose values are empty strings. “Host” is set to the $proxy_host variable, and “Connection” is set to close.

IMHO the default should be respected, in the unlikely case that you truly want to overide Host with $host then you can always set up the location and add a custom header.

vbraun avatar Aug 27 '23 15:08 vbraun

I deleted the line proxy_set_header Host $host; in /etc/nginx/conf.d/include/proxy.conf

weiyuDatawiza avatar Oct 07 '23 10:10 weiyuDatawiza

Issue is now considered stale. If you want to keep it open, please comment :+1:

github-actions[bot] avatar Apr 17 '24 01:04 github-actions[bot]

I conducted a test using the custom location feature and concluded that the header configuration within the custom location cannot override the default header configurations provided by nginxproxymanager, such as:

perl Copy code 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_set_header X-Real-IP $remote_addr; proxy_pass http://192.168.1.250:8080; Is there a method available to ensure that the headers in the custom configuration can override the default headers?

config: image

nginx proxy file: image

clhey avatar Apr 28 '24 09:04 clhey

Since this pr(#3729), I got the same problem, advanced_config should move to buttom?

Erzbir avatar Aug 20 '24 09:08 Erzbir

Issue is now considered stale. If you want to keep it open, please comment :+1:

github-actions[bot] avatar Mar 12 '25 02:03 github-actions[bot]

any update?

jayl1e avatar Jun 09 '25 08:06 jayl1e