How to Configure a Catch-All HTTPS Virtual Host in Apache 2.4 with Multiple SSL Domains


2 views

When working with Apache 2.4, setting up a catch-all HTTPS virtual host while maintaining multiple SSL-enabled domains presents unique challenges. Unlike HTTP where wildcards work reliably, HTTPS requires careful certificate handling.

The primary issue occurs because:

# This won't work as expected with SSL:
<VirtualHost _default_:443>
    ServerAlias *
    SSLEngine on
    # ...certificate paths...
</VirtualHost>

Here's the correct implementation using Server Name Indication (SNI):

# First, define your specific domains
<VirtualHost *:443>
    ServerName example-prod.com
    ServerAlias www.example-prod.com
    SSLEngine on
    SSLCertificateFile "/path/to/prod/cert.pem"
    SSLCertificateKeyFile "/path/to/prod/key.pem"
    # ... other SSL directives ...
    Include conf/sites/example-prod.com.conf
</VirtualHost>

# Then create a true catch-all that comes LAST
<VirtualHost *:443>
    ServerName wildcard.example.com
    ServerAlias *
    SSLEngine on
    SSLCertificateFile "/path/to/wildcard/cert.pem"
    SSLCertificateKeyFile "/path/to/wildcard/key.pem"
    Redirect permanent / https://example-prod.com
</VirtualHost>

For the catch-all to work:

  • Use a wildcard certificate (*.example.com) or
  • A multi-domain (SAN) certificate covering all possible domains
  • Ensure the catch-all vhost appears last in your config
# Check which vhost is being selected:
apachectl -S

# Verify SSL configuration:
openssl s_client -connect example.com:443 -servername example.com

Using catch-all HTTPS vhosts affects performance because:

  1. Apache must evaluate every request against all vhosts
  2. SSL handshake occurs before hostname matching
  3. Consider using separate IPs for high-traffic sites

Instead of a catch-all vhost, you could use mod_rewrite:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^example-prod\.com$ [NC]
RewriteCond %{HTTP_HOST} !^example-dev\.com$ [NC]
RewriteRule ^ https://example-prod.com%{REQUEST_URI} [R=301,L]

Setting up a catch-all HTTPS virtual host in Apache 2.4 presents unique challenges compared to HTTP configurations. The SSL/TLS negotiation occurs before Apache processes the Host header, which fundamentally changes how default vhosts behave.

Here's the proper way to implement this while maintaining your existing SSL configurations:


# HTTP catch-all (works as expected)
<VirtualHost *:80>
    ServerName dummy.example.com
    ServerAlias *
    Redirect permanent / https://example-prod.com
</VirtualHost>

# HTTPS catch-all (must be FIRST vhost definition)
<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile "C:/prod/hosts.crt.pem"
    SSLCertificateKeyFile "C:/prod/hosts.key.pem"
    SSLCertificateChainFile "C:/prod/intermediate.crt.pem"
    
    # Wildcard ServerAlias won't work here - use specific fallback
    ServerName catch-all.example.com
    ServerAlias *.catch-all.example.com
    
    # Implement proper fallback logic
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^(www\.)?example-prod\.com$ [NC]
    RewriteCond %{HTTP_HOST} !^example-dev\.com$ [NC]
    RewriteRule ^ https://example-prod.com%{REQUEST_URI} [L,R=301]
</VirtualHost>

# Existing production vhost (must come AFTER catch-all)
<VirtualHost *:443>
    ServerName example-prod.com
    ServerAlias www.example-prod.com
    SSLEngine on
    # ... rest of your existing config
</VirtualHost>

1. VHost Order Matters: The catch-all must be the first <VirtualHost *:443> definition in your config

2. Certificate Requirements: Your catch-all cert should be valid for all possible domains or use a wildcard

3. Performance Impact: Consider adding Protocols h2 http/1.1 to optimize modern browsers

If you encounter SSL handshake failures:


# Test configuration without restarting
apachectl configtest

# Check which vhost Apache is using
openssl s_client -connect yourdomain:443 -servername test.example

For more complex setups with multiple certificates:


# In main httpd.conf
SSLStrictSNIVHostCheck off

# Per-vhost configuration
<VirtualHost *:443>
    SSLStrictSNIVHostCheck on  # Only for specific vhosts
    # ... normal vhost config
</VirtualHost>