A recent configuration issue that we encountered involved trying to host multiple SSL enabled websites on a RackSpace Cloud Server with RackConnect. Each cloud server get’s only a single IP address but SSL requires each site to have a separate IP address. The work around then is to use a RackSpace Cloud Load Balancer to route additional IP addresses to the the cloud server on alternate ports. So for example if we have a cloud server at 10.10.10.1:
a. https://www.acme.com points to 1.2.3.4:443 on the load balancer with the backend node configured to route to 10.10.10.1:8443
b. https://www.mace.com points to 1.2.3.5:443 on the load balancer with the backend node configured to route to 10.10.10.1:8444
b. https://www.case.com points to 1.2.3.6:443 on the load balancer with the backend node configured to route to 10.10.10.1:8445
Now this looks like it should work. On the cloud server we just have to configure each of the virtual hosts to listen on the appropriate port.
But there is a catch, the ServerName in each virtual host must be in the form “acme.com:8443” … including the port number. Then when the server get’s a request like this where “admin” is a directory:
https://www.acme.com/admin
It tries to redirect to:
https://www.acme.com:8443/admin
This is the “trailing slash redirect” provided by mod_dir. The problem is Apache can’t for a proper self referencing URL because the ServerName includes the port number.
The solution we found for this problem is to bind the virtual host to a private address on the loopback interface and then frontend the instance with a virtual host using mod_proxy.
Here’s how it works:
a. the real virtual hosts are bound to 127.0.0.x addresses
Site A-Real goes on 127.0.0.2:80/443
Site B-Real goes on 127.0.0.3:80/443
Site C-Real goes on 127.0.0.4:80/443
b. the proxy virtual hosts are bound to the actual network interface:
Site A-Proxy goes on 10.10.10.1:8082/8443
Site B-Proxy goes on 10.10.10.1:8083/8444
Site B-Proxy goes on 10.10.10.1:8084/8445
Here’s a template for the real site config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<VirtualHost 127.0.0.2:443> ServerName "acme.com:443" ServerName "acme.com" ServerAlias "www.acme.com" UseCanonicalName Off UseCanonicalPhysicalPort Off DocumentRoot "/var/www/vhosts/acme.com/httpdocs" SSLEngine on SSLVerifyClient none SSLCertificateFile /etc/pki/tls/certs/acme.com.crt SSLCertificateKeyFile /etc/pki/tls/private/acme.com.key SSLCACertificateFile /etc/pki/tls/certs/acme.com.cacert </VirtualHost> <VirtualHost 127.0.0.2:80> ServerName "acme.com:80" ServerName "acme.com" ServerAlias "www.acme.com" UseCanonicalName Off UseCanonicalPhysicalPort Off DocumentRoot "/var/www/vhosts/acme.com/httpdocs" </VirtualHost> |
And here’s the proxy config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<VirtualHost _default_:8445&< ServerName "acme.com:8445" ServerAlias "www.acme.com" ServerAlias "ipv4.acme.com" DocumentRoot "/var/www/vhosts/acme.com/httpdocs" SSLEngine on SSLVerifyClient none SSLCertificateFile /etc/pki/tls/certs/acme.com.crt SSLCertificateKeyFile /etc/pki/tls/private/acme.com.key SSLCACertificateFile /etc/pki/tls/certs/acme.com.cacert SSLProxyEngine On ProxyPreserveHost On ProxyPass / https://127.0.0.2/ </VirtualHost< <VirtualHost 10.10.10.1:8082< ServerName "acme.com" ServerAlias "www.acme.com" ServerAlias "ipv4.acme.com" DocumentRoot "/var/www/vhosts/acme.com/httpdocs" ProxyPreserveHost On ProxyPass / http://127.0.0.2/ </VirtualHost< |