2

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.

NorthsideP
  • 23
  • 3

2 Answers2

0

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").

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • Thank you for the detailed response! I'm hoping that a method for a for a true redirect is possible, although I had considered changing the "DocumentRoot" to point to the local IP address of the desired server as a stopgap measure. I'm just not sure if there are any real tangible security benefits from going that route however. – NorthsideP May 07 '15 at 18:46
  • @NorthsideP Note I'm not talking about redirects or changing the document root, I'm talking about running a reverse proxy. That would be transparent for the client. – Bruno May 07 '15 at 19:38
  • Sorry, I didn't mean it to sound like I was equating the two ideas. I am going to give [sniproxy](https://github.com/dlundquist/sniproxy) a try later tonight and report back. Thanks again! – NorthsideP May 07 '15 at 19:49
0

sniproxy suggestion from Bruno works like a charm! Very easy to install and configure.

  1. Installed Ubuntu Server 14.04 64-bit.

  2. Configured server (upgrades, ufw, etc.).

  3. Installed git.

    sudo apt-get install git

  4. Installed sniproxy dependencies.

    sudo apt-get install autotools-dev cdbs debhelper dh-autoreconf dpkg-dev gettext libev-dev libpcre3-dev libudns-dev pkg-config

  5. Downloaded sniproxy 0.4.0 git files to desired folder.

    git clone https://github.com/dlundquist/sniproxy.git

  6. Built Debian package.

    ./autogen.sh && dpkg-buildpackage

  7. Installed package.

    sudo dpkg -i ../sniproxy__.deb

  8. Edited /etc/sniproxy.conf "http_hosts" and "https_hosts" tables to point domains to the desired local ip addresses and ports.

  9. Started sniproxy.

    Usage: sniproxy [-c ] [-f] [-n ] [-V]
    -c configuration file, defaults to /etc/sniproxy.conf
    -f run in foreground, do not drop privileges
    -n specify file descriptor limit
    -V print the version of SNIProxy and exit

More instructions can be found at the sniproxy GitHub.

Community
  • 1
  • 1
NorthsideP
  • 23
  • 3