Friday, February 1, 2013

How to host multiple SSL enabled sites on a single IP address using Apache?

In the past, only one SSL enabled website could be hosted on a single IP address and default port 443 due to the limitation of TLS negotiation. With an addition of SNI(Server Name Identification) extension to TLS, server can now host multiple SSL enables sites using VirtualHost directive.

Apache ( 2.2.12 or later ) using OpenSSL(0.9.8 or later)  incorporates SNI. Today many browsers with the latest updates support SNI too. However, there could be many users still using older version of browsers that don't support SNI. Thus,  you may run into an issue where those customers may only be able to access your default website not the others.

Apache Configuration :

    Listen 443
    NameVirtualHost *:443
    SSLStrictSNIVHostCheck off

<VirtualHost *:443>
        ServerName  website1.yourdomain.com
        DocumentRoot /usr/local/your-website1/
----
----
</VirutalHost>

<VirtualHost *:443>
        ServerName  website2.yourdomain.com
        DocumentRoot /usr/local/your-website2/
----
----
</VirutalHost>


  • NameVirtualHost  apache directive is required if you want to configure name-based virtual hosts.
  • If SSLStrictSNIVHostCheck is off, then the request will be handled as if the server did not have SNI support.



Note: In Ubuntu, make changes appropriately to ports.conf and sites-enabled/your-ssl-websites  configuration files. In SLES, make changes appropriately  to listen.conf and vhosts.d/your-ssl-websites configuration files.


Additional Info:
Q: How to create SSL self signed certificate?
Ans: You can follow 4 basic steps:
    Step1: Generate no pass-phrase server private key; Note you can use any name for the key and certs. I prefer to use website URL as it is easier to track.
            #openssl genrsa -out website1.yourdomain.com.key 2048
    Step2: Generate CSR(Certificate Signing Request) using server private key
           #openssl req -new -key website1.yourdomain.com.key -out website1.yourdomain.com.csr
   Step3: Generate certificate using CSR and server private key.
           #openssl x509 -req -days 730 -in website1.yourdomain.com.csr  
-signkey website1.yourdomain.com.key -out website1.yourdomain.com.crt
   Step4: Copy certs and keys to appropriate location. In Linux, you can copy private keys to /etc/ssl/private and certificates to /etc/ssl/certs/

Q: How can I view the details of a certificate?
Ans: You can use the following command 
 #openssl x509 -in website1.yourdomain.com.crt -text

You can see that Certificate contains the reference to the issuer, the public key of the owner of this certificate, the dates of validity of this certificate and the signature of the certificate to ensure this certificate hasn't been tampered with. The certificate does not contain the private key as it should never be transmitted in any form whatsoever. This certificate has all the elements to send an encrypted message to the owner (using the public key) or to verify a message signed by the author of this certificate.

Q: How can I deploy SSL key and certificate in Apache?
Ans: You can follow 2 basic steps:
  Step1: Update VirtualHost configuration with the information of  SSL key and certificate you created.

    <VirtualHost *:443>
        ServerName  website1.yourdomain.com
        DocumentRoot /usr/local/your-website1/   
        SSLCertificateFile    /etc/ssl/certs/website1.yourdomain.com.crt
        SSLCertificateKeyFile /etc/ssl/private/website1.yourdomain.com.key
   </VirutalHost>


  Step2: Reload apache
         #service apache2 reload

Q: How SSL works?
Ans
Read notes from Symantec.com , tldp.org and luxsci.com

Basic steps (reference: tldp.org):
  1. A browser requests a secure page (usually https://).
  2. The web server sends its public key with its certificate. Note: Usually Certificate is signed with a private key of trusted Certificate Authority (e.g Verisign, Thwate, GoDaddy,etc). You can self sign a cert as demonstrated above if you don't want to pay for CSR. 
  3. All the browser comes installed with public key of all trusted Certificate Authority. The browser uses the public key to verify that the certificate was issued by a trusted root CA and certificate is still valid and that the certificate is related to the site contacted. If certificate is not signed by trusted CA, browser will complain that "Site's certificate is not trusted!".
  4. The browser then uses web server's public key to encrypt a random symmetric encryption key and sends it to the server with the encrypted URL required as well as other encrypted http data.
  5. The web server decrypts the symmetric encryption key using its private key and uses the symmetric key to decrypt the URL and http data.
  6. The web server sends back the requested html document and http data encrypted with the symmetric key.
  7. The browser decrypts the http data and html document using the symmetric key and displays the information.




Reference: