Using SNI to host multiple SSL Sites on a single IP in apache using Rackspace Cloud

1/15/14 Update: Fr0X from the Rackspace Cloud Community solved the issue of Browser and OS limitations by leveraging CloudFlare with this solution. His post is at: https://community.rackspace.com/products/f/25/t/1829

Using SNI to host multiple SSL Sites on a single IP in apache using Rackspace Cloud

Common hosting knowledge has always been that if you want to host multiple SSL Sites on a single server you need to assign each website it’s own unique IP address. This makes sense. The whole purpose of SSL is that the request and response are encrypted. So when the request gets to Apache, Apache can not use standard name based hosting because it can not read the name of the site being requested since it is encrypted. To get around this, you can put sites on separate IP addresses and Apache will look at the request and say “I don’t know what site you are requesting, but I know you are requesting it on X IP address, so I will send you to the default site I have for X IP address.”

In a world with unlimited IP addresses this works just fine. The problem is that the world is quickly running out of IPv4 Addresses and that we might be stuck limping around on IPv4 for awhile waiting for ISPs to catch up with IPv6.

Enter SNI (Server Name Indication). SNI allows for browsers to send the hostname (domain) being requested separately un-encrypted so that the web server can understand the request and serve the right virtual host. It is not without it’s drawbacks though, let’s look at what those are:

Server Pre-Requisites

You must be running Apache 2.12 or higher, and you must be running openSSL 0.9.8f or higher. RHEL/CentOS 5.5 do not have both of these version available in the standard repositories or the extended EPEL repos, so yum install is out the window on those Distros. You will be stuck building from source. This is a game changer since your package manager is no longer aware of the installation of that software and will cause all sorts of headaches. Your options would be to search for a repo that does include these later versions and install it (I haven’t looked too hard yet), install from source, pray that 5.6 has it and wait, or go with Fedora 14.

For this example, I am going to go with Fedora 14 because it is the easiest way to demonstrate SNI since the necessary versions are in the yum repos.

Browser Limitations

Oh yeah, you don’t just have to worry about your server. You also have to worry about your user’s browsers. Not all of them support SNI, but most do. The following browsers work:

  • Mozilla Firefox V2 and up.
  • Chrome
  • Opera 8.0 or higher
  • IE 7 or higher on Vista or higher. (Sorry, IE 7 on XP won’t work)
  • Safari 3.2.1 on OS X 10.5.6 or higher

Ok, so that’s all the bad news. Is that enough to scare you away from it? Maybe. Only you can decide that, and as IPv4 addresses become more scarce and supply and demand kicks in prices for IPv4 addresses will go up. Only you can determine if this is the right solution for your business and website. Now let’s dive into a server!

Proof of Concept

Let’s see this in action! I am going to do these steps using a Fedora 14 Rackspace Cloud Server. I will do this using self-signed certs, and it will be a minimum install because it is simply proof of concept. I will be using domains test1.com and test2.com and modifying my hosts file to point to the IP of my server. Start up the server and login as root.

Install what you will need

Add in Firewall Rules

Create Some Directories

Create Some Index Files

Put something in them so we can see if it works

Create the self-signed Certs

Again, I am using test1.com and test2.com. Several of these commands will prompt you for input, just roll with it.

Repeat those steps above for a self signed cert for test2.com

Edit your Apache Config File

add into /etc/httpd/conf/httpd.conf

Start Apache

That’s it – after you edit your local hosts file you should be able to go to https://test1.com and https://test2.com in a browser and see your 2 test files. Note that you WILL get SSL Errors in your browser with the above, but that is only because they are self signed certs. If you look at the error, you will see that it is NOT due to a host name mismatch, but because the signer is not trusted. If you actually buy the certs you won’t get an error.

Leave me a comment and let me know what you think!

  1. According to: http://en.wikipedia.org/wiki/Server_Name_Indication

    The following combinations do not support SNI:

    Client side
    —————————————
    Konqueror/KDE in any version[19]
    Internet Explorer (any version) on Windows XP
    Safari on Windows XP
    wget[20]
    BlackBerry Browser
    Windows Mobile up to 6.5[21]
    Android default browser[22] (Targeted for Honeycomb but won’t be fixed until next version for phone users as Honeycomb will be reserved to tablets only)
    Oracle Java JSSE (As of 2011[update])

    Server side
    ———————–
    Microsoft Internet Information Server IIS (As of 2009[update]).
    Apache Tomcat (As of 2011[update])
    IBM HTTP Server [23]

    Libraries
    —————————————-
    Qt Client Side up to 4.7[18]
    Mozilla NSS server side [24]
    Python 2.x (ssl, urllib[2] and httplib modules) [17]

  2. Is this possible if you want to use a Load Balancer to distribute traffic to multiple web servers? I think Rackspace doesn’t support SSL Termination yet. Is there another way?

  3. I would have one small clarification to make:
    I see that you remove the pass phrase from the private key but then you do not use the “insecure” private key for Apache (this means that each time Apache starts it will expect the pass phrase to be typed in – maybe that’s what you want…).
    However, to user the private key without the pass-phrase I would suggest to more commands in the each directory from /etc/httpd/certs/:
    rm -rf server.key
    mv server.key.insecure server.key

    Thanks,
    Adi

  4. Feedback “Create the self-signed Certs” CLI is currently
    cd /etc/httpd/certs/test1
    it needs to be
    cd /etc/httpd/certs/test1.com

  5. It would also make it simple if you include the local hosts file edits

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">