:arrow_up_small: added $resolved_proto map
Improve Protocol Forwarding Accuracy Using resolved_proto
This PR enhances the accuracy of protocol forwarding in Nginx Proxy Manager by introducing a resolved_proto map variable. The resolved_proto variable ensures that the X-Forwarded-Proto and X-Forwarded-Scheme headers consistently reflect the most authoritative protocol information, particularly in setups involving upstream proxies like Cloudflare or AWS.
Context
While learning Nginx, I encountered an issue where protocol mismatches occurred in setups using Cloudflare's proxy feature, leading to errors in applications like Laravel. Specifically, in my case, Laravel's Livewire file upload feature failed with unauthorized errors when the X-Forwarded-Proto header was incorrectly set to http instead of https.
After investigating further, I discovered that the proxy.conf file in Nginx Proxy Manager always sets X-Forwarded-Proto to $scheme, which can conflict with the upstream X-Forwarded-Proto header set by proxies such as Cloudflare. This issue is compounded because these lines are automatically included in the default location block, leaving no way to override them through the UI.
Changes in This PR
To address this issue:
A resolved_proto map is introduced:
map $http_x_forwarded_proto $resolved_proto {
default $scheme;
~.+ $http_x_forwarded_proto;
}
X-Forwarded-Proto and X-Forwarded-Scheme headers now use $resolved_proto instead of $scheme in proxy.conf and _location.conf.
Benefits
- Ensures that the
X-Forwarded-ProtoandX-Forwarded-Schemeheaders correctly reflect the protocol information from upstream sources. - Resolves compatibility issues with upstream proxies like Cloudflare and AWS, ensuring seamless integration with applications relying on accurate protocol headers.
Notes
This PR serves as a suggestion and might not cover every edge case, as I’m still learning Nginx. However, it addresses a common issue many users face, as documented in this discussion, and many more I saw in Laravel, Livewire or Filament issues while researching. any feedback is welcome to refine the implementation further.
This is a beautiful example of a well written PR comment :)
Thanks for looking into this - NPM was originally written with the concept that it would be the edge server and not behind another proxy.
CI is currently failing with:
16:42:43 nginx: [emerg] unknown "resolved_proto" variable
This is a beautiful example of a well written PR comment :)
Thank you very much :) I'm trying to make an easy to use deployment script for Laravel apps and found NPM a very useful tool in doing so, still have a lot to learn though, if you know any good resource, let me know
one thing i do not understand is how this setting can effect my nginx config in laravel container for example if i manually set
proxy_set_header X-Forwarded-Proto https; this value still gets overwritten by what is inside proxy host config, should not my config overwrite that? but its working the other way around.
See this file which has the default location /. That then includes this file which sets the header on that level.
In order to override this, you'll have to define the entire location / { block in the Advanced config tab:
location / {
add_header X-Served-By $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass $forward_scheme://$server:$port$request_uri;
}
and in doing so, the host won't use the default location / {. Also be aware that the default block includes access control config and other config statements that would need to be added if your host needed them.
@jc21 hello again.
your last comment did not fix my problem (also won't cover http cases), but my PR hopefully will cover all cases, when do you have time to merge this, as for why check fail i have no idea what is casing the issue, so don't know how to fix it.
right now i manually edit all my proxy conf files but reset or change will overwrite them ;(