As in the post about initial DNS setup, I will call “new.example” the new domain name, and “old.dyn.example” the former free domain name.

When you visit a secure web site (bank, messaging…), that stands out as secure by the display of a lock and the use of HTTPS in the address, the web site sends to the web browser a site certificate that uniquely identifies it. This certificate is encrypted in such a way that only the true site can rightfully send it, and there is one trusted authority that can approve of it. This last step is checked locally by the browser, which has access to one locally-stored authority certificate for each trusted authority.

One cannot provide a certificate that would be deemed acceptable by a web browser without working with a trusted authority, because in such a case the web browser would not find any authority certificate that would give credence to the site certificate! The web browser would then display a warning that would discourage visitors to go on with their visit.

This problem can be circumvented by anyone familiar enough with the site to guarantee to the web browser, that it can trust this certificate. One obviously cannot expect casual visitors to engage in this circumvention procedure.

Of course, trusted authorities’ services do not come for free. Except, that is, for the one authority that allows you to have one free web certificate: StartSSL. They provide a free web certificate, with limited features, for a domain name that you own. The certificate is created for one year, and can be renewed each year for free. StartSSL will not work with a sub-domain, which is why a “free domain” will not do, as it is actually a sub-domain lent to you by the rightful owner of the domain (for example: sub-domain “old” of domain “dyn.example”). So you have to own a domain name to use StartSSL with it.

Thanks to the excellent explanations from geek85.net (ironically, the site has an invalid certificate…), I could very easily create the certificate.

First of all, I registered an account at StartSSL, which ends with importing my user certificate (another kind of certificate…) into my web browser. This certificate allows me to authenticate to StartSSL, which I did.

Then I declared my “new.example” domain name. Using the “Control Panel”, I went to the “Validations Wizard”, and chose “Domain Name Validation”. There, I entered the domain name, then the email address that StartSSL is going to use for all further exchanges related to this domain. Success at this step is made easier by previously having configured the mail server to accept emails sent to “new.example”; indeed, the choice of address is not free, but rather limited to common standard values, such as “hostmaster@new.example”. After that, I only had to do as instructed.

Secure web

At last, I created the certificate. I went to the “Certificates Wizard”, and chose “Web Server SSL/TLS Certificate”. I entered the domain name, as well as a mandatory sub-domain for the alias; for the latter, a common value is www, but since only one alias is allowed (for a free HTTPS certificate by StartSSL), it is worth thinking about what HTTPS will be used for, before making the final choice! And once again, I did as instructed… I chose to let StartSSL generate the private key for me, because there is not much behind my server’s HTTPS port; but as a general rule, and especially if you have sensitive data to protect, you should create the private key yourself. At the end of the process, I have two files, that I store on my server:

/etc/ssl/startssl/new.example_web.key.pem
/etc/ssl/startssl/new.example_web.crt.pem

I add to these a few useful files, that I generate with the following commands:

cd /etc/ssl/startssl/
wget -qO - https://www.startssl.com/certs/ca.pem https://www.startssl.com/certs/sub.class1.server.ca.pem >startssl_ca+subclass1.crt.pem
cat new.example_web.crt.pem new.example_web.key.pem >new.example_web.crt+key.pem
cat new.example_web.crt.pem startssl_ca+subclass1.crt.pem >new.example_web+startssl_ca+subclass1.crt.pem
cat new.example_web+startssl_ca+subclass1.crt.pem new.example_web.key.pem >new.example_web+startssl_ca+subclass1.crt+key.pem

All files with “key” in their name must be kept secret.

Then the web server configuration must be changed, in order to use the new certificate. Recently, I changed from Apache (where I was using a self-signed certificate, not valid in web browsers), to Nginx. I configured all the web browsers that I use to allow my self-signed certificate for my old domain name, thus, for the latter, I wish to continue using the old certificate; the new certificate is not valid for the old domain name anyway. Here is the general structure of the resulting Nginx configuration:


server {
server_name old.dyn.example;
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/certs/apache.pem;
ssl_certificate_key /etc/ssl/certs/apache.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;

location / {
return 301 $scheme://new.example$request_uri;
}

location /keep-on-old-domain {
… usual configuration …
}
location /stay-here-too {
… usual configuration …
}
}
server {
listen 80 default_server;
listen 443 default_server ssl;
ssl_certificate /etc/ssl/startssl/new.example_web+startssl_ca+subclass1.crt.pem;
ssl_certificate_key /etc/ssl/startssl/new.example_web.key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
keepalive_timeout 70;

}

When the configuration is done, it can be verified, as explained on jasoncodes.com:

echo HEAD / | openssl s_client -connect new.example:443 -quiet >/dev/null

I write the full domain name instead of localhost to remove the ambiguity, as my server is answering requests for several domains. If all goes well, the output looks like this:

depth=2 …

verify return:0

If the configuration is not correct, however, the output will look like that:

depth=0 …


verify return:1

Once this local verification is done, the web server as seen from outside can be more thoroughly tested by ssllabs.com. My web server scores an A :-)

Secure email

As proposed by the jasoncodes.com web site, the same certificate can be used with Exim (STARTTLS on SMTP) and Courier (STARTTLS on IMAP, IMAPS, POP3S), simply by running the following commands:

ln -s /etc/ssl/startssl/new.example_web+startssl_ca+subclass1.crt.pem /etc/exim4/exim.crt
ln -s /etc/ssl/startssl/new.example_web.key.pem /etc/exim4/exim.key

ln -s /etc/ssl/startssl/new.example_web+startssl_ca+subclass1.crt+key.pem /etc/courier/imapd.pem
ln -s /etc/ssl/startssl/new.example_web+startssl_ca+subclass1.crt+key.pem /etc/courier/pop3d.pem

Warning: Now that encryption is enabled, it is important to ensure that the certificate remains valid. That is why I chose to follow the excellent advice from the biapy.com web site, and I installed the small tool that monitors the end dates for the certificates that I use.

Changelog:

  • 2014-12-11 — Set the Nginx parameter ssl_protocols in order to be protected against the dreaded poodle attack.
  • 2015-10-07 — Exim needs the whole certificate chain for its certificate to be trusted by clients.