How to Block Unknown Host Requests in Apache2 by Disabling Default VirtualHost


6 views

Apache's default behavior of routing unmatched host headers to the first defined VirtualHost creates security and operational concerns. When implementing multi-tenant hosting solutions, this can lead to unintended content exposure or configuration leaks.

The correct approach involves creating a catch-all VirtualHost that returns HTTP 444 (Nginx-style connection drop) or 403 Forbidden:

# /etc/apache2/sites-available/000-catchall.conf

    ServerName invalid.host
    ServerAlias *
    RewriteEngine On
    RewriteRule ^ - [R=403,L]
    # Alternative silent drop:
    # 
    #   Require all denied
    # 

For this to work effectively:

  • The catch-all must be the first loaded VirtualHost
  • NameVirtualHost directive must be enabled
  • Individual VirtualHosts should explicitly declare ServerName

Here's a complete configuration for a secure multi-host setup:

# Main configuration
Listen 80
NameVirtualHost *:80

# Default catch-all (must be first)

    ServerName invalid.host
    ServerAlias *
    DocumentRoot /var/www/empty
    
        Require all denied
    
    ErrorLog ${APACHE_LOG_DIR}/invalid-host.log
    CustomLog ${APACHE_LOG_DIR}/invalid-host-access.log combined


# Valid host 1

    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example
    # Additional configuration...


# Valid host 2

    ServerName api.example.com
    DocumentRoot /var/www/api
    # Additional configuration...

For enhanced security:

  • Implement mod_rewrite rules to log invalid access attempts
  • Consider rate-limiting for repeated invalid requests
  • Monitor the invalid-host-access.log for scanning attempts

Some administrators prefer to redirect invalid hosts instead of blocking:


    ServerName invalid.host
    ServerAlias *
    Redirect 301 / https://valid-primary-domain.com


Apache's default behavior of routing undefined Host headers to the first VirtualHost can create security and management headaches. When you need strict hostname enforcement, here's how to properly implement it:

The most reliable method involves creating a catch-all VirtualHost that returns HTTP 444 (Nginx-style connection drop) or 403 Forbidden:



    ServerName default-catch-all
    
        Require all denied
    
    ErrorLog ${APACHE_LOG_DIR}/invalid_host.log
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/invalid_host_access.log combined


# Your legitimate vhosts come AFTER the catch-all

    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example

For a more Nginx-like behavior where connections are simply closed:



    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^example\.com$ [NC]
    RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
    RewriteRule ^ - [R=444]

  • Ensure your catch-all VirtualHost is the FIRST defined vhost in your config
  • For SSL configurations, duplicate this setup on port 443
  • Consider logging invalid requests for security monitoring
  • Test with: curl -H "Host: bogus.example" http://yourserver

Here's a complete configuration handling both HTTP and HTTPS:


# Catch-all for HTTP

    ServerName invalid-host
    Redirect 403 /
    ErrorLog ${APACHE_LOG_DIR}/invalid_host_error.log
    CustomLog ${APACHE_LOG_DIR}/invalid_host_access.log combined


# Catch-all for HTTPS

    ServerName invalid-host
    SSLEngine on
    # Your SSL cert paths here
    SSLProtocol all -SSLv2 -SSLv3
    Redirect 403 /
    ErrorLog ${APACHE_LOG_DIR}/invalid_ssl_host_error.log
    CustomLog ${APACHE_LOG_DIR}/invalid_ssl_host_access.log combined


# Legitimate vhosts

    ServerName example.com
    Redirect permanent / https://example.com/



    ServerName example.com
    SSLEngine on
    # SSL config here...
    DocumentRoot /var/www/example