I'm at the end of my rope and could really use some fresh insight/suggestions.
The problem:
While runing Apache 2.2.3 on Debian Etch, my Apache server frequently sends a request to ITSELF (to the LAST virtual host in the config file) on random incoming HTTP activity directed towards ANY of the 15 virtual hosts I have set up.
I even mirrored my live server to a local virtual box and I get the exact same behavior.
The (trunacated) logs:
[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 /"
The reason I know it's the last virtual host receiving the strange request is the 400-Bad request
error above. Turns out my last vhost is SSL enabled and Apache is sending itself a non-SSL request for /.
My vhost config:
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>
So when you send an HTTP request to one.example.com, (sometimes) the log file for secure.example.com will be as shown above. WEIRD! I ran mod_dumpio
and mod_log_forensic
, but didn't gain much insight from them.
What in the world could possibly be causing this?
What I know:
- It is random, and doesn't matter which vhost receives the HTTP request.
- When I comment out the last vhost, the problem disappears.
- My Apache, PHP and MySQL setups are very standard.
- I can only reproduce the strange self-request when requesting PHP + image files rather than .txt, .xml, .html, etc. files.
Edit (The Fix):
In case anyone else stumbles upon this, here is what I did to remedy the situation.
Change the order of my Apache Listen directives:
Listen 192.168.0.199:443
Listen 192.168.0.199:80
Then add a rewrite rule to my FIRST virtual host:
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]
The rewrite rule simply says, "if the remote users' IP address is the same as my web server AND the remote users' agent (browser) contains the words 'internal dummy connection', redirect (302) any request to http://www.example.com/apache-internal-dummy-connection/".
I chose to redirect to a non-existant URI to keep the load down on my server.
Used tail -f
on my first vhost log file and it's working fine on both servers.
Hope this helps someone.
The requests are internal dummy connections which Apache uses to affect the status of child processes. They are harmless and the reason the reason that you are seeing your precise behaviour is due to some quirkiness.
The internal process isn't capable of speaking SSL and gets easily confused by the order of your
Listen
directives. IfListen 443
is defined afterListen 80
then it will attempt to send a non-SSL request to http://localhost:443/, which will hit your default SSL vhost and fail, resulting in the HTTP status code 400.As far as I'm aware the only workaround is to re-order your
Listen
directives the other way round.While I see that your last vhost block is for port 443, I don't see that it's actually configured for SSL. You have to have "SSLEnable On" for starters. Maybe that's the reason you're seeing the "bad request" error...?
Please note that you can't NameVirtualHost an SSL connection!
http://httpd.apache.org/docs/2.2/vhosts/name-based.html
actually you can use NameVirtualHost + SSL, using SAN (subject-alternative-name) certs..