针对不适合重新定位到子目录的 URL 进行反向代理的解决方案

针对不适合重新定位到子目录的 URL 进行反向代理的解决方案

短篇故事
啊!我希望管理界面的开发人员能够公开一个“webroot=/myAppAppearsHere”选项,或者使所有链接都是相对的。

很长的故事

我为客户提供一个管理门户,它基本上是一个 apache mod_auth 登录,然后是一系列指向后端管理页面的链接,如下所示;

https://portal.mysite.com/login    
https://portal.mysite.com/

然后是一堆像这样的链接

https://portal.mysite.com/monitoring   -> https://nagios.localdomain/nagios
https://portal.mysite.com/munin     -> https://munin.localdomain/nagios
https://portal.mysite.com/bacukups     -> https://backups.localdomain/backups

然而,有几个应用程序确实不喜欢被反向代理到子目录,例如 chef-server-webui 和 logstash web 界面。

ProxyPassReverse 将重新映射标题,但所有内部绝对 URL 都需要更改,并且如果应用程序配置中没有此选项,则必须将其强制转换为 HTML 响应。

显而易见的策略是创建子域名或通配符子域名来映射到这些应用程序,如下所示;

https://chef.mysite.com/   -> https://chefserver.localdomain:4040/
https://logstash.mysite.com/   -> https://logstash.localdomain/
https://*.mysite.com/   -> https://($1).localdomain/

但不幸的是我无法控制域名的管理,获得这些附加功能虽然可能,但却很麻烦。(但我更喜欢一种不需要第三方参与每个新链接的解决方案)(我知道通配符可以解决这个问题,但我有兴趣看看有哪些基于 HTTP 和 apache 的替代方案...用于学习等 ;-)

因此我开始使用Apache2::ModProxyPerlHtml它类似于 mod_proxy_html,并允许在文档中动态重新映射字符串。这实际上与 LocationMatch 和 ProxyHTMLRewrite 的某种组合一起使用,我甚至可以让 javascript 运行良好。然而,每做一件事都是非常痛苦的,尤其是对于任何非 web 1.0 应用程序来说。

例如以下内容几乎修复了 logstash 使其在 /logstash 下正常工作;

<LocationMatch "^/logstash/">

    RequestHeader   unset   Accept-Encoding
    PerlSetVar ProxyHTMLVerbose "On"
    PerlInputFilterHandler Apache2::ModProxyPerlHtml
    PerlOutputFilterHandler Apache2::ModProxyPerlHtml
    SetHandler perl-script
    PerlAddVar ProxyHTMLRewrite "/style.css /logstash/style.css"
    PerlAddVar ProxyHTMLRewrite "/css/smoothness/jquery-ui-1.8.5.custom.css /logstash/css/smoothness/jquery-ui-1.8.5.custom.css"
    PerlAddVar ProxyHTMLRewrite "/js/jquery-1.6.1.min.js /logstash/js/jquery-1.6.1.min.js"
    PerlAddVar ProxyHTMLRewrite "action='/search' action='/logstash/search'"
    PerlAddVar ProxyHTMLRewrite "/js/jquery-ui-1.8.13.min.js /logstash/js/jquery-ui-1.8.13.min.js"
    PerlAddVar ProxyHTMLRewrite "/media/throbber.gif /logstash/media/throbber.gif"

    PerlAddVar ProxyHTMLRewrite "/api/search /logstash/api/search"
    PerlAddVar ProxyHTMLRewrite "/api/histogram /logstash/api/histogram"

</LocationMatch>

但是它极其不稳定,你不能只使用通配符来交换 URL,因为有大量的 JSON 和 javascript 会被破坏。

我正在考虑某种跟踪当前代理后端的 cookie 或查询字符串变量,以便 apache 可以动态地将请求重定向到正确的后端.. 像这样;

https://admin.mysite.com/?request-proxy=chef -> https://chefserver.localdomain:4040/
https://admin.mysite.com/?request-proxy=logstash  -> https://logstash.localdomain/

基本上,当 apache 最后一次查看所有服务器 HTTP 内容时,它可以使用附加查询变量 &request-proxy=logstash 动态标记 URL。但是,我认为这会遇到与 ModProxyPerlHtml/mod_proxy_html 解决方案相同的问题,即它永远不会在任何地方都起作用,尤其是在使用某些 javascript 与客户端查询参数进行混搭的应用程序中。

我猜想 cookie 几乎可以起作用,因为你可以根据一些传递的 cookie 值进行代理,比如“request-proxy=logstash”,然而如果你在网站上打开了 2 个标签,这就会遇到问题,因为它们可能会覆盖彼此的 cookie。

我知道有些应用程序只是采取某种暴力方法,将整个代理请求包装在重新烘焙的 html 中,例如Netscreen SA-3000

无论如何,是否有任何 Apache 模块可以实现这些策略,或者以某种方式绕过为每个代理站点编写匹配规则?

  1. 附言:我知道 lemonldap,但如果不深入研究 perl 代码,我也没能取得多大进展。不过它看起来很酷,以后我会再看看。
  2. 我开始怀疑,从时间上来说,我还不如花时间用 ModProxyPerlHtml 重新映射这些 HTML 页面,因为不会有一个适合所有情况的解决方案。

答案1

mod_substitute工作做得很好;

摘要:mod_substitute 提供了一种对响应主体执行正则表达式和固定字符串替换的机制。

只是需要花一点时间来完成映射规则。

相关内容