Apache 反向代理将浏览器直接发送到后端
Apache Reverse Proxy Sending Browser to Backend Directly Instead
(UPDATE 在底部的主要问题,下面可能是多余的细节)
我遇到了一个有趣的问题,Apache 没有按预期反向代理。
基本上,当我在我的网站上点击一个 link 并转到相对路径 /app1
时,我希望 URL 是 external.company.ca/app1
内容来自 internal.company.ca/some_app
。相反,浏览器将直接转到 internal.company.ca/some_app
。
没有 302 或任何东西,就在那里。这对我来说很奇怪,因为除了反向代理配置之外,配置中的任何地方都没有提到 internal.company.ca
,所以我根本不知道浏览器是如何学习域的。
这是从客户端(浏览器)角度截取的 Fiddler 截图,显示了我点击 link 后的行为,该 link 转到 /app1
(你必须相信我绿色名称为 external.company.ca
,黑色名称为 internal.company.com
,路径为 /some_app/blahblah
):
此后发生的一切都是用 internal.company.com
加载页面。当然,这在生产中根本行不通。
以下是我们的 Apache 配置文件的(截断的)版本以供考虑:
<VirtualHost *:80>
# rewrite rules to 443
</VirtualHost>
<VirtualHost *:443>
ServerName external.company.ca
ServerAlias external.company.com
# Logging rules.........
SSLEngine on
SSLProxyEngine on
SSLProxyVerify none
# Most of this is off for testing purposes, adding in case it matters
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
# more SSL stuff.... Now on to the interesting part
ProxyPreserveHost On
ProxyPass /app1 https://internal.company.com/some_app
ProxyPassReverse /app1 https://internal.company.com/some_app
</VirtualHost>
有一次,我认为 cookie 可能会丢东西,因为它们位于不同的域(前面是 .ca,后面是 .com),但我相信如果反向代理工作正常,浏览器会 none 更聪明。有人看出以上有什么问题吗?
更新
我找到了罪魁祸首:
<script type="text/javascript">window.location.assign('https://internal.company.com/app1/login?redirectUrl=' + encodeURIComponent(window.location.pathname + window.location.hash));</script>
问题是,如何使用 Apache 重写这个绝对 URL?我知道 mod_proxy_html 修改元素属性(例如 a
元素中的 href
)但是它可以重写元素本身中的任意数据吗?
内部应用程序由供应商提供,虽然可以对其进行修改以删除上述代码,但我现在宁愿远离该路径,看看是否有其他选择。
我想出了一个有点讨厌的解决方法:
ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLLinks script src
ProxyHTMLURLMap https://internal.company.com
问题是在整个 HTML(和 javascript)中使用来自供应商应用程序的绝对 URL。搜索并删除域可以解决问题(但速度非常慢)。
如果以后有人遇到这个问题,我不建议使用这个解决方案。我猜你来这里是因为你不能修改内部应用程序。相反,您应该向维护代码的任何人发送一张票,以使他们的应用程序对反向代理更加友好。
一个可能更安全的解决方案是使用 mod_substitute. You could also consider ProxyHTMLExtended,但它的替换可能相当残酷,偶尔会破坏 JavaScript。
编辑:刚注意到您目前正在使用 ProxyHTMLExtended。我的错。正如您所强调的那样,这是一个非常残酷和危险的问题解决方案。
(UPDATE 在底部的主要问题,下面可能是多余的细节)
我遇到了一个有趣的问题,Apache 没有按预期反向代理。
基本上,当我在我的网站上点击一个 link 并转到相对路径 /app1
时,我希望 URL 是 external.company.ca/app1
内容来自 internal.company.ca/some_app
。相反,浏览器将直接转到 internal.company.ca/some_app
。
没有 302 或任何东西,就在那里。这对我来说很奇怪,因为除了反向代理配置之外,配置中的任何地方都没有提到 internal.company.ca
,所以我根本不知道浏览器是如何学习域的。
这是从客户端(浏览器)角度截取的 Fiddler 截图,显示了我点击 link 后的行为,该 link 转到 /app1
(你必须相信我绿色名称为 external.company.ca
,黑色名称为 internal.company.com
,路径为 /some_app/blahblah
):
此后发生的一切都是用 internal.company.com
加载页面。当然,这在生产中根本行不通。
以下是我们的 Apache 配置文件的(截断的)版本以供考虑:
<VirtualHost *:80>
# rewrite rules to 443
</VirtualHost>
<VirtualHost *:443>
ServerName external.company.ca
ServerAlias external.company.com
# Logging rules.........
SSLEngine on
SSLProxyEngine on
SSLProxyVerify none
# Most of this is off for testing purposes, adding in case it matters
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
# more SSL stuff.... Now on to the interesting part
ProxyPreserveHost On
ProxyPass /app1 https://internal.company.com/some_app
ProxyPassReverse /app1 https://internal.company.com/some_app
</VirtualHost>
有一次,我认为 cookie 可能会丢东西,因为它们位于不同的域(前面是 .ca,后面是 .com),但我相信如果反向代理工作正常,浏览器会 none 更聪明。有人看出以上有什么问题吗?
更新
我找到了罪魁祸首:
<script type="text/javascript">window.location.assign('https://internal.company.com/app1/login?redirectUrl=' + encodeURIComponent(window.location.pathname + window.location.hash));</script>
问题是,如何使用 Apache 重写这个绝对 URL?我知道 mod_proxy_html 修改元素属性(例如 a
元素中的 href
)但是它可以重写元素本身中的任意数据吗?
内部应用程序由供应商提供,虽然可以对其进行修改以删除上述代码,但我现在宁愿远离该路径,看看是否有其他选择。
我想出了一个有点讨厌的解决方法:
ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLLinks script src
ProxyHTMLURLMap https://internal.company.com
问题是在整个 HTML(和 javascript)中使用来自供应商应用程序的绝对 URL。搜索并删除域可以解决问题(但速度非常慢)。
如果以后有人遇到这个问题,我不建议使用这个解决方案。我猜你来这里是因为你不能修改内部应用程序。相反,您应该向维护代码的任何人发送一张票,以使他们的应用程序对反向代理更加友好。
一个可能更安全的解决方案是使用 mod_substitute. You could also consider ProxyHTMLExtended,但它的替换可能相当残酷,偶尔会破坏 JavaScript。
编辑:刚注意到您目前正在使用 ProxyHTMLExtended。我的错。正如您所强调的那样,这是一个非常残酷和危险的问题解决方案。