我正在尝试将 Apache 设置为反向代理。以下是其配置的基本部分:
NameVirtualHost 10.16.10.245:9443
Listen 10.16.10.245:9443
<VirtualHost 10.16.10.245:9443>
ServerName proxy.lan:9443
SSLEngine on
...
TraceEnable off
SSLProxyEngine on
ProxyPreserveHost On
ProxyRequests Off
ProxyVia full
ProxyPass / http://localhost/
ProxyPassReverse / http://localhost/
</VirtualHost>
请注意,代理正在监听非标准端口 9443。当我使用显示 phpinfo 的虚拟页面作为后端时,一切都按预期运行。但是,我需要放在代理后面的站点要么太严格,要么写得太差,因此行为会发生变化,如下所示:
client -> https://proxy.lan:443 -> http://localhost = success
client -> https://proxy.lan:<ANY_OTHER_PORT> -> http://localhost = wrong redirect
客户端从https://proxy.lan:9443/到https://proxy.lan/auth/login显然代理无法满足请求,因为它没有监听端口 443:
# wget --no-check-certificate -vS https://proxy.lan:9443
--2019-05-12 02:51:37-- https://proxy.lan:9443/
Resolving proxy.lan (proxy.lan)... 10.10.254.186
Connecting to proxy.lan (proxy.lan)|10.10.254.186|:9443... connected.
WARNING: cannot verify proxy.lan's certificate, issued by '...':
Self-signed certificate encountered.
WARNING: certificate common name 'backend.lan' doesn't match requested host name 'proxy.lan'.
HTTP request sent, awaiting response...
HTTP/1.1 302 Found
Date: Sat, 11 May 2019 23:51:37 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Location: https://proxy.lan/auth/login
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'
X-Permitted-Cross-Domain-Policies: none
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Set-Cookie: PHPSESSID=...; path=/; secure; HttpOnly
Via: 1.1 proxy.lan:9443 (Apache/2.2.31)
Connection: close
Location: https://proxy.lan/auth/login [following]
--2019-05-12 02:51:37-- https://proxy.lan/auth/login
Connecting to proxy.lan (proxy.lan)|10.10.254.186|:443... failed: Connection refused.
Resolving proxy.lan (proxy.lan)... 10.10.254.186
Connecting to proxy.lan (proxy.lan)|10.10.254.186|:443... failed: Connection refused.
我可以手动将端口添加到生成的 URL 中,然后https://proxy.lan:9443/auth/login除了页面上指向的所有链接外,其他均有效https://proxy.lan/...
Apache 环境如下所示:
HTTP_HOST proxy.lan:9443
HTTP_VIA 1.1 proxy.lan:9443 (Apache/2.2.31)
HTTP_X_FORWARDED_FOR 10.100.0.30
HTTP_X_FORWARDED_HOST proxy.lan:9443
HTTP_X_FORWARDED_SERVER proxy.lan
HTTP_CONNECTION Keep-Alive
SERVER_SIGNATURE <address>Apache Server at proxy.lan Port 9443</address>
SERVER_NAME proxy.lan
SERVER_ADDR ::1
SERVER_PORT 9443
REMOTE_ADDR ::1
...
有什么想法可以在代理端做什么吗?也许是一些重写规则?
答案1
是ProxyPreserveHost on
造成这种情况的原因。如果您不确定是否需要它,请始终将其保留为默认值off
,这样就没问题了。
对于您确实需要的极少数情况ProxyPreserveHost on
,请 ProxyPassReverse
明智地调整 - 这是处理重定向的唯一指令。
ProxyPassReverse / http://localhost/
在你的场景中看起来是错误的,因为你的后端(80 个应用程序)似乎没有说“我将你重定向到http://localhost/foo/bar“任何地方。如果你把它放在ProxyPassReverse / https://proxy.lan/
那里,它可能会更好地工作 - 请查看官方文档。