Ubuntu LTS - Apache, SSL and vhosts

Secure connections to your website are vital when entering passwords or entering administration areas.

This article will take you through creating a self-signed certificate and configuring your virtual host to use https (port 443) connections.


Non commercial

Before we go any further I would point out that self-signed certificates will produce warnings when accessed via an https link.

They are not suitable for commercial sites or any public facing site but are ideal for personal administration areas.

There are many sites that specialise in issuing recognised and guaranteed certificates. A search for 'ssl certificates' in your favourite search engine will provide many links.

Note

It has been pointed out that the package:

apache2-ssl-certificate

may not be installed on some Ubuntu distros.

I have not been able to reproduce this issue but if you missed any of the articles when setting up your Slice this may well be the case.

If you are missing the package you can install it (if it available for your distro) or use another method such as:

sudo mkdir /etc/apache2/ssl
sudo /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem

Also, note that we no longer offer Ubuntu Dapper (LTS) as Ubuntu Hardy (LTS) has has replaced it.

However, following the Apache install article (link in the next sentence) does install the package whenever I have tested it on an Ubuntu Dapper (LTS) Slice.

SSL directory

We can place the generated certificate anywhere but I like to keep them in one folder and it just so happens that during the Apache install (see here), the directory '/etc/apache2/ssl' was created for us.

Well, that saves us a job.

Certificate

There are a few of ways of creating self-signed certificates. The method used here creates a single file and does not require a passphrase on a reboot or Apache restart.

To start enter the following command:

sudo apache2-ssl-certificate

The initial output is as follows:

creating selfsigned certificate
replace it with one signed by a certification authority (CA)

enter your ServerName at the Common Name prompt

If you want your certificate to expire after x days call this programm
with -days x
Generating a 1024 bit RSA private key
.....................++++++
..++++++
writing new private key to '/etc/apache2/ssl/apache.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

As indicated, you will be asked a series of questions:

Country:

Country Name (2 letter code) [GB]:

In my case, I just pressed 'enter' as the process picked up that my default location was Great Britain. Remember it is a 2 letter code.

State:

State or Province Name (full name) [Some-State]:

You can leave this blank but for demonstration purposes I entered 'Nottinghamshire'

City:

Locality Name (eg, city) []:

Again, leave blank if you wish. I entered 'Nottingham'.

Organisation:

Organization Name (eg, company; recommended) []:

Here I entered 'PickledOnion Ltd'.

Unit:

Organizational Unit Name (eg, section) []:

I entered 'Web Development'

Server Name

server name (eg. ssl.domain.tld; required!!!) []:

Enter the domain you want the certificate to relate to. In this example I entered 'admin.domain.com'.

If you enter an incorrect address or use the single certificate on multiple domains you will be presented with a warning box as indicated below in the 'Warnings' section.

Email:

Email Address []:

If you want your email address displayed on the certificate, then enter it here. If you are going to use a self-signed certificate for public facing sites then I would recommend entering a valid address as it gives them a person to contact.

Anyway, I entered 'webadmin@domain.com'

Done

You will be placed back at the command prompt and the certificate has been placed in /etc/apache2/ssl/. The certificate filename is apache.pem.

mod_ssl

So now we have the certificate we need to enable Apache mod_ssl:

sudo a2enmod ssl

As directed, restart Apache:

sudo /etc/init.d/apache2 force-reload

ports.conf

Next configure Apache to listen to port 443 (the default https port):

sudo nano /etc/apache2/ports.conf

Add port 443 to the list so the file looks like this:

Listen 80
Listen 443

Virtual Hosts

Now we get to configuring the virtual hosts to enable secure connections.

Remember that you can only have one certificate per IP address which means that if you enable SSL connections to more than one virtual host they will share the same certificate.

If you have multiple IPs for your Slice (yes, they are coming!) then you would configure the virtual hosts based on IP address and not necessarily based on named hosts (more on this in future articles).

Let's start by enabling port 443 on the default vhost:

sudo nano /etc/apache2/sites-available/default

At the very top of the file you will see this:

NameVirtualHost *
<VirtualHost *>
...

