mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2026-11-10 12:28:28 +00:00
Fix for changing the upstream Host from $host to $forward_host
($http_host) forwards the raw client Host header, including the port and any absolute-form URI mismatch, to every upstream and into the asset cache key
This commit is contained in:
1 parent
99678969b3
commit
fff2b0d097
3 files changed
+16
-6
No files matched your search
@@ -9,4 +9,5 @@ test/node_modules
|
|||||||
docker/dev/dnsrouter-config.json.tmp
|
docker/dev/dnsrouter-config.json.tmp
|
||||||
docker/dev/resolv.conf
|
docker/dev/resolv.conf
|
||||||
.claude
|
.claude
|
||||||
|
test/__pycache__
|
||||||
|
|
||||||
@@ -52,10 +52,16 @@ http {
|
|||||||
# Dynamically generated resolvers file
|
# Dynamically generated resolvers file
|
||||||
include /etc/nginx/conf.d/include/resolvers[.]conf;
|
include /etc/nginx/conf.d/include/resolvers[.]conf;
|
||||||
|
|
||||||
# Preserve the client authority, falling back when a request has no Host header.
|
# Forwarded Host: nginx's normalised $host (lowercased, taken from the request line for
|
||||||
map $http_host $forward_host {
|
# absolute-form requests) plus the client's port, so upstreams that compare Host with
|
||||||
default $http_host;
|
# Origin/Referer on non-standard ports keep working. The port is only carried over when
|
||||||
"" $host;
|
# the Host header names the same host nginx routed on; otherwise (no Host, absolute-form
|
||||||
|
# URI naming a different host) it falls back to bare $host. Using $host rather than the
|
||||||
|
# raw header keeps case variants and mismatched Host values out of upstream requests and
|
||||||
|
# the asset cache key.
|
||||||
|
map "$host|$http_host" $forward_host {
|
||||||
|
"~*^(?<fwd_name>[^|]+)\|\k<fwd_name>(?<fwd_port>:[0-9]+)$" "$host$fwd_port";
|
||||||
|
default $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Default upstream scheme
|
# Default upstream scheme
|
||||||
|
|||||||
@@ -178,7 +178,10 @@ def check_image(image):
|
|||||||
for authority in authorities:
|
for authority in authorities:
|
||||||
for prefix in ("/", "/custom/"):
|
for prefix in ("/", "/custom/"):
|
||||||
for method in ("GET", "POST"):
|
for method in ("GET", "POST"):
|
||||||
origin = f"{scheme}://{authority}"
|
# nginx forwards its normalised (lowercased) $host, as browsers send
|
||||||
|
# in Host and Origin anyway
|
||||||
|
forwarded = authority.lower()
|
||||||
|
origin = f"{scheme}://{forwarded}"
|
||||||
referer = origin + "/settings"
|
referer = origin + "/settings"
|
||||||
path = prefix + "apply?one=1&two=2"
|
path = prefix + "apply?one=1&two=2"
|
||||||
payload = "rule=example" if method == "POST" else None
|
payload = "rule=example" if method == "POST" else None
|
||||||
@@ -190,7 +193,7 @@ def check_image(image):
|
|||||||
raise AssertionError((authority, path, method, str(error))) from error
|
raise AssertionError((authority, path, method, str(error))) from error
|
||||||
assert status == 200 and headers.get("Content-Type") == "application/json", (
|
assert status == 200 and headers.get("Content-Type") == "application/json", (
|
||||||
authority, path, method, status, body)
|
authority, path, method, status, body)
|
||||||
assert json.loads(body) == {"host": authority, "origin": origin,
|
assert json.loads(body) == {"host": forwarded, "origin": origin,
|
||||||
"referer": referer, "method": method, "path": path,
|
"referer": referer, "method": method, "path": path,
|
||||||
"body": payload or ""}, body
|
"body": payload or ""}, body
|
||||||
checked += 1
|
checked += 1
|
||||||
|
|||||||
Reference in new issue
Block a user