SSL Certificate Signing with CAcert for Raspberry Pi, Ubuntu & Debian

CAcert logo




Before we start: a quick note about filename extensions




  • .csr for the certificate signing request (CSR)
  • .crt for the signed certificate file
  • .key for the key file


Generate your certificate






  • 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)
  • Email Address (the contact address for your administrator e.g.




Install the CAcert root certificate




cd ~





sudo c_rehash /etc/ssl/certs



To install to Android, follow this tutorial of mine.

Required Email Address





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






cat <filename for the CSR>.csr

...and click submit.


sudo nano <path to your cert>.crt



Certificate File Locations



Permissions & Ownership


This command will set it to be owned by root:

sudo chown root:root /etc/ssl/private/samhobbs.key


sudo chmod 600 /etc/ssl/private/samhobbs.key




sudo chown root:root /etc/ssl/certs/samhobbs.crt


sudo chmod 644 /etc/ssl/certs/samhobbs.crt

Some common SSL cert configuration parameters: Apache, Postfix, Dovecot




SSLEngine on
SSLCertificateFile /etc/ssl/certs/samhobbs.crt
SSLCertificateKeyFile /etc/ssl/private/samhobbs.key

Then reload Apache:

sudo service apache2 reload




...and reload Postfix:

sudo service postfix reload



ssl_cert = </etc/ssl/certs/samhobbs.crt
ssl_key = </etc/ssl/private/samhobbs.key


Reload dovecot:

sudo service dovecot reload




Thanks for the really helpful guide.

Sorry to ask a silly question - but when you copy and paste the certificate content - do you include (or not) the "BEGIN CERTIFICATE" and END CERTIFICATE" text?

Also when I do the final step to restart apache I get

Tried the fix below but still get the same error.

Yep those statements are part of the certificate.

That error about the server name is unrelated to SSL, you can fix it by setting the ServerName directive anywhere in your main Apache config (i.e. not in a virtualhost).

There are a few ways to do this, depending on whether you're using Ubuntu/Debian/Raspbian.

Basically, you need ServerName in your main config somewhere (not in a VirtualHost).

In newer versions of Ubuntu, you can create separate config files and then enable them with sudo a2enconf foo where foo.conf is the name of a config file in /etc/apache2/conf-available/, which will symlink it into /etc/apache2/conf-enabled/ so that it's read when Apache starts up. You don't have to do it this way, though.

In Debian/Raspbian (or Ubuntu, if you don't like the suggestion above), just put the statement in your main Apache config file (/etc/apache2/apache2.conf).

...and reload/restart.


Can you elaborate on this - What you probably need to do is create your own root cert for your local domain and use it to sign a cert for the Pi

I have tornado running on my pi and I have a webpage which uses the microphone on my pc - browser is chrome. I need to get the pi to serve the page up as https so that I don't have to keep enabling the mic each time. The web page will only be accessed by my pc and it only has an ip address and is set up as an access point through wifi.



Just to confirm:

  • your computer runs windows?
  • you access the web page using an IP address for the pi, which is static

It's not that difficult to generate your own root cert, but you might just want to make a security exception for the snakeoil (default) cert for that IP address, particularly if you'll always be using the same browser on the same machine... much less hassle!


Thanks I seem to have got it working now with the snake oil cert. Just it comes up with an annoying message when I first go to the page and the https is crossed out. Is there a way to avoid that - by using frames or something? Otherwise I can live with it. To confirm the setup is exactly as you say.

Every browser is different and I'm struggling to remember Chrome... in FF, when I confirm a permanent security exception for my brother's site which is hosted on my server and therefore uses the same SSL cert (with common name i.e. a mismatch) I don't see any difference in the padlock icon when I visit the site again to a normal accepted cert. If I click the padlock it tells me I added a permanent exception.... I wonder if this kind of behaviour is possible in Chrome.


My Dad just pointed out to me that if the Tornado thing you're running (what is it?) is loading content from external sources then Chrome will warn you about displaying insecure content. Is that the message that you were getting?

If that is the reason you're getting the message then there isn't an easy fix, short of using the Pi to download the external content and store it locally, and then link to it from there... but all that depends on what tornado actually does and how it works.


Hi Sam,

Thanks for the great tutorials. Really the best I've found on the internet.

One thing to consider is the use of a virtual alias table instead of creating user aliases. I did this as I have multiple domains but all mapped to one email and didn't want to use up all those usernames. It's explained well here (2nd answer):→-userex

All the best,


Thank you, that's high praise indeed! As for the link, I didn't know about either of those two ways of doing things (luser_relay or the virtual way - I never considered virtual users because it's just me using my server) so thank you very much for that. The link is going in my bookmarks!


Thank you so much, Sam, for both the SSL certificate and the email server tutorials.

Both were (relatively) painless to follow on my pi. In fact all the problems I had turned out to be fat fingered ones.

Hehe, I know the feeling. Few things are more frustrating than a typo that takes 30minutes to debug!

I'm glad you found them useful, thanks for commenting :)


Hello Sam,
thanks a lot for the dedication and care that you put into achieving these useful pages.
These pages has helped me a lot and has reduced my learning curve on postfix very well
Well done Sam

Thanks for the feedback! It's great to hear the tutorials have been useful to you.



Thanks for this guide, it proved to be well done. Everything went smoothly on my pi and everything seems to happen like your guide says. The only thing is now that i'm done, no page from my pi server seem to be https. I am checking from outside the network too...

Anything you can suggest to help troubleshoot this?



Some things to check:

  • Do you have a rewrite rule rewriting to HTTPS?
  • Do you have an enabled virtualhost config file for HTTPS?
  • Is mod_rewrite enabled? (sudo a2enmod rewrite, sudo service apache2 reload)
  • Is port 443 forwarded from your router to your pi? If you manually type https in the url, does it connect?


Hi Sam.
I've done everything you write here but after sending an email to a Gmail account I got my message in spam box.
How do I fix this (if possible)?

I think they must have changed something recently because a few people have been asking that!

Try setting up a PTR record if your ISP will let you, and an SPF record too. I think Gmail is marking email as spam if you don't have either of these.


Do you think this will do?


I'm not finding any PTR info.

Your ISP controls your PTR record, you have to change it with them not your DNS provider, many won't let you change it. Since it's tied to the IP address you'll have to have a static IP to do this.

Here's my SPF record as an example:

E.g. it applies to the root domain (@), it's input as a text record, and the text v=spf1 mx a ~all means use SPF version 1, allow messages submitted from IP addresses with a matching MX or DNS A record, softfail the rest (i.e. don't bounce messages, but the 3rd party server can decide what to do - normally mark as spam). Old versions had the PTR record in there too along with MX and A but messages sent from a host with a matching PTR record are accepted by default, so that's a depreciated option.


Thanks for the great tutorial , I really like the idea of owning my emails, owning all my data and not have it read by un-invited guests!
my question is that if I setup postfix mail server on my domain and update mx records of my domain. do i still need the ssl cert for email so that other external mail-servers can accept my email and I can accept their email. I doubt that they will accept snakeoil cert from my mx email server. Thanks again!

Most servers use something like "TLS=may" for server to server communication, which means they'll encrypt if they can and send the email it in platoon text if they can't (port 25 can do both, it always starts as plain and the STARTTLS command is used to convert to a TLS connection if necessary).

Depending on configuration, it sometimes checks that the common names on the certs match and sometimes doesn't bother - any certificate will allow the creation of a secure connection, the signing part is just about making sure the server is who it says it is!

The snakeoil cert won't have a matching common name, so it's a good idea to create your own. If you don't you'll still probably get all your email but it might be sent in plain text.

The reality is, so many SMTP servers use self-signed certificates that you break interoperability if you require TLS and do strict certificate checking... so most don't.


Hi Sam,

Thank you for your tutorials! I'm using the new Raspberry pi2 and it is excellent to run mailserver (finally working :)), host website and time lapse the emoto rice experiment with my webcam.

I followed your tutorial the third now and keep ending up with this error: sec_error_unknown_issuer
It seems the browser does not find/recognise the issuer: CAcert

Thanks again, great site you are hosting.
Best regards,

Did you install the CAcert root certificate into the operating system on each computer? Firefox has its own certificate store so you have to do that separately.


Hi Sam,

I have downloaded the CAcert windows package from:

Now the certificate is signed and valid. It is only a pity that you have to install the certificate on every computer you want to use SSL. So for a random visitor on the website this is not something you can ask.

Thank you for your help. Keep up with your much appreciated work.

Best regards,

That's true, this tutorial is more about securing services you run for yourself (like webmail) than securing a SSL-only public site.

If you decide to get a commercial cert, check out this tutorial of mine, which will help you set it up.


I have my www site hosted by a private company. At my home, I use my raspberry pi for mail and owncloud. Am I correct in assuming that I will have to make two certs without a wild card for my mail and owncloud, in other words and

Many thanks for your numerous tutorials.


You could just create a single wildcard certificate and use that for mail and ownCloud (I'm assuming you have a commercial cert for www?). I don't think CAcert will refuse to sign a wildcard for you just because a certificate already exists for part of the domain hosted elsewhere - you're still in control of the domain.



Add new comment