首页 > 解决方案 > 如何通过从路径中提取主机来将 Apache 配置为反向代理

问题描述

我想将 Apache 配置为反向代理,通过解析请求的 URL 的路径来动态确定要代理的 URL。

例如,URLhttp://proxy-server/app/your-app将被代理http://your-app:8000/http://proxy-server/app/your-app/some/path转到http://your-app:8000/some/path.

我在使用以下配置时遇到的问题是,它http://proxy-server/app/your-app/工作得很好,但http://proxy-server/app/your-app/some/path被重定向到http://proxy-server/some/path,这会产生 404 错误。

我试过mod_proxy像这样使用

ProxyPassMatch "^/app/([^/]+)(?:/(.*))?$" "http://$1:8000/$2"

我已经试过了mod_rewrite

RewriteEngine On
RewriteBase "/app/"
RewriteRule "^([^/]+)/?$" "http://$1:8000/" [E=CONTAINER:$1,P]
RewriteRule "^([^/]+)/(.+)$" "http://$1:8000/$2" [E=CONTAINER:$1,P]

ProxyPassInterpolateEnv On
ProxyPassReverse "/app/" "http://${CONTAINER}:8000/" interpolate

当我curl -D - http://proxy-server/app/your-app得到HTTP/1.1 200 OK回应时。当我curl -D - http://proxy-server/app/your-app/some/path得到HTTP/1.1 301 Move Permanently回复时Location: /some/path/

我不确定 301 是从哪里来的。Apache 和在该主机上运行的应用程序都不应该返回 301,但Location标题让我认为可能是反向代理没有设置为正确重写它所代理的远程的 URL,这就是为什么我添加了ProxyPassReverse上面的指令。但我仍然无法让它工作。

任何有关如何设置的见解将不胜感激。

标签: apachereverse-proxy

解决方案


我确实ProxyPassReverse为这种情况配置了错误的指令。

我代理的远程服务器(一个 Django 应用程序)通过将Location标头设置为路径而不是完整的 URL 来发出重定向。所以我不得不像这样配置Apache:

RewriteEngine On
RewriteRule "^/app/([^/]+)(?:/.*)?$" - [E=CONTAINER:$1]

ProxyPassInterpolateEnv On
ProxyPass "/app/${CONTAINER}/" "http://${CONTAINER}:8000/" interpolate
ProxyPassReverse "/app/${CONTAINER}/" "http://${CONTAINER}:8000/" interpolate

# This guarantees that any Location headers that are just absolute paths
# get rewritten
ProxyPassReverse "/app/${CONTAINER}/" "/" interpolate

最后一行是关键。它告诉 Apache 如果它得到一个Location: /some/path/头文件,它应该将它重写为Location: /app/your-app/some/path/. 只有当ProxyPassReverseApache 收到Location: http://${CONTAINER}:8000/some/path/.


推荐阅读