Resolving SSL Virtual Host Conflicts in Apache: Single IP HTTPS Configuration for Multiple Domains


1 views

When hosting multiple websites on a single server with Apache, a common challenge arises with SSL virtual hosts. The scenario described shows two domains - siteone.com (with SSL) and sitetwo.com (without SSL) - where HTTPS requests to sitetwo.com incorrectly serve content from siteone.com.

This behavior occurs because of how SSL/TLS handshakes work at the protocol level. The SSL certificate exchange happens before the HTTP request reaches Apache, which means:

  • Name-based virtual hosting can't function at the SSL layer without Server Name Indication (SNI)
  • With a single IP address, the first configured SSL virtual host becomes the default

For CentOS with Apache, we have several approaches:

1. SNI Implementation (Recommended)

Modern browsers support SNI, which allows multiple SSL certificates on one IP. Ensure your Apache and OpenSSL versions support SNI:

# Check OpenSSL version
openssl version
# Should be OpenSSL 1.0.1 or later

Example configuration for SNI:

<VirtualHost *:443>
    ServerName siteone.com
    SSLEngine on
    SSLCertificateFile /path/to/siteone.crt
    SSLCertificateKeyFile /path/to/siteone.key
    # Other SSL directives...
</VirtualHost>

<VirtualHost *:443>
    ServerName sitetwo.com
    SSLEngine on
    SSLCertificateFile /path/to/sitetwo.crt
    SSLCertificateKeyFile /path/to/sitetwo.key
    # Other SSL directives...
</VirtualHost>

2. Redirect Non-SSL Site

For sitetwo.com without SSL, implement a forced HTTP redirect:

<VirtualHost *:443>
    ServerName sitetwo.com
    Redirect permanent / http://sitetwo.com/
    SSLEngine on
    # Use a self-signed or dummy certificate
    SSLCertificateFile /path/to/dummy.crt
    SSLCertificateKeyFile /path/to/dummy.key
</VirtualHost>

3. Wildcard Certificate Approach

If both sites share a domain level (*.example.com):

<VirtualHost *:443>
    ServerName siteone.com
    ServerAlias *.siteone.com
    SSLEngine on
    SSLCertificateFile /path/to/wildcard.crt
    SSLCertificateKeyFile /path/to/wildcard.key
</VirtualHost>

After making changes, always validate your configuration:

# Check syntax
apachectl configtest
# Show virtual host configuration
apachectl -S
# Restart Apache
systemctl restart httpd
  • For older clients that don't support SNI, consider using separate IPs
  • Implement HSTS headers for your SSL sites
  • Use Let's Encrypt for free certificates if implementing SNI
  • Consider HTTP/2 for improved performance with multiple SSL sites

When hosting multiple websites on a single CentOS server with Apache, the SSL virtual host configuration becomes tricky with just one IP address. The fundamental issue stems from how SSL/TLS handshakes occur before the Host header is processed, making traditional name-based virtual hosting impossible for HTTPS.

Your Apache configuration shows:

VirtualHost configuration:
xxx.xxx.xxx.xxx:443     siteone.com
*:80                   NameVirtualHost
*:443                  NameVirtualHost

The key problem occurs because all HTTPS requests default to siteone.com regardless of the requested domain.

Here are three approaches to handle this scenario:

Option 1: Redirect HTTPS to HTTP

For sitetwo.com, create a dedicated SSL VirtualHost that forces HTTP redirect:

<VirtualHost *:443>
    ServerName sitetwo.com
    ServerAlias www.sitetwo.com
    Redirect permanent / http://sitetwo.com/
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem
</VirtualHost>

Option 2: Use SubjectAltName Certificates

Create a single certificate covering both domains:

openssl req -new -newkey rsa:2048 -nodes -keyout server.key \
  -out server.csr -subj "/CN=siteone.com" \
  -reqexts SAN -config <(cat /etc/ssl/openssl.cnf \
  <(printf "[SAN]\nsubjectAltName=DNS:sitetwo.com,DNS:www.sitetwo.com"))

Option 3: Wildcard Certificate Approach

If managing multiple subdomains:

<VirtualHost *:443>
    ServerName siteone.com
    ServerAlias *.siteone.com
    SSLEngine on
    SSLCertificateFile /path/to/wildcard.crt
    SSLCertificateKeyFile /path/to/wildcard.key
    # Other directives
</VirtualHost>
  • Always include ServerName directive in each VirtualHost
  • Keep SSL certificates in /etc/pki/tls/certs/
  • Use separate configuration files per domain in /etc/httpd/conf.d/
  • Test configuration with apachectl configtest before restarting

When debugging SSL virtual hosts:

# Check which virtual host is being served:
openssl s_client -connect sitetwo.com:443 -servername sitetwo.com | openssl x509 -noout -text

# Verify Apache's virtual host selection:
tail -f /var/log/httpd/ssl_access_log | grep sitetwo.com

# Test redirect behavior:
curl -v -k -H "Host: sitetwo.com" https://your-server-ip/

For production environments:

  • Enable OCSP stapling in SSL configuration
  • Implement HTTP/2 for better multiplexing
  • Consider using Let's Encrypt for certificate management

Remember that while these solutions work for most cases, the ideal long-term solution would be to either obtain additional IP addresses or migrate to a server that supports SNI (Server Name Indication) if you're using older clients.