我已经山穷水尽了,确实需要一些新的见解/建议。
问题:
在 Debian Etch 上运行 Apache 2.2.3 时,我的 Apache 服务器经常在针对我设置的 15 个虚拟主机中的任意一个的随机传入 HTTP 活动中向其自身(配置文件中的最后一个虚拟主机)发送请求。
我甚至将我的实时服务器镜像到本地虚拟盒并且得到了完全相同的行为。
(截断的)日志:
[30/Sep/2009:16:44:04 -0400] (Remote-host:) 127.0.0.1 (400) (Request:) "GET /"
[30/Sep/2009:16:44:05 -0400] (Remote-host:) 127.0.0.1 (400) (Request:) "GET /"
[30/Sep/2009:16:47:07 -0400] (Remote-host:) 127.0.0.1 (400) (Request:) "GET /"
[30/Sep/2009:16:47:12 -0400] (Remote-host:) 127.0.0.1 (400) (Request:) "GET /"
我知道这是最后一个接收奇怪请求的虚拟主机的原因是400-Bad request
上面的错误。原来我的最后一个虚拟主机启用了 SSL,而 Apache 正在向自己发送 / 的非 SSL 请求。
我的虚拟主机配置:
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerName one.example.com
</VirtualHost>
<VirtualHost *:80>
ServerName two.example.com
</VirtualHost>
<VirtualHost *:80>
ServerName three.example.com
</VirtualHost>
<VirtualHost *:443>
ServerName secure.example.com
</VirtualHost>
因此,当您发送 HTTP 请求到one.example.com,(有时)日志文件secure.example.com将如上所示。奇怪!我运行了mod_dumpio
和mod_log_forensic
,但没有从中获得太多见解。
到底是什么原因造成这种现象?
我知道的:
- 它是随机的,并且哪个虚拟主机接收 HTTP 请求并不重要。
- 当我注释掉最后一个 vhost 时,问题就消失了。
- 我的 Apache、PHP 和 MySQL 设置非常标准。
- 我只能在请求 PHP + 图像文件而不是 .txt、.xml、.html 等文件时重现奇怪的自我请求。
编辑(修复):
如果其他人遇到这种情况,以下是我为补救这种情况所采取的措施。
更改我的 Apache Listen 指令的顺序:
Listen 192.168.0.199:443
Listen 192.168.0.199:80
然后向我的第一个虚拟主机添加重写规则:
RewriteCond %{REMOTE_ADDR} ^(192\.168\.0\.199|127\.0\.0\.1)$
RewriteCond %{HTTP_USER_AGENT} internal\ dummy\ connection [NC]
RewriteRule .* /apache-internal-dummy-connection/ [R=302,L]
重写规则简单地说,“如果远程用户的 IP 地址与我的 Web 服务器相同,并且远程用户的代理(浏览器)包含‘内部虚拟连接’字样,则将任何请求重定向(302)到http://www.example.com/apache-internal-dummy-connection/“。
我选择重定向到一个不存在的 URI,以减轻服务器的负载。
在我的第一个 vhost 日志文件上使用tail -f
,并且它在两个服务器上都运行良好。
希望这对某人有帮助。
答案1
这些请求是 Apache 用来影响子进程状态的内部虚拟连接。它们是无害的,您看到精确行为的原因是由于某些怪癖。
内部进程无法使用 SSL,并且很容易被Listen
指令的顺序搞糊涂。如果Listen 443
在之后定义Listen 80
,它将尝试向发送非 SSL 请求http://本地主机:443/,这将命中您的默认 SSL 虚拟主机并失败,导致 HTTP 状态代码 400。
Listen
据我所知,唯一的解决方法是以相反的方向重新排序你的指令。
答案2
虽然我看到您的最后一个 vhost 块用于端口 443,但我没有看到它实际上已为 SSL 配置。首先,您必须启用“SSLEnable On”。也许这就是您看到“错误请求”错误的原因……?
答案3
请注意,您无法使用 NameVirtualHost SSL 连接!
答案4
实际上,您可以使用 NameVirtualHost + SSL,使用 SAN(主题备用名称)证书。