Apache2 server requesting ITSELF on random HTTP activity

apache-2.2

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.

Best Answer

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. If Listen 443 is defined after Listen 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.