我使用的是 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