Revision of SSL Encryption from Mon, 01/04/2010 - 13:21

Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.

Secure communication with your web server by using self-signed SSL certificates.

Instructions adapted from http://www.tc.umn.edu/~brams006/selfsign.html.

Rather than paying for an SSL certificate from a signing authority, we'll use a self-signed certificate to provide encryption in Apache. The client's web browser will prompt them to whether the certificate should be accepted or not - if that is going to be a problem, then you'll need to get a certificate from a recognized signing authority.

Create a directory, readable only by root to hold our working files:

mkdir ~/cert
chmod 600 ~/cert
cd ~/cert

Generate your own Certificate Authority (CA)
The first thing we need to do is establish ourselves as a CA
Create an RSA Private Key;

openssl genrsa -des3 -out ca.key 4096

Then generate a Certificate Signing Request. You will be prompted for a various information. One of the prompts will be for "Common Name" - this should be the FQDN of the server you are protecting. However, it should also be different from the server key's CN, so add " CA" to the end of this one.

openssl req -new -x509 -days 365 -key ca.key -out ca.crt

You will be prompted for a variety of information:

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.
-----
Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Generate a server key and request for signing (csr).
This time, when prompted for a Common Name, use the FQDN of the server you want to protect. It should match the FQDN or IP address you specify in httpd.conf or ssl.conf for your server. If it doesn't, client browsers will give a "domain mismatch" message when they go to your server. The "challenge password" and "optional company name" can be left blank.
For a wildcard certficate, use *.domain.com for the server name.

openssl genrsa -des3 -out server.key 4096
openssl req -new -key server.key -out server.csr

Again, you'll have a variety of information to provide:

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.
-----
Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Sign the cerficate signing request (csr) with the self-created certificate authority (CA)
Note that 365 days is used here. After a year you'll need to do this again.
The serial number of the signed server certificate is set to "01". Each time you do this, especially if you do this before a previously-signed certificate expires, you'll need to change the serial key to something else. If you don't someone visiting your site who has a cached version of your certificate will get an error message.
The following command It takes your signing request (csr) and makes a one-year valid signed server certificate (crt) out of it. In doing so, we need to tell it which Certificate Authority (CA) to use, which CA key to use, and which Server key to sign.

openssl x509 -req -days 365 -in server.csr \
-CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

If you want to inspect the components of the key:

openssl rsa -noout -text -in server.key

Make a server.key for Apache that doesn't require a password
Here we create an insecure version of the server.key that will be used for when Apache starts, and will not require a password with every restart of the web server. But keep in mind that while this means you don't have to type in a password when restarting Apache (or worse -- coding it somewhere in plaintext), it does mean that anyone obtaining this insecure key will be able to decrypt your transmissions. Guard it for permissions VERY carefully.

openssl rsa -in server.key -out server.key.insecure
mv server.key server.key.secure
mv server.key.insecure server.key

Copy the files into position

mkdir /usr/local/apache2/conf/ssl.key
mkdir /usr/local/apache2/conf/ssl.crt
cp server.key /usr/local/apache2/conf/ssl.key/
cp server.crt /usr/local/apache2/conf/ssl.crt/

If you want to use this same certificate with your mail server?:

  • Qmail
    cat server.key server.crt>/var/qmail/control/servercert.pem
  • Courier-IMAP
    cat server.key server.crt>/usr/local/share/imapd.pem
  • Dovecot
    cat server.key server.crt > /usr/local/etc/dovecot.pem

Enable SSL in Apache config
Enable the SSL config file in the main Apache config, /usr/local/apache2/conf/httpd.conf by uncommenting:

Include conf/extra/httpd-ssl.conf

Edit the /usr/local/apache2/conf/extra/httpd-ssl.conf and comment out the default <VirtualHos> directive (all the lines in it).
Virtual Hosts with SSL
There's a variety of gotchas with using SSL with Virtual Hosts but by using a wildcard certificate, you can do it (though the end user will still get warnings).
Edit /usr/local/apache2/conf/extra/httpd-vhosts.conf and add the

NameVirtualHost *:443

Then create an entry for your VirtualHost:

<VirtualHost *:443>
  ServerName example.com
  ServerAlias www.example.com
  DocumentRoot /path/to/www.example.com
  # Note: SSL settings only need to be defined once!
  SSLEngine On
  SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
  SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key
</VirtualHost>
For additional VirtualHosts, you can omit the key information:
<code>
<VirtualHost 192.168.1.200:80 192.168.1.200:443>
  ServerName subsite.example.com
  DocumentRoot /path/to/subsite.example.com
</VirtualHost>

Restart Apache using daemontools:

svc -t /service/apache

Verify that it all works by accessing your site from your web browser. Be sure to use "https" instead of "http".

Recent Updates

  • 1 week 6 days ago
    1.27.2 update
  • 3 weeks 3 days ago
    Drupal 10/11 config
  • 3 weeks 4 days ago
  • PHP
    3 weeks 4 days ago
    PHP 8.3.11 and AlmaLinux
  • 3 weeks 5 days ago
    New version of Pound