Apache 2.4 RequestHeader 使用 ProxyPass 进行反向代理

Apache 2.4 RequestHeader 使用 ProxyPass 进行反向代理

我使用的是 Ubuntu 14.04,有多个 Apache HTTP VirtualHosts 在端口 80 上监听。一个站点是用于在本地主机上监听应用程序的反向代理。Apache 已为该站点上的根位置配置了基本身份验证。

这是 Apache 配置:

<VirtualHost *:80>
        DocumentRoot /home/korisnik/site
        Alias /static /home/korisnik/site/static
        <Directory /home/korisnik/site/static>
          Require all granted
        </Directory>

        ProxyPass /static !
        ProxyPass / http://127.0.0.1:9002/
        ProxyPassReverse / http://127.0.0.1:9002/

        RequestHeader set X-Proxy-USER %{REMOTE_USER}e  #
        RequestHeader set X-Proxy-SECURE-USER %{REMOTE_USER}s
        RequestHeader set X-Foo "Bar"

        <Location />
          AuthType Basic
          AuthName "Authentication Required"
          AuthUserFile "/home/korisnik/htpasswd"
          Require valid-user
        </Location>
</VirtualHost>

我的目标是通过 ENV 变量将经过身份验证的用户的用户名传递给后端应用程序,这在一台启用了 Apache SSL 模块的服务器上有效,而在另一台服务器上,相同的配置将 HTTP_X_PROXY_REMOTE_USER ENV 变量设置为 null。服务器之间的唯一区别是启用了 SSL 模块。

文档 (http://httpd.apache.org/docs/current/mod/mod_headers.html) 说

RequestHeader set X-VARNAME %{VARNAME}e

应在非 SSL 站点上使用,而在运行 SSL 的站点上使用

RequestHeader set X-VARNAME %{VARNAME}s

下面是我用于转储标头的 php 脚本:

<?php
        print "REMOTE_USER: ".$_SERVER['REMOTE_USER']."\n";
        print "HTTP_X_PROXY_USER: ".$_SERVER['HTTP_X_PROXY_USER']."\n";
        print "HTTP_X_PROXY_SECURE_USER: ".$_SERVER['HTTP_X_PROXY_SECURE_USER']."\n";
        print "HTTP_X_FOO: ".$_SERVER['HTTP_X_FOO']."\n";
?>

我发现,当 SSL 被禁用时,这两个指令都不起作用。当 SSL 被启用时,第二个指令无需任何其他更改即可工作,例如在该网站上启用 SSL,或者在任何其他网站上启用 SSL。

启用 Apache2 mod_ssl 且请求通过 ProxyPass 的标头

REMOTE_USER: 
HTTP_X_PROXY_USER: (null)
HTTP_X_PROXY_SECURE_USER: korisnik
HTTP_X_FOO: Bar

启用 Apache2 mod_ssl 的标头,请求直接转到 php 文件,无需 ProxyPass

REMOTE_USER: korisnik
HTTP_X_PROXY_USER: (null)
HTTP_X_PROXY_SECURE_USER: korisnik
HTTP_X_FOO: Bar

禁用 Apache2 mod_ssl 且请求通过 ProxyPass 的标头

REMOTE_USER: 
HTTP_X_PROXY_USER: (null)
HTTP_X_PROXY_SECURE_USER: (null)
HTTP_X_FOO: Bar

标头已禁用 Apache2 mod_ssl,并且请求直接转到 php 文件,无需 ProxyPass

REMOTE_USER: korisnik
HTTP_X_PROXY_USER: (null)
HTTP_X_PROXY_SECURE_USER: (null)
HTTP_X_FOO: Bar

是我遗漏了什么,还是 Apache 在 SSL 模块被禁用时拒绝为 Proxy 指令后面的连接设置 REMOTE_USER RequestHeader?

答案1

问题似乎是"%{REMOTE_USER}e"在 URL 处理阶段(即评估 Header 指令)无法通过远程用户访问。根据 RewriteRule 文档:

For instance, to rewrite according to the REMOTE_USER variable from within the per-server context (httpd.conf file) you must use %{LA-U:REMOTE_USER} - this variable is set by the authorization phases, which come after the URL translation phase (during which mod_rewrite operates).

我推测由于类似的原因,header 指令也会失败。我不知道为什么它突然在 SSL via 下可用"%{REMOTE_USER}s",但我再次推测这是因为在通过 SSL 进行通信的早期阶段设置了远程用户。

不过,我确实有一个解决方案。您可以按照文档使用 RewriteRule 进行前瞻,以获取远程用户,然后相应地设置标头。

重写引擎开启
重写规则 ^ - [E=MY_REMOTE_USER:%{LA-U:REMOTE_USER}]
RequestHeader 设置 X-Proxy-USER %{MY_REMOTE_USER}e

相关内容