Creating a TLS encryption key and certificate

(If you are unfamiliar with the abbreviation “TLS“: it is the successor to SSL.)

The internet is the best invention since sliced bread but it has become an evil place more than ever. We are dealing with script kiddies, out-of-control secret services and organized crime on a large scale. It is completely out of the question to run any unencrypted services over the internet. I consider any password immediately wasted that went through the internet unencryptedly. So let us create an encryption key and a certificate for Postfix (SMTP), Dovecot (IMAP/POP3) and Roundcube (Webmail/HTTPS).

Caveat: do not use different certificates for Postfix and Dovecot. At least the MacOS mail client will refuse your connection with confusing error messages.

There are two factors that make an encryption certificate secure:

(a) – Cryptographical security

The mathematical idea of one-way functions that make it easy to decrypt data if you know the key – but to make it virtually impossible trying to break the decryption without that knowledge. For a couple of years the SHA1 algorithm was famous but thanks to Edward Snowden’s disclosures we assume that it can be broken too easily. So everyone is advised to use at least SHA256 (which is part of the SHA2 algorithm). Also RSA signatures should not be 1024 bits long any more but rather 4096 bits. Creating secure keys and certificates is relatively easy – we have tools for that.

(b) – Trust

The idea of trusting a certificate. What’s the point if the certificate is mathematically good but you don’t know who you are communicating with. You may communicate very securely with the wrong counterpart (called man-in-the-middle). That’s not what you want. (See also my article on creating your own certificate authority.)

So you have to decide whether to buy a certificate or to create one yourself. In comparison:

Type Advantages Disadvantages Application
Self-signed No costs.
Quickly created.
Users will get a warning message about an untrusted certificate. They can accept the certificate manually but you should tell them the certificate’s fingerprint so they can verify it. Private mail server for yourself and friends who don’t mind ignoring the warning message about an unverified identity.
Self-signed with own PKI No costs.
You can create further certificates that your users will consider trusted if they have your root certificate installed. The easy-rsa package is a good start.
Takes 15 minutes longer for you. Requires that all users install your root certificate as trusted on their computers. This may make sense only if you can automatically distribute the certificate in a corporate environment. Private mail server for yourself and friends who don’t mind installing your root certificate once. Or a corporate mail server where you can automatically deploy your root certificate on all client workstations.
No-cost certificate from LetsEncrypt No costs.
Users will likely not get a warning because most software trusts LetsEncrypt.
Certificates are only valid for 90 days. Depending on your network it may be a hassle and cause a downtime to renew a certificate. Public mail server that does not need sugar coating called “extended validation”.
Paid certificate Users will not get a warning. Expensive (50€-200€ per year).
Probably a lengthy registration process.
You support the certificate mafia.
You don’t improve the communication security in any way.
For anyone who has too much money.

Note: Whichever method you use – always create the key on your own server. Never trust a key that has been created by anyone else. It appears simpler because you can omit one step. But the other party now knows your secret key and could in theory intercept your encrypted traffic. I will describe how to do that properly in any of the following sections. Just choose your option and follow the instructions.

Option 1: Self-signed

The simplest option. Just run this command on your server and you have a valid all-purpose certificate that is valid for the next ten years:

openssl req -newkey rsa:4096 -nodes -sha512 -x509 -days 3650 -nodes -out /etc/ssl/certs/mailserver.pem -keyout /etc/ssl/private/mailserver.pem

You will be asked for several pieces of information. Enter whatever you like. The only important field is the “Common Name” that must contain the fully-qualified host name that you want your server to be known on the internet. Fully-qualified means host + domain.

Make sure that the secret key is only accessible by the ‘root’ user:

chmod go= /etc/ssl/private/mailserver.pem

Option 2: Self-signed with own PKI

This option is a bit better than using a simple self-signed certificate. But your users or customers need to install your root certificate manually to establish a trust relationship to your PKI in both their browsers and their email programs.

I suggest you install the “easy-rsa” package and read the documentation:

zless /usr/share/doc/easy-rsa/README-2.0.gz

If there is enough interest in this topic I will elaborate on managing your own certificate authority using easy-rsa.

Option 3: No-cost certificate from StartSSL

This is almost always the best option. It doesn’t cost you money and will give you a basic trustworthy certificate that most browsers and email clients will accept.

