If you run your own website, email server or other services like OwnCloud at home then you may find yourself in need of a SSL certificate. When you install Apache, it generates a self-signed "snakeoil" certificate that can be used to encrypt your session. However, while this certificate is useful for testing purposes, it falls short in a couple of important ways:
- The snakeoil certificate has not been signed by an authority that your browser trusts, so your browser will throw an error when you connect.
- The common name on the certificate probably doesn't match your domain name. Another browser error.
- Short of manually inspecting the certificate's checksum, you have no guarantee that you are communicating with your own server - it could easily be an imposter using another self-signed certificate.
This tutorial will show you how to generate your own SSL certificate, and get it signed by the community driven SSL certificate signing authority CAcert. Once you have imported the certificate into your browser or into your operating system's root filesystem, your computer will automatically verify the identity of the server and you will enjoy error-free secure communications. Oh, and CAcert is free of charge!
Before we start: a quick note about filename extensions
As far as I can tell, Linux is not at all bothered about what you name your certificate and certificate key files. You could use the .magic extension for your cert if you liked and it would probably still work. From what I've read, file name extensions seem to only matter on Windows, whereas on Linux they're just descriptive. However, it's probably worth noting that there are lots of different types of certificate encoding styles, which have been summarised neatly here. Some extensions such as .pem and .der imply that the file is encoded in a certain way. Since we are able to choose whatever extension we like, I've chosen the following:
- .csr for the certificate signing request (CSR)
- .crt for the signed certificate file
- .key for the key file
These have the benefit of not implying any particular encoding. The first time I did this on my Pi, I used .pem for everything and got in a muddle, forgetting which file was which. This should make things much easier!
Generate your certificate
We are going to use a two step process to generate your certificate. First, run this command, which will generate a private key:
openssl genrsa -out <filename for your private key>.key 4096
Now we will generate a new certificate signing request (CSR) from your private key:
openssl req -new -key <filename for your private key>.key -out <filename for the CSR>.csr
This stage requires user input, a series of questions about what information you would like to be on the certificate. Since CAcert is an automated service, it discards most of the information on the certificate (so that it doesn't certify the information it is unable to verify), leaving only the essentials: the email address and the common name. Here is the information you will be asked for:
- Country Name (use a two letter code e.g. GB)
- State or Province Name (e.g. Surrey)
- Locality Name (e.g. Guildford)
- Organisational Name (e.g. Sam Hobbs' Personal Website)
- Organisational Unit Name (e.g. Website)
- Common Name (your domain name - see note below - e.g. samhobbs.co.uk)
- Email Address (the contact address for your administrator e.g. webmaster@samhobbs.co.uk)
Don't set a password - leave it blank when asked. We will keep the key file private by setting appropriate permissions. The common name is important here: most websites rewrite https://
to https://www.
or vice versa. If your website is available at https://yourdomain.com
then you should use yourdomain.com
as the common name; if your website is at https://www.yourdomain.com
then your common name should be www.yourdomain.com
or *.yourdomain.com
(the wildcard will match any subdomain, meaning you can use the same cert for https://mail.yourdomain.com
and https://www.yourdomain.com
, which is handy). Personally, I use a wildcard certificate. If you were paying for a normal certificate authority to sign your certificate then a wildcard cert would be more expensive, but CAcert is of course free so you might as well take advantage of it!
Install the CAcert root certificate
Every operating system comes pre-loaded with a set of certificates that are seen as trusted by the OS. This includes certificates from verisign and other big name certificate signing authorities. Very few OSes trust CAcert by default, although a couple of Linux distributions do. The CAcert website provides https using a certificate that was signed by the CAcert root. Since you are going to be sending sensitive information to the website during registration, it makes sense to install the CAcert root certificate now so that you can use the site without browser errors. To install the CAcert root certificate from the commandline, you can use these commands:
cd ~ wget http://www.cacert.org/certs/root.txt sudo cp root.txt /etc/ssl/certs/cacert-root.crt
Those commands will download the CAcert root certificate into your home directory, and then copy it to your certificates folder. If you look in your certs directory (ls -l /etc/ssl/certs
) you will see that all of the certs have sensible certificate names like GeoTrust_Global_CA.pem, but there are also a load of symbolic links with names like 2c543cd1.0 that point to the certificate files with the human readable names. Those symlink names like 2c543cd1.0 are hashes of the certificate files, and are there to enable programs on your computer to quickly check whether the root certificate is in your computer's certificate directory or not. Some programs manage to recognise that the certificate is installed just fine without the symlinks, but some of them do not. Openssl is one of the ones that doesn't. So, we need to make use of one more command to create a symlink for the newly installed cacert-root.crt (this will also refresh the symlinks for the rest of the certs in the folder):
sudo c_rehash /etc/ssl/certs
Now that the CAcert root cert is installed, almost all software on your system will recognise it (chromium, rekonq etc.). The exception to this is Mozilla software such as the Firefox web browser and Thunderbird email client. Mozilla software has its own certificate database, which has both advantages and disadvantages. For example, if you're using a system where you don't have admin rights, you can still easily import the CAcert root to Firefox. The disadvantage is that if you are an administrator, you can't do a one-stop installation: you have to import it separately to Firefox. To install the certs, open Firefox and navigate to the root certificate downloads page and click on the links for the class 1 and class 3 .pem encoded root certificates. You will be prompted to decide whether to import them or not. To install to Android, follow this tutorial of mine.
Required Email Address
CAcert verifies that you own the domain it is signing a certificate for by sending a verification link to one of the following email addresses:
- root@yourdomain.com
- webmaster@yourdomain.com
- postmaster@yourdomain.com
You therefore need to be able to receive email to one of these addresses. You can set up your own email server, or failing that some domain name registrars provide email forwarding capabilities. If you used my tutorials to set up your email server then you may want to add some aliases to your server so that emails to those addresses above are delivered to your username. Here's how: Edit /etc/aliases
and add:
postmaster: yourusername webmaster: yourusername root: yourusername
Now run this command to load the new aliases:
sudo newaliases
And reload Postfix:
sudo service postfix reload
Submitting the CSR to CAcert
First things first, you will need to go to the CAcert website and create an account: Please note that CAcert has signed its own SSL certificate, so your browser may throw an error if you haven't imported the root cert yet. After you have created your account and logged in, navigate to server certificates --> new. On your server, use cat
to print the the Certificate Signing Request (CSR) you created earlier and then copy & paste it into the box:
cat <filename for the CSR>.csr
...and click submit. The result will be displayed on screen, and you will also be emailed the certificate. Copy and paste it into a file with the .crt extension, e.g. using nano:
sudo nano <path to your cert>.crt
...then CTRL+SHIFT+V to paste, CTRL+X, save when prompted. Note: the BEGIN CERTIFICATE and END CERTIFICATE lines are part of the cert, so copy those too!
Certificate File Locations
Assuming your certificates and key file are in your home directory, it's a good idea to move them to the proper locations
- Your key file should be stored at
/etc/ssl/private/samhobbs.key
. - Your certificate file should be stored at
/etc/ssl/certs/samhobbs.crt
. - You can get rid of your CSR, or keep it for reference if you like.
Permissions & Ownership
Your key file is secret. It should be owned by root, and your permissions should be set so that only the root user can read and write to it. This command will set it to be owned by root:
sudo chown root:root /etc/ssl/private/samhobbs.key
And this command will set it so that only the root user can read and modify it:
sudo chmod 600 /etc/ssl/private/samhobbs.key
Most services like Apache, Postfix etc. require root privileges to start up. They read the certs when they start and store them in RAM, so that they can still use them when they drop to their normal users ( e.g. www-datafor Apache). Unlike your key file, your signed certificate file is not a secret (it is sent to users when establishing a secure session). You want all users to be able to read the cert, but only the root user to have write access to it. As before, this command will set it to be owned by root:
sudo chown root:root /etc/ssl/certs/samhobbs.crt
And this command will set it to be readable by everyone, but only modified by root:
sudo chmod 644 /etc/ssl/certs/samhobbs.crt
Some common SSL cert configuration parameters: Apache, Postfix, Dovecot
This section is a quick reference for where to find SSL parameters for Apache, Postfix and Dovecot.
Apache
You can tell Apache to use a specific certificate file in your SSL virtualhost configuration (e.g /etc/apache2/sites-available/default-ssl
) with these parameters:
SSLEngine on SSLCertificateFile /etc/ssl/certs/samhobbs.crt SSLCertificateKeyFile /etc/ssl/private/samhobbs.key
Then reload Apache:
sudo service apache2 reload
Postfix
Postfix' SSL cert configuration can be found in /etc/postfix/main.cf
:
smtpd_tls_cert_file=/etc/ssl/certs/samhobbs.crt smtpd_tls_key_file=/etc/ssl/private/samhobbs.key
...and reload Postfix:
sudo service postfix reload
Dovecot
Dovecot's SSL configuration is in /etc/dovecot/conf.d/10-ssl.conf
:
ssl_cert = </etc/ssl/certs/samhobbs.crt ssl_key = </etc/ssl/private/samhobbs.key
NB: the < at the start of the path isn't an error, if you miss it out Dovecot won't load. Reload dovecot:
sudo service dovecot reload
Hopefully you found that useful! If you have anything to add or a question, please feel free to leave a comment!
Comments
Great tutorial
I must say, I've followed this all to the letter and it is perfect. You covered virtually every situation I ran into trying to set up my own email server on my Raspberry Pi. Kudos!
Awesome! Thanks for the
renew CACert
Hi Sam, Thanks for your tutorials they really are a fantastic resource. I followed your tutorial a while back and it worked great and allowed me to use certificate for email and web server.
However now I am getting notification I will need to renew my certificate, I followed the link in the email and logged into CACert website. I clicked to renew which gave me a new certificate. I then created a new certificate file and copied it over the old one, I renamed it to use same name as old one. However when I tried to restart my webserver (which is nginx) I get a message that the private key file doesn't match. Also my email stopped working. I wondered if you have any idea where I went wrong? At the moment I've copied the old one back in which has everything working again, but will expire fairly soon.
Thanks
It's a while since I've
Hi Sam, No I didn't need to
Hi Sam, No I didn't need to submit another CSR they just gave me a new certificate when I clicked the renew button. But I'm not sure what to do with it! I downloaded the pem version (if i remember right) and then renamed it to replace the old one with the new one (in /etc/ssl/certs). But that didn't seem to work. Wondered if i need to recreate symlinks or something ? Or if its because the private key doesn't work with the new cert? Anyway no worries if you don't know off top of your head. I guess I can go through the whole creating a CSR process again if I need to ..
Well, it should work. As you
Apache won't reload or restart
Hi Sam
Excellent set of tutorials, thank-you. However, I have a problem, after changing the SSLCertificateFile and SSLCertificateKeyFile, Apache won't reload or restart, I get the error message
pi@raspberrypi ~ $ sudo service apache2 restart
[....] Restarting web server: apache2 ... waiting Action 'start' failed.
The Apache error log may have more information.
failed!
When I try to restart, same with reload. When I change the parameters back, it works fine.
Any hints, ideas?
Thanks
Shaun
What's in the Apache error
/var/log/apache2/error.log
. SamSmooth operation, but, can't connect :-(
Many thanks for the excellent article and website. I've installed and pointed to the .crt applying this to sub-domains (after reading your other post) and now on the base domain the browser is throwing up cannot connect pages.
Any ideas?
Error info
/var/log/apache2/error.log
)? SamRE: Error info
Thanks for the response, it appears the firewall was not forwarding the 443 port, router swapped and the ssl is working better, still a few niggles but webmin has broken the apache2 install and throwing up loads of old config files, I'm just re-installing a new raspbian as we speak :)
Created CAcert first time round!
Hi Sam,
Again can I applaud your dedication with these great tutorials. I managed to create a CAcert on the first time of asking and it immediately picked it up on my K9 app...excellent!
Regards,
Jo
How to use Pagekite with this tutorial
Hello,
Thank you for the excellent tutorial. One barrier I'm having is that I'm using the pagekite server to tunnel my PI to a public IP address and I do not have an actual personal domain & email address to receive the required emails.
Will I need to actually register a domain name and map the pagekite address to the domain to get the email and setup the CAcert? Any workaround for this?
Thanks again
why use pagekite at all?
Expired certificate
Thanks for the great tutorials I setup a Pi Mailserver using your tuts and she is working perfectly!!!
However, I'm now being told when I open Outlook (2010) that the CAcert certificate is "expired".
I've checked with CAcert and it's valid and current.
Is there an update process I have to do on the Pi or is there something else I'm missing?
Thanks for the help!!! (I wouldn't have been able to do this without your tutorials!!!)
Could the message be about
Ca Cert Woes
Hi Sam,
more feedback on Ca Cert troubles.
I used an on-line cert checker at DigiCert.com and the result is. .
DNS resolves timxjr1300.ddns.net to {not saying]
HTTP Server Header: Apache/2.2.22 (Debian)
SSL certificate
Common Name = timxjr1300.ddns.net
Subject Alternative Names = timxjr1300.ddns.net
Issuer = CA Cert Signing Authority
Serial Number = 119E19
SHA1 Thumbprint = B811771D3C854C121B9909FD8EB597644F1EDDFC
Key Length = 4096
Signature algorithm = SHA256 + RSA (excellent)
Secure Renegotiation: Supported
SSL Certificate has not been revoked
OCSP Staple: Not Enabled
OCSP Origin: Not Enabled
CRL Status: Not Enabled
SSL Certificate expiration
The certificate expires July 9, 2016 (178 days from today)
Certificate Name matches timxjr1300.ddns.net
Subject timxjr1300.ddns.net
Valid from 11/Jan/2016 to 09/Jul/2016
Issuer CA Cert Signing Authority
SSL Certificate is not trusted
The certificate is not signed by a trusted authority (checking against Mozilla's root store). If you bought the certificate from a trusted authority, you probably just need to install one or more Intermediate certificates. Contact your certificate provider for assistance doing this for your server platform.
So it appears that CA Cert is not trusted?
I must be missing something.
Regards
Tim
cacert not in trusted root store
Certificate not trusted
At first thanks for the great tutorial!
After completing the tutorial I decided to try openssl to connect to my mail server. This ended up with this error:
openssl s_client -connect localhost:465 -quiet
depth=0 CN = [domain]
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = [domain]
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = [domain]
verify error:num=21:unable to verify the first certificate
verify return:1
220 [domain] ESMTP Postfix (Debian/GNU)
Changing localhost for my domain name also ended up with the same error. Do you have any idea what I did wrong? I changed the dovecot/postfix config files to the right certificates and restarted both services.
(sorry if this is a repost my internet browser keeps timing out when submitting this form)
Thanks in advance!
You need to use the CApath
Mail Server
Sam,
One more question. Suppose a message is sent to the RPi mailer as wronguser@xxx.co.uk is there a way in which this message could be routed to, say, postmaster@xxx.co.uk? My current ISP mail system will route all such wrongly identified mail to admin@<my ISP mail address>. In the past this has proved helpful. (On one occasion, it exposed a robot which was sending marketing mail to random 5 letter users at my ISP mail server. This activity was reported to the ICO and led to a potential prosecution of the company involved....)
John
possible, but I wouldn't recommend it
Certificate error
Thanks for all the tutorials that you have done.
I have followed the email server setup and was able to send and receive email but when i tried to add a certificate from CAcert. I'm getting failed connections.
Here is whats the error is in mail.log:
May 4 13:09:46 raspberrypi dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=192.168.0.26, lip=192.168.1.150, TLS handshaking: SSL_accept() failed: error:14094416:SSL r$
May 4 13:09:46 raspberrypi postfix/smtps/smtpd[1305]: connect from unknown[192.168.0.26]
May 4 13:09:47 raspberrypi postfix/smtps/smtpd[1305]: SSL_accept error from unknown[192.168.0.26]: 0
May 4 13:09:47 raspberrypi postfix/smtps/smtpd[1305]: warning: TLS library problem: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown:s3_pkt.c:1294:SSL alert number 46:
May 4 13:09:47 raspberrypi postfix/smtps/smtpd[1305]: lost connection after CONNECT from unknown[192.168.0.26]
May 4 13:09:47 raspberrypi postfix/smtps/smtpd[1305]: disconnect from unknown[192.168.0.26]
I'm not sure where i went wrong. Any help would be much appreciated.
Server timed out
When I go to the CAcert site and put all my information in the site gives me this message:
Email Address given was invalid, or a test connection couldn't be made to your server, or the server rejected the email address as invalid
Failed to make a connection to the mail server
Also when I try to send out or receive messages in the Thunderbird my server times out. Not but I think I missing something, any ideas?
-Cassie
anything in the logs?
logs
I input tail -f /var/log/mail.log and this what it gave me:
Jun 23 23:46:44 Ajax dovecot: master: Warning: Killed with signal 15 (by pid=192 5 uid=0 code=kill)
Jun 23 23:46:44 Ajax dovecot: master: Dovecot v2.2.13 starting up for imap (core dumps disabled)
Jun 23 23:55:43 Ajax postfix/master[1680]: terminating on signal 15
Jun 23 23:55:44 Ajax postfix/master[2137]: daemon started -- version 2.11.3, con figuration /etc/postfix
Jun 23 23:55:54 Ajax dovecot: master: Warning: Killed with signal 15 (by pid=215 8 uid=0 code=kill)
Jun 23 23:55:54 Ajax dovecot: master: Dovecot v2.2.13 starting up for imap (core dumps disabled)
Jun 23 23:57:10 Ajax postfix/master[2137]: reload -- version 2.11.3, configurati on /etc/postfix
Jun 23 23:58:12 Ajax postfix/master[2137]: reload -- version 2.11.3, configurati on /etc/postfix
Jun 21 23:17:20 Ajax dovecot: master: Dovecot v2.2.13 starting up for imap (core dumps disabled)
Jun 21 23:17:23 Ajax postfix/master[1700]: daemon started -- version 2.11.3, con figuration /etc/postfix
I then input tail /var/log/err.log
un 21 22:57:34 Ajax dovecot: imap(test1234): Error: stat(/home/test1234/Maildir/tmp) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +x perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0700)
Jun 21 23:07:34 Ajax dovecot: imap(test1234): Error: stat(/home/test1234/Maildir/tmp) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +x perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0700)
Jun 21 23:17:34 Ajax dovecot: imap(test1234): Error: stat(/home/test1234/Maildir/tmp) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +x perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0700)
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: stat(/home/test1234/Maildir/subscriptions) failed: Permission denied
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: opendir(/home/test1234/Maildir) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +r perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0755)
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: opendir(/home/test1234/Maildir) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +r perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0755)
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: opendir(/home/test1234/Maildir) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +r perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0755)
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: opendir(/home/test1234/Maildir) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +r perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0755)
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: stat(/home/test1234/Maildir/.Trash) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +x perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0700)
Jun 23 23:23:13 Ajax dovecot: imap(test1234): Error: stat(/home/test1234/Maildir/tmp) failed: Permission denied (euid=1002(test1234) egid=1002(test1234) missing +x perm: /home/test1234/Maildir, dir owned by 1003:1003 mode=0700)
what do you think?
-Cassie
Maildir permissions & ownership
permissions
total 12
drwx------ 2 1003 1003 4096 May 28 02:46 cur
drwx------ 2 1003 1003 4096 May 28 02:46 new
drwx------ 2 1003 1003 4096 May 28 02:46 tmp
Change ownership to test1234
I need help please
Hi, sam
I got as far as the Submitting the CSR to CAcert step when i ran into trouble. I got the following error when i submitted the form
Email Address given was invalid, or a test connection couldn't be made to your server, or the server rejected the email address as invalid
Failed to make a connection to the mail server.
I used the email address(not testmail) from your raspberry pi email server tutorial, for which I am submitting for the cert. Am I getting the error because i don't have the cert for the address yet, or could there be a problem with my email server? Should I just use a different email address in the CaCert form?
Add new comment