After upgrading to Apache 2.2.31, I noticed a puzzling behavior where some SSL VirtualHosts were serving the default certificate instead of their designated ones, despite proper Server Name Indication (SNI) configuration. The error log clearly indicated:
[error] Server should be SSL-aware but has no certificate configured [Hint: SSLCertificateFile]
This occurred even when the VirtualHost blocks were correctly configured with SSLCertificateFile
directives.
The issue stems from Apache's SSL configuration parsing order. In 2.2.x versions, Apache processes SSL directives differently than later versions. The key points:
- SSL directives must appear before the
<VirtualHost>
block in the main configuration - Apache 2.2.x requires explicit SSL engine activation for each IP:port combination
- Missing global SSL configuration causes the parser to ignore VirtualHost-specific certificates
Here's the proper configuration structure that works with Apache 2.2.31:
# In httpd.conf or ssl.conf
Listen 443
NameVirtualHost *:443
# Global SSL configuration
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /path/to/default.crt
SSLCertificateKeyFile /path/to/default.key
# Then your VirtualHosts
<VirtualHost *:443>
ServerName www.hostedsite.org
SSLEngine on
SSLCertificateFile /path/to/hostedsite.crt
SSLCertificateKeyFile /path/to/hostedsite.key
# Other directives...
</VirtualHost>
The global SSL configuration acts as a fallback for non-SNI clients while allowing SNI-aware clients to receive the correct certificate. The critical elements:
- The global
SSLEngine on
activates SSL processing at the server level - Each VirtualHost must redeclare
SSLEngine on
- Certificate paths must be absolute (relative paths often cause issues)
Use this OpenSSL command to verify SNI behavior:
openssl s_client -connect yourserver:443 -servername www.hostedsite.org -showcerts
Compare the output when testing different hostnames to ensure each VirtualHost serves its designated certificate.
This issue typically manifests after Apache upgrades when VirtualHost configurations appear correct but certificates get mismatched. The key symptom is browsers showing certificate warnings despite proper SSLCertificateFile directives in your config.
In Apache 2.2.31+, the server validates SSL VirtualHost configurations more strictly. The error occurs when:
- SNI (Server Name Indication) enabled clients connect
- VirtualHost sections lack proper SSL parameter inheritance
- Certificate paths contain symlinks or relative paths
# 1. Verify your SSL config with:
apachectl -S 2>&1 | grep -A10 "port 443"
# 2. Check for syntax errors:
apachectl configtest
# 3. Examine mod_ssl loading order in httpd.conf:
LoadModule ssl_module modules/mod_ssl.so
A proper working configuration should resemble:
<VirtualHost *:443>
ServerName www.hostedsite.org
DocumentRoot "/var/www/site"
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
# Absolute paths required:
SSLCertificateFile /etc/ssl/certs/hostedsite.crt
SSLCertificateKeyFile /etc/ssl/private/hostedsite.key
SSLCertificateChainFile /etc/ssl/certs/intermediate.crt
# Critical for SNI:
SSLStrictSNIVHostCheck on
</VirtualHost>
For complex setups with multiple certificates:
- Ensure each VirtualHost has unique IP or port if disabling SNI
- Verify file permissions (certificates should be readable by Apache user)
- Consider using Include directives for shared SSL settings
When implementing the fix:
- OCSP stapling configuration should be added
- Enable session caching to reduce SSL handshake overhead
- Consider HTTP/2 configuration for modern browsers
# Verify certificate mapping:
openssl s_client -connect hostedsite.org:443 -servername hostedsite.org | openssl x509 -text
# Check Apache's SSL diagnostics:
tail -f /var/log/apache2/ssl_error_log