Hosting Multiple SSL Web Sites On One IP Address With Apache 2.2 And GnuTLS (Debian Lenny)

Want to support HowtoForge? Become a subscriber!
 
Submitted by todgerme (Contact Author) (Forums) on Wed, 2011-02-02 18:26. :: Debian | Web Server | Apache

Hosting Multiple SSL Web Sites On One IP Address With Apache 2.2 And GnuTLS (Debian Lenny)

This tutorial describes how you can host multiple SSL-encrypted web sites (HTTPS) on one IP address with Apache 2.2 and GnuTLS on a Debian Lenny server.

For more information on why this couldn't be done prior to OpenSSL 0.98g or with GnuTLS please refer to http://en.wikipedia.org/wiki/Server_Name_Indication.

I will mention that Virtual Hosting SSLs on the same IP address has 1 or 2 caveats before beginning and before anyone begins ripping out and handing back IPs to their ISPs.

   1.  Firefox 2.0+ works on all platforms (Mac/Windows/Linux) - it has its own TLS implementation - if you have SSLv2 enabled for VMware tools, Firefox doesn't work either, but by default Firefox comes with v2 disabled by default
   2. Windows XP does not support SNI and still has 40% share in the world so you could alienate a lot of people unless they are using Firefox on XP.
   3. Browsers like Safari/Chrome/IE only work on Vista or greater because they use the O/S TLS implementation
   4. Safari/Chrome only work on 10.5.7 or above on Macs

Let's assume you have written a cool Web 2.0 app behind an SSL which only runs in the latest and greatest browsers because of excessive amounts of Javascript the everything I said above will be fine because your website won't work anyway in the older  browsers O/Ses anyways without Firefox.

You can test if your browser is passing SNI by visiting here: https://sni.velox.ch/

 Let's begin:

apt-get install libapache2-mod-gnutls

a2dismod ssl

a2enmod gnutls

Edit /etc/apache2/ports.conf and add the following line:

Listen 443

Also comment out the following in /etc/apache2/ports.conf:

 <IfModule mod_ssl.c>
    # SSL name based virtual hosts are not yet supported, therefore no
    # NameVirtualHost statement here
   Listen 443
</IfModule>

Finally create a file called /etc/apache2/ssl.conf:

NameVirtualHost xx.yy.zz.kk:443
<VirtualHost xx.yy.zz.kk:443>
ServerName secure.domain1.com:443
GnuTLSEnable on
GnuTLSCertificateFile /etc/apache2/ssl-certs/secure.domain1.com.crt
GnuTLSKeyFile /etc/apache2/ssl-certs/secure.domain1.com.key
GnuTLSPriorities NORMAL
DocumentRoot /web/www1

</VirtualHost>

<VirtualHost xx.yy.zz.kk:443>
ServerName secure.domain2.com:443
GnuTLSEnable on
GnuTLSCertificateFile /etc/apache2/ssl-certs/secure.domain2.com.crt
GnuTLSKeyFile /etc/apache2/ssl-certs/secure.domain2.com.key
GnuTLSPriorities NORMAL
DocumentRoot /web/www2

</VirtualHost>

Add in an include line in /etc/apache2/apache2.conf:

Include "/etc/apache2/ssl.conf"

Finally restart Apache2 with:

apache2ctl restart

Note on Godaddy SSLs:

With Godaddy you normally have you import a gd_bundle into Apache with the following OpenSSL directive:

SSLCertificateChainFile /etc/apache2/ssl-certs/gd_intermediate_bundle.crt

In order to use this root certificate in GnuTLS simply run:

cat  gd_intermediate_bundle.crt >> /etc/apache2/ssl-certs/secure.domain1.com.crt

This simply appends the bundle to the end of the certificate and GnuTLS is very happy using it.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by Ramin (not registered) on Sat, 2012-02-25 22:59.

Hi guys,

 I am wondering if this can be done on centos6.2 and ispconfig 3. if yes any one has the how to? Till do you have any insight?

take care... 

 

Submitted by Mark Waters (not registered) on Sat, 2011-02-05 20:32.
Works a treat on Ubuntu 10.04 PPC too Thanks!
Submitted by TheFu (not registered) on Wed, 2011-02-02 21:49.

Pound, a reverse proxy, can be used to provide an SSL front end to multiple back end web apps, web sites, and java apps. This isn't really the same thing as the article provides - it is not name-based virtual hosting to SSL. It isn't perfect, but works surprisingly well.

Basically, you install the SSL cert into pound.cfg and listen on port 443. Then configure multiple backends and proxy names to normal HTTP (non-SSL) services running either on the same or different machines. You cannot reverse proxy SSL/HTTPS webapps, but you can redirect them (probably to a different port).

Pound is small, efficient, and really easy to get working. It also allows URL validation to prevent unwanted external requests.

http_url --> https_url/subdir  --> webapp

  • http://webmail/ --> https://pub-ip/webmail/  ---> Zimbra
  • http://wiki/ --> https://pub-ip/wiki/  ---> MediaWiki
  • http://dms/ --> https://pub-ip/dms/  ---> Alfresco
  • http://vpn/ --> https://pub-ip/vpn/  ---> Adito
  • http://crm/ --> https://pub-ip/crm/  ---> vTiger
  • http://redmine/ --> https://pub-ip/redmine/  ---> Redmine
  • http://internal/ --> https://pub-ip/int/  ---> internal server
  • http://blog/ --> https://pub-ip/blog/  ---> 3 blog servers using round robin load balancing
  • Anything you like.

The issue comes when some webapps manually build links (Zimbra 5.x does this) so links to other parts of the webapp fail to work in some situations. This doesn't always happen, but having to manually add or remove the "s" from HTTPS gets old.


You can use HTTP name-based virtual hosts on a single HTTP machine (or with pound) to redirect to these different SSL subdirectories too. 

 I think Nginx reverse proxy can do the same sorts of things that pound does.

Submitted by SamTzu (registered user) on Fri, 2011-02-04 19:32.
This might be something that could be included in ISPConfig3. All the sites could be hosted with the same address, even the SSL protected admin panel (and /phpmyadmin.) And we could change the panel away from port 8080 to /ispconfig so that even those who are restricted to only using port 80 can have access to the control panel.
Submitted by SamTzu (registered user) on Fri, 2011-02-04 19:25.
Thx for the examples. Can we get a HowTo on Pound plz.