Create a 4096 bit key file:

openssl genrsa -out /etc/ssl/private/mailserver.pem 4096

Create a certificate signing request (CSR) file from that key:

openssl req -new -key /etc/ssl/private/mailserver.pem -out /etc/ssl/certs/mailserver.csr

You will be asked for several pieces of information. Enter whatever you like. The only important field is the “Common Name” that must contain the fully-qualified host name that you want your server to be known on the internet.

Now go to StartSSL and sign up for an account. First use the “Validation Wizard” to validate your email address first. Then use the validation wizard again to validate the domain you want to use for your email server.

Next use the “Certificates Wizard” to create a “Web Server SSL/TLS certificate”. Choose your email domain, paste the contents of the CSR file (/etc/ssl/certs/mailserver.csr) you created previously and receive your certificate file. Move that file to /etc/ssl/certs/mailserver.pem and set its permissions properly:

chmod go= /etc/ssl/private/mailserver.pem

In addition to the Apache configuration described below please ensure to install the chaining certificate, too. A sample configuration section is available in the StartSSL documentation.

Option 4: Paid certificate

Are you sure you want to do it? Then just search the web for “SSL certificate” and throw your money at any certificate authority.

The key and the certificate request are created as described above in Option 3.

Use the CSR file to request a certificate from the SSL authority. Move that certificate file to /etc/ssl/certs/mailserver.pem and set its permissions properly:

chmod go= /etc/ssl/private/mailserver.pem

Increasing TLS security

By the way – you should forbid communication using potentially insecure encryption methods. There is a way to attack the encryption by pretending that you do not support modern encryption techniques and thus rather want to use SSL version 2 or 3. This is called the POODLE attack. So you better run

postconf 'smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3'

to forbid communication using pre-Snowden protocols that may be abused to attack you. (Thanks for the hint, Guillaume.)

