Search code examples
apachesslsni

Is it possible to run 2 servers with seperate SSL certificates on 1 IP address?


I have two domains running on separate local servers, each with their own SSL certificate. In the past, this would require two public IP addresses. With the advent of SNI (Server Name Indication), these two sites can be run on the same server by modifying Apache.conf like so-

<NameVirtualHost *:443>

<VirtualHost *:443>
 ServerName www.yoursite.com
 DocumentRoot /var/www/site
 SSLEngine on
 SSLCertificateFile /path/to/www_yoursite_com.crt
 SSLCertificateKeyFile /path/to/www_yoursite_com.key
 SSLCertificateChainFile /path/to/DigiCertCA.crt
</VirtualHost>

<VirtualHost *:443>
 ServerName www.yoursite2.com
 DocumentRoot /var/www/site2
 SSLEngine on
 SSLCertificateFile /path/to/www_yoursite2_com.crt
 SSLCertificateKeyFile /path/to/www_yoursite2_com.key
 SSLCertificateChainFile /path/to/DigiCertCA.crt
</VirtualHost>

Due to security concerns, I would prefer to run these sites on different local servers to help mitigate damages in case one server is compromised. Can this be done via a local IP address redirect in Apache.conf without breaking the SSL certificate?
Thank you in advance for any suggestions.


Solution

  • Since you're happy to use SNI, your problem here isn't so much about using two certificates on the same IP address (and port), it's about having two servers bound to the same IP address and port at the same time.

    Having two distinct servers listening on the same IP address and port is generally not possible or useful (depending on the OS).1

    That said, nothing prevents you from running other Apache Httpd instances, even on the same machine, listening on different ports.

    To make the client connection still use port 443, you could have a main Apache Httpd server running and listening on that port, configured as a reverse proxy for the other server(s), depending on which VirtualHost is reached.

    In this case, that front-end would still handle both certificates (and you would only generally require plain HTTP connection between the reverse proxy front-end and the other servers on the same host, although you might want to make sure the other hosts are only accessible from localhost).

    Alternatively, I've seen (not tried) tools like sniproxy which allow you to detect the host name in the SNI extension and redirect this to other sockets. It's a similar principle, but each back-end server would handle its own certificate.


    1. You may find people mentioning using SO_REUSEADDR on the socket, but that doesn't really solve the problem: it won't allow you to bind another process if another one is in LISTEN state on Unix ("This socket option tells the kernel that even if this port is busy (in the TIME_WAIT state), go ahead and reuse it anyway. If it is busy, but with another state, you will still get an address already in use error."), and it won't guarantee the connection will go to the right socket on Windows ("For example, if all of the sockets on the same port provide TCP service, any incoming TCP connection requests over the port cannot be guaranteed to be handled by the correct socket — the behavior is non-deterministic").