Debian – How to debug Apache2 virtual hosts

apache-2.4debian

I'm hosting two websites in one server. Each has their own VirtualHost defined. First site works nicely but when I try to access the second I get redirected to the first one. It's like Apache would not recognize the correct VirtualHost by the ServerName and redirects me to the default (first) site.

Is there a log or something where I can see what steps Apache is taking when it handles my request? Does it log anywhere what ServerName it is using when it tries to find a matching VirtualHost?

Update:

I added a VirtualHost section for a subdomain of my second site and that works. It renders page from the correct application server that runs in 8501 port when I enter "interface.domain.com" into my browser. But when I try "www.domain.com" it redirects to my first site.

Below is my virtual host file for the second site.

<VirtualHost *:80>
  ServerName www.domain.com
  DocumentRoot /home/domain/current/public

  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ http://localhost:8501/$1 [P]
</VirtualHost>

<VirtualHost *:80>
  ServerName interface.domain.com
  DocumentRoot /home/domain/current/public

  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ http://localhost:8501/$1 [P]
</VirtualHost>

apache2ctl -S

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 1.2.3.4. Set the 'ServerName' directive globally to suppress this message
VirtualHost configuration:
1.2.3.4:443        www.domainfirst.com (/etc/apache2/sites-enabled/https_www_domainfirst_com.conf:1)
1.2.3.4:80         is a NameVirtualHost
         default server domainfirst.com (/etc/apache2/sites-enabled/domainfirst_com.conf:1)
         port 80 namevhost domainfirst.com (/etc/apache2/sites-enabled/domainfirst_com.conf:1)
         port 80 namevhost www.domainfirst.com (/etc/apache2/sites-enabled/www_domainfirst_com.conf:1)
*:80                   is a NameVirtualHost
         default server domain.com (/etc/apache2/sites-enabled/domain_com.conf:1)
         port 80 namevhost domain.com (/etc/apache2/sites-enabled/domain_com.conf:1)
         port 80 namevhost www.domain.com (/etc/apache2/sites-enabled/www_domain_com.conf:1)
         port 80 namevhost interface.domain.com (/etc/apache2/sites-enabled/www_domain_com.conf:10)
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/var/log/apache2/error.log"
Mutex watchdog-callback: using_defaults
Mutex rewrite-map: using_defaults
Mutex ssl-stapling: using_defaults
Mutex proxy: using_defaults
Mutex ssl-cache: using_defaults
Mutex default: dir="/var/lock/apache2" mechanism=fcntl 
PidFile: "/var/run/apache2/apache2.pid"
Define: DUMP_VHOSTS
Define: DUMP_RUN_CFG
User: name="www-data" id=33
Group: name="www-data" id=33

Solution:

Clear the browser cache. My browser had cached a rule to forward request to the other site.

Best Answer

Do not mix IP:port and *:port definitions in your <VirtualHost> tags unless you are a very experienced Apache administrator and know exactly what you are doing.

Any domain that resolves to 1.2.3.4 (in you example) will be served by your one bound to 1.2.3.4:80 no matter which host name used.

If the server names and server alaises in your *:80 virtual host do not resolve to 1.2.3.4 then something else is wrong. If they do resolve to this IP, simply change you <VirtualHost 1.2.3.4:80> to <Virtualhost *:80>

Additional comment: If you only have 1 IP on your server, only use the *:port version, it will avoid confusion

More comments: Part of the problem may be the way you are sanitising all the domain names. this must be done consistently otherwise our efforts will be in vain. The way apache decides which server to send a request to is as follows. This just simply works, any bug in this process could never survive even the most basic of testing for an Apache release:

  • If the connection is to a particular IP address and apache has a single matching <VirtualHost> tag for that ip/port then that virtual host will receive the request
  • If not, apache looks at the ServerName and ServerAlias directives for any <VirtualHost> that matches the IP/port the connection came in on and matches the HTTP Host header that came with the request. The first <VirtualHost> in the output of apachectl -S that matches will be the one to receive the request.
  • If no match is found then the default virtual host for that IP/port receives the request. This is the first virtual hjost listed in the output of apachectl -S for a particular ip/port combination.

Remember the IP could just be *.

Related Topic