30 thoughts on “Creating a TLS encryption key and certificate

  • 2015-11-03 at 12:15
    Permalink

    You have wrong paths to mailserver.pem in your last two commands.
    You should NOT use this:
    chmod go= /etc/ssl/private/mailserver.pem

    You should use this:
    chmod go= /etc/ssl/certs/mailserver.pem

    Reply
    • 2015-11-03 at 12:58
      Permalink

      Why? The certificate is the “public key” so to say. It does not need to be protected. It contains the data that is sent first when a secure connection is opened anyway. The private key however (located in /etc/ssl/private) must not be read by anyone except the mail server. Anyone who would have the private key could decrypt your otherwise secure traffic.

      Reply
      • 2016-04-27 at 10:24
        Permalink

        I think the confusion is caused by the sentences above those two commands. They state “Move that certificate file to /etc/ssl/certs/mailserver.pem and set its permissions properly:”. The command that follows it then refers to the keyfile in /etc/ssl/private, instead of the certificate file that you just moved to /etc/ssl/certs. So the command is correct, but the sentence above it is confusing.

        Great guide by the way!

        Reply
  • 2015-11-16 at 09:56
    Permalink

    Thanks for the great tutorial, I was wondering, if I wanted to host mail for several domains, ie: example1.com, example2.org etc would a single ssl cert for example1.com work for example2.org and others?

    Also, how would email be handled at a domain level? mx.example1.com and mx.example2.org point to the same ip?

    Reply
    • 2015-11-16 at 10:05
      Permalink

      You could in theory create a certificate for several domains. But I haven’t seen a certificate authority that would sign such a certificate. When dealing with web servers you can get several certificates and thanks to modern SNI (server name indication) the web server can figure out which certificate it should use. But that won’t work for secure IMAP, POP3 and SMTP communication.

      If several MX servers point to the same IP that’s no problem. If one server sends email to another then nowadays it will accept any certificate and initiate an encrypted connection.

      Reply
  • 2015-11-17 at 20:22
    Permalink

    By the way, you should add smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3 in your main.cf to avoir the Poodle SSLv3 vulnerability

    Reply
  • 2015-11-26 at 18:42
    Permalink

    Hi,

    Just to mention that letsencrypt.org is issuing free certs that are validated, a good alternative to the commercial things and to the self signed.

    W.

    Reply
  • 2015-12-03 at 11:43
    Permalink

    Hi,

    First of all thanks for the amazing tutorial. I am stuck trying to install the chain certificate. On StartSSL it is not so clear and I don’t have any experience setting this up.

    Keith

    Reply
    • 2015-12-07 at 10:21
      Permalink

      HI Keith. When StartSSL offers you to download (copy/paste) the actual certificate then there are links to the CA and the Intermedia certificates. Download both. And then put these two plus your own certificate all into one “mailserver.crt” file. That will do it.

      Reply
      • 2016-08-18 at 18:00
        Permalink

        Hi Christoph, Thank you for this wonderful guide. I am confused slightly because I believe the StartSSL website has changed. I am trying to properly install certificates. When I receive my certificates from StartSSL I get a downloaded file called “mydomain.com.zip” inside that file are three more .zip files: ApacheServer.zip, IISServer.zip, NginxServer.zip and OtherServer.zip. Inside each of those four zip files are: ApacheServer.zip: 1_root_bundle.crt, 2_mydomain.com.crt, IISServer.zip: 1_Intermediate.crt, 2_mydomain.com.crt, NginxServer.zip: 1_mydomain.com_bundle.crt and OtherServer.zip: 1_Intermediate.crt, 2_mydomain.com.crt, root.crt.

        What do I put where? I currently have /etc/ssl/certs/mailserver.csr and /etc/ssl/private/mailserver.pem. I am confused about your instructions as well as the comments as they seem to conflict. I would also like to know how and where I should put the intermediate certificate.
        Thank you for your tutorial!

        Reply
  • 2015-12-11 at 22:12
    Permalink

    Hey Christoph,

    I’ve read through the entire tutorial and I’ve got to say, this is astounding! I do want to leave a bit of extra info on installing the chaining cert though. I feel like this will be a massive roadblock for a lot of readers. So hopefully this saves some time…

    First,

    # cd /etc/ssl/private

    Next, we’re going to obtain the Class 1 Intermediate Server CA by typing,

    # wget https://www.startssl.com/certs/sub.class1.server.ca.pem

    To combine your certificate with the newly obtained “sub.class1.server.ca.pem” certificate, you’re going to use the cat command as follows (assuming YOUR certificate is still in /etc/ssl/certs)

    # cat /etc/ssl/certs/mailserver.pem sub.class1.server.ca.pem > ssl-chain-mail-yourdomain.pem

    This should place the new chaining certificate in your /etc/ssl/private directory.

    Let me know if you disagree with this.

    Cheers

    Reply
  • 2015-12-15 at 15:41
    Permalink

    A very good alternative way is to use a letsencrypt certificate. It’s free of cost, trusted and very easy to install on a modern Debian Server (automatic Installation via cert Client). In the meantime the letsencrypt Project is in Status Open Beta. It worked fine for me. Have a look at https://letsencrypt.org/ if u are interested.
    Regards Peter

    Reply
  • 2015-12-23 at 10:11
    Permalink

    Hey could anyobody please tell me what/where to find the “certificate wizard” is?
    thanx

    Reply
  • 2015-12-23 at 13:43
    Permalink

    StartSSL.com have launched a new website. The old certificate wizard is no longer there.

    You need to click on “Start Now for Free SSL Certificate” and then “Sign Up” to validate who you are.

    But be warned, the site at the moment is at a crawl.

    Reply
  • 2016-01-01 at 18:49
    Permalink

    For certificates: you can get a totally legitimate free SSL certificate from the newly started project (funded by EFF and Mozilla) called Let’s Encrypt: https://letsencrypt.org/.

    Reply
    • 2016-01-10 at 14:47
      Permalink

      +1

      Works like a charm over here! Worth mentioning.

      Reply
    • 2016-03-04 at 11:13
      Permalink

      I think this is worth including in this or the next tutorial. The letsencrypt packages are now in debian-backports, so the setup is actually quite easy.

      Reply
  • 2016-02-03 at 15:43
    Permalink

    I Went for option three, but not ran into problems.
    § Dns records need to be set.
    § A running mailserver needs to be online on the domain you need to validate (accordning to godaddy).

    Therefore, I suggest that you move at least option three and four until the mail server is online.
    Regards

    Reply
    • 2016-02-03 at 15:48
      Permalink

      People looking for an alternative might also want to look at Let’s Encrypt.

      Reply
  • 2016-03-09 at 10:14
    Permalink

    I am trying to use option 3 (startssl), but it seems that something changed in their system (or i made a big mistake).
    I didnt got a pem-file, i got a zip with many crt-files and now i dont understand how to install this (which file did i have to use for replace my /etc/ssl/private/mailserver.pem) ?

    Thanks in advance
    Jan

    Reply
    • 2016-03-10 at 10:17
      Permalink

      It seems i got it:

      unzip File from StartSSL
      unzip Apache file and got 2 files – used the second (2_myhost.mydomain.somewhere)

      wget https://startssl.com/certs/sca.server1.crt # its PEM Version
      cat 2_myhost.mydomain.somewhere sca.server1.crt > /etc/ssl/certs/mailserver.pem

      to test it u have to get the root-ca file from startssl
      wget https://startssl.com/certs/ca.crt
      mv ca.crt /etc/ssl/certs/ca.pem
      openssl s_client -connect localhost:25 -starttls smtp -CAfile /etc/ssl/certs/ca.pem

      or use the existing one:
      openssl s_client -connect localhost:25 -starttls smtp -CAfile /etc/ssl/certs/StartCom_Certification_Authority.pem

      I hope thats the correct way – any advices?

      Reply
      • 2017-01-01 at 22:05
        Permalink

        Thanks for the reminder and the pointers. As much as I liked StartCom I have replaced the recommendation by LetsEncrypt. Also I consider LetsEncrypt pretty much a mess of scripts and a hassle of downtimes every 90 days. 🙁

        Reply
  • 2016-03-16 at 10:26
    Permalink

    Made another cert for my webserver. After i compared the files, i noticed:
    U can use both files from Apache folder (maybe one of the other files are ready to use, but this way you may better understand the cert things):

    cat 2_myhost.mydomain.somewhere 1_root_bundle.crt > /etc/ssl/certs/mailserver.pem

    still learning every day 🙂

    Reply
    • 2016-04-27 at 13:56
      Permalink

      In case anyone else is confused about the meaning of the certificate files that you receive from startssl and why these can be concatenated: I found this page very informative: http://theheat.dk/blog/?p=534. A brief summary: it is advised that you not only provide your own certificate, but also the intermediate certificate. If you don’t provide the latter, most browsers will download it themselves, but it is not best practice.

      In our scenario we need both the 1_root_bundle.crt and the 2_myhost.mydomain.somewhere and they can indeed be combined into a single PEM file as per instructions of Jan above here. But you can also keep them in two separate files. I have renamed the 1_root_bundle.crt file to mailserver_intermediate.pem. In this case you need to enable the following in the /etc/apache2/sites-enabled/default-ssl.conf file:

      SSLCertificateFile /etc/ssl/certs/mailserver.pem
      SSLCertificateKeyFile /etc/ssl/private/mailserver.pem
      SSLCertificateChainFile /etc/ssl/certs/mailserver_intermediate.pem

      In case some other component needs the concatenated pem file it can’t hurt to keep this one as well. Mine is called mailserver_with_chain.pem.

      Reply
  • 2016-08-31 at 16:29
    Permalink

    Hey Christoph,
    Thanks very much for your great tutorial, which is very special because it describes the procedures considering the person on the other side. Which is rather rare and denoting great sensitivity and a real educational spirit!

    With regard to the question SSL instead, I would like to suggest this project: “https://github.com/lukas2511/letsencrypt.sh”.

    What do you think about this? Could be useful to integrate your tutorial with this resource?

    Thank you

    Davide

    Reply
  • 2016-09-20 at 19:59
    Permalink

    Perhaps you could update the guide to include Let’s Encrypt as an option? I’ve been using one of their certificates without issue (for mail).

    Reply
  • 2017-01-05 at 21:18
    Permalink

    I was a big fan of StartSSL until Google stopped trusting them. For ubuntu 16.10 with apache2 working (http:), LetsEncrypt setup took 3 commands:

    # Get the certification bot:
    sudo apt-get install python-certbot-apache
    # Run the bot, answer questions, it even configures apache:
    certbot –apache
    # Load the updated apache site config file:
    sudo service apache2 restart

    After that, browser refresh returns https:// – that’s all it took!
    For background, see https://letsencrypt.org/getting-started/
    which should guide you to: https://certbot.eff.org/
    Pick your configuration and go.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close