How to Exclude Specific Domains from Apache Wildcard ServerAlias While Maintaining Catch-All Functionality


2 views

When configuring Apache for multi-tenant applications with custom domains, the wildcard ServerAlias (*) is both a blessing and a curse. While it elegantly handles unlimited subdomains, it creates conflicts when you need to host other applications on the same server.

The typical wildcard virtual host configuration looks like this:


    ServerName primary.example
    ServerAlias * *.primary.example www.primary.example
    DocumentRoot /path/to/primary/app
    # Other directives...

The real problem emerges when you need to exclude certain domains from this catch-all:

  • Admin interfaces (admin.example)
  • API endpoints (api.example)
  • Marketing sites (marketing.example)
  • Legacy domains (oldapp.example)

Apache processes VirtualHost blocks in configuration file order, with the first matching ServerName/ServerAlias winning:

# Specific domains first

    ServerName excluded1.example
    ServerAlias www.excluded1.example
    DocumentRoot /path/to/other/app
    # Other directives...


# Catch-all comes LAST

    ServerName primary.example
    ServerAlias * *.primary.example
    # Original configuration...

For more dynamic control, implement domain checks in your catch-all VirtualHost:


    ServerName primary.example
    ServerAlias * *.primary.example
    
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(excluded1|excluded2|admin)\. [NC]
    RewriteRule ^ - [L,R=404]
    
    # Original configuration...

For better maintainability with many exclusions:

# In main Apache config
IncludeOptional sites-enabled/excluded-*.conf
Include sites-enabled/wildcard.conf

Then create separate files for excluded domains in sites-enabled/

  • Keep the exclusion list optimized - regex patterns can be expensive
  • Consider DNS-level filtering for large-scale deployments
  • Benchmark with ab -n 10000 -c 100 http://test.domain/

For truly dynamic domain management, consider integrating with your application:


    ServerName primary.example
    ServerAlias *
    
    RewriteEngine On
    RewriteMap excluded-domains "dbm:/path/to/domain-map.db"
    RewriteCond ${excluded-domains:%{HTTP_HOST}|NOT_FOUND} !NOT_FOUND
    RewriteRule ^ - [L,R=404]
    
    # Original configuration...


When configuring Apache2 for multi-tenant applications that need to support custom domains, many developers use wildcard ServerAlias configurations like this:


    ServerName example.com
    ServerAlias * *.example.com
    # Other configurations...

While the wildcard (*) works perfectly for catching all undefined domains, it creates conflicts when you need to:

  • Host other independent applications on the same server
  • Maintain admin or staging subdomains
  • Support legacy domains during migration

Apache processes VirtualHosts in order of specificity. Place your exceptions before the wildcard VirtualHost:


    ServerName special-app.com
    DocumentRoot /var/www/special
    # Other configs for this specific domain



    ServerName example.com
    ServerAlias * *.example.com
    # Wildcard config

For more complex exclusions, use mod_rewrite with regex patterns:


    ServerName example.com
    ServerAlias *
    
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(admin|staging|legacy)\.example\.com$ [NC]
    RewriteRule ^ - [L]
    
    # Rest of your config

For mission-critical exclusions, consider using separate IP addresses:


    ServerName critical-app.com
    # Special config



    ServerName example.com
    ServerAlias *
    # Wildcard config

For production environments, I recommend combining methods:

# 1. Specific domains first

    ServerName admin.example.com
    # Config


# 2. Regex exclusions

    ServerName example.com
    ServerAlias *
    
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(staging|dev)\. [NC]
    RewriteRule ^ - [L]
    
    # Main config

Always verify your setup with:

apachectl configtest
apachectl -S

The second command will show you how Apache is actually resolving your domains to VirtualHosts.