对无法重定位到子目录的 URL 进行反向代理的解决方案

Tom*_*Tom 7 reverse-proxy apache-2.2

短篇小说
嘎!我希望开发管理界面的开发人员会公开一个“webroot=/myAppAppearsHere”选项,或者让所有链接都是相对的。

很长的故事

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

https://portal.mysite.com/login    
https://portal.mysite.com/
Run Code Online (Sandbox Code Playgroud)

然后一堆像这样的链接

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
Run Code Online (Sandbox Code Playgroud)

然而,有一些应用程序对反向代理到子目录真的不满意,例如 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/
Run Code Online (Sandbox Code Playgroud)

但不幸的是,我无法控制域的管理,获得这些添加是可能的,但很痛苦。(但我更喜欢一个不需要每个新链接都涉及某些 3rd 方的解决方案)(我知道通配符可以解决这个问题,但我有兴趣看看有哪些基于 HTTP 和 apache 的替代方案。 .. 用于学习等 ;-)

所以我转而使用类似于 mod_proxy_html的Apache2::ModProxyPerlHtml,并允许在文档中动态重新映射字符串。这实际上确实适用于 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>
Run Code Online (Sandbox Code Playgroud)

但它非常受欢迎,你不能只是通配符 URL 交换,因为有大量的 JSON 和 javascript 会被破坏。

我正在考虑跟踪当前代理后端的某种 cookie 或查询字符串 var,因此 apache 可以将请求动态重定向到正确的后端。

https://admin.mysite.com/?request-proxy=chef -> https://chefserver.localdomain:4040/
https://admin.mysite.com/?request-proxy=logstash  -> https://logstash.localdomain/
Run Code Online (Sandbox Code Playgroud)

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

我猜 cookie 几乎可以工作,因为您可以基于某些传递的 cookie 值进行代理,例如“request-proxy=logstash”,但是如果您在站点上打开了 2 个选项卡,这会出现问题,因为它们可能会覆盖每个选项卡其他饼干。

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

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

  1. ps我知道lemonldap,但我没有深入研究perl代码就没有走远。虽然它看起来很酷,但我将来会再看一次。
  2. 我开始怀疑在时间上我还不如花时间用 ModProxyPerlHtml 重新映射这些 HTML 页面,因为不会有一个适合所有情况的解决方案。

Tom*_*Tom 1

mod_substitute很好地完成了这项工作;

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

只需花费一些时间来完成映射规则。