Configure Apache2 to run multiple secure, name based vhosts on the same IP
Apache2/SSL/vhosts on a single IP
Hosting in the cloud has some benefits, but one current drawback for Amazon's EC2 is the limitation of one external IP address for each instance. It is a common opinion that Apache can't share an IP with secure name based virtual hosts. I believed that for years. I arrived at this solution because I didn't want to pay for an instance for each secure subdomain (sql.example.com, admin.example.com, client.example.com) in addition to one for example.com.
The rule
"You cannot put multiple SSL-enabled virtual Apache hosts onto the same IP and port.
An exception to the rule
You cannot put multiple SSL-enabled virtual Apache hosts onto the same IP and port , unless they are on the same domain and you have a wildcard ssl certificate.
Having different SSL domains on the same IP and port is a virtual chicken/egg problem. Apache doesn't know which host it is so it doesn't know which SSL cert to use. It doesn't know which cert to use until it knows which host it is.
The reason we can share the same IP, port and SSL cert with more than one name based host is this - Apache doesn't know which of the vhosts on the IP the traffic is for, but since they all use the same SSL cert, it can decrypt the request and successfully use the right virtual host.
Things you must not forget to remember
- All vhosts must be fore the same domain.
- You must have a wildcard certificate for the domain
- You must manually set some Apache Environment Variables that it will set wrong
- You must be specific as possible wiht the names of your hosts AND the port number
- Only enable SSL for the first secure vhost in the file
Download the example below...
# How to enable multiple secure vhosts on the same IP, port and domain.
#
# 0) All hosts on the same IP must use the same wildcard SSL certificate.
#
# 1) Without the port number on the ServerName users would randomly see a
# "12263 error" over SSL. To be safe I added it on all vhosts.
#
# 2) With PHP - if you want to use Environment Vars from $_SERVER, you might
# have to set them yourself. Apache lies to PHP when on SSL.
#
# 3) Only enable SSL once per Cert
#
# Enable name based hosts for the IP and ports you plan to use
NameVirtualHost 192.168.0.2:80
NameVirtualHost 192.168.0.2:443
# WWW.EXAMPLE.COM
<VirtualHost 192.168.0.2:80>
ServerName www.example.com:80
DocumentRoot "/var/www/example.com/www"
</VirtualHost>
# SECURE WWW.EXAMPLE.COM
<VirtualHost 192.168.0.2:443>
# Without the port number on the ServerName users would randomly see a "12263 error"
ServerName www.example.com:443
DocumentRoot "/var/www/example.com/www"
# Enable SSL (only once per cert)
SSLEngine on
SSLCertificateFile /var/ssl/example.com/STAR_moneydesktop_com.crt
SSLCertificateKeyFile /var/ssl/example.com/STAR_moneydesktop_com.key
SSLCACertificateFile /var/ssl/example.com/STAR_moneydesktop_com.gd_bundle.crt
# Apache lies to PHP about these environtment variables
# Despite the browser being happy on https (443)
# 'HTTPS' isn't set in the PHP $_SERVER array and 'SERVER_PORT' is set to 80
SetEnv HTTPS on
SetEnv SERVER_PORT 443
</VirtualHost>
# ADMIN.EXAMPLE.COM REDIRECT
<VirtualHost 192.168.0.2:80>
ServerName example.com:80
redirect permanent / https://admin.example.com/
</VirtualHost>
# SECURE ADMIN.EXAMPLE.COM
<VirtualHost 192.168.0.2:443>
# Without the port number on the ServerName users would randomly see a "12263 error"
ServerName admin.example.com:443
DocumentRoot "/var/www/admin_example.com/www"
# DO NOT turn the SSL Engine on or configure the SSL Certs, it is already done
# Apache lies to PHP about these environtment variables
# Despite the browser being happy on https (443)
# 'HTTPS' isn't set in the PHP $_SERVER array and 'SERVER_PORT' is set to 80
SetEnv HTTPS on
SetEnv SERVER_PORT 443
</VirtualHost>
I hope this helps someone out. Feel free to email me if you have questions. This worked on Apache2 on Debian GNU/Linux lenny, I can't say what happens with other versions of Apache2 or PHP.
Download the example above
|