Change these settings to listen to the default http port (80):

NameVirtualHost *:80
<VirtualHost *:80>
...

Now we need to add support for port 443.

Add 'NameVirtualHost *:443' so it looks like this:

NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost *:80>
...

So now the default virtual host is listening to both port 80 and port 443. However, we've only got settings for port 80: It won't know what to do with any connections to port 443.

Let's rectify that by copying the <VirtualHost *:80> settings:

<VirtualHost *:80>
...
...
</VirtualHost>

and paste them at the bottom of the file with the port changed to *:443 as follows:

<VirtualHost *:443>
...
...
</VirtualHost>

One final tweak to the pasted settings is the addition of these two lines (before the final /VirtualHost line):

SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem

Heh?

Don't worry if you got a bit lost there as I've attached a copy of what the finished virtual host file should look: view file

I haven't changed the default vhost settings except to add port 443 access as described above.

Other virtual hosts

Remember how we changed <VirtualHost *> to <VirtualHost *:80> in the default virtual hosts file? Well, we need to do the same for any other virtual hosts files.

Then, to add SSL support to any other virtual hosts simply repeat the procedure and have two configurations in each file. One for port 80 and one for port 443 - keep in mind that any configured virtual hosts will share the same certificate.

You don't need the NameVirtualHost settings in each file though. They only need to be in the default file.

Reload

At this point, reload Apache for the new settings to take effect:

sudo /etc/init.d/apache2 force-reload

Warnings

Now when you browse to your IP address or whichever virtual host you setup to use SSL:

https://www.domain.com

You will see warnings similar to these:

Apache  SSL Warning

Clicking 'OK' will take you to a second warning:

Apache  SSL Warning #2

If you accept the certificate, you will then proceed to the site. However, as you can tell, a visitor receiving these warnings on a secure area of a public website will not be too impressed. They are, however, fine for personal use and for an administration area.

Summary

If you followed this through you will see that adding self-signed certificates and adding virtual host support for SSL connections is relatively straight forward.

PickledOnion.

Article Comments:

Bouke commented Sat Feb 28 09:49:58 UTC 2009:

Great tutorial; got my Apache2 installation running with SSL in less then no time. Thanks!

Musfuut commented Mon Mar 09 10:04:19 UTC 2009:

Sadly the apache2-ssl-certificate command was removed in Ubuntu between feisty up to hardy and was reinstated in intrepid.

As an alternative to compiling from source, upgrading to intrepid, or using make-ssl-cert with its 30 day limit I wrote a brief wiki entry to creating long-term certs with openssl.

http://wiki.slicehost.com/doku.php?id=sslcerts

Hope it is helpful, cheers!

Jeremy commented Sat Nov 28 23:54:05 UTC 2009:

I was just a little stumped when I could not make this work, realizing that I had forgotten to make a firewall exception for port 443. That was my fault.

Great tutorials!

Magnus commented Sun Jan 10 16:59:43 UTC 2010:

Followed this tutorial with no luck. Works with just port 80 but when I add port 443 site does not display and get this message when restarting apache.

  • Restarting web server apache2 [Sun Jan 10 16:55:40 2010] [warn] NameVirtualHost *:443 has no VirtualHosts [Sun Jan 10 16:55:40 2010] [warn] NameVirtualHost *:80 has no VirtualHosts httpd (no pid file) not running [Sun Jan 10 16:55:50 2010] [warn] NameVirtualHost *:443 has no VirtualHosts [Sun Jan 10 16:55:50 2010] [warn] NameVirtualHost *:80 has no VirtualHosts (98)Address already in use: make_sock: could not bind to address 0.0.0.0:80 no listening sockets available, shutting down Unable to open logs

Carlton Gibson commented Thu Jun 17 10:44:34 UTC 2010:

It helps to turn the SSL engine on per virtual host:

SSLEngine on

unlocking phone commented Fri Apr 19 12:44:27 UTC 2013:

I'm extremely inspired along with your writing skills as neatly as with the layout to your blog. Is this a paid topic or did you customize it yourself? Either way keep up the excellent high quality writing, it's uncommon to peer a great weblog like this one today..

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)