# Configure TLS support in postfix using CAcert certs [UPDATE]

## budee

I have revised the guide, this is v2.01, changelog in my post.

I was pulling my hair out trying to make TLS encryption to work in postfix. I was trying to follow the instructions in http://www.gentoo.org/doc/en/virt-mail-howto.xml but i got errors in log like:

```
Mar 15 07:12:30 simone postfix/smtpd[27385]: warning: cannot get certificate from file /etc/postfix/newcert.pem

Mar 15 07:12:30 simone postfix/smtpd[27385]: warning: TLS library problem: 27385:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:642:Expecting: CERTIFICATE:

Mar 15 07:12:30 simone postfix/smtpd[27385]: warning: TLS library problem: 27385:error:140DC009:SSL routines:SSL_CTX_use_certificate_chain_file:PEM lib:ssl_rsa.c:767:

Mar 15 07:12:30 simone postfix/smtpd[27385]: cannot load RSA certificate and key data

```

```
Mar 15 16:49:27 simone postfix/smtpd[12837]: initializing the server-side TLS engine

Mar 15 16:49:27 simone postfix/smtpd[12837]: warning: cannot get private key from file /etc/postfix/newreq.pem

Mar 15 16:49:27 simone postfix/smtpd[12837]: warning: TLS library problem: 12837:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:642:Expecting: ANY PRIVATE KEY:

Mar 15 16:49:27 simone postfix/smtpd[12837]: warning: TLS library problem: 12837:error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib:ssl_rsa.c:709:

Mar 15 16:49:27 simone postfix/smtpd[12837]: cannot load RSA certificate and key data

```

when using netcat to connect to smtp port i always got:

```
$ nc localhost 25

220 mail.domain.org ESMTP Postfix

EHLO domain.org

250-mail.domain.org

250-PIPELINING

250-SIZE 10240000

250-VRFY

250-ETRN

250-STARTTLS

250 8BITMIME

STARTTLS

454 TLS not available due to local problem

```

Then i finally found out how to do it:

First you have to decide which domain you are making the certificate for. If you own a domain (call it domain.org), you will be making the certificate for *.domain.org, this way it will be valid for everything under your domain. You will need access to one of the emails root@ hostmaster@ postmaster@ admin@ or webmaster@ at the domain you are registering (from now on i will refer to it as DOMAIN.ORG).

I tought much about where to put certificates, then i guessed /etc/ssl/private directory could be a good place for them, so work in that directory. Then create a private key and a certificate signing request. The latter you'll send to CAcert for signing (replace DOMAIN.ORG with your domain):

```
cd /etc/ssl/private

openssl req -nodes -new -keyout DOMAIN.ORG.key -out DOMAIN.ORG.csr

```

The questions should be straightforward, only when asked for "Common Name (eg, YOUR name):" enter *.domain.org. Dont make too much hassle filling out the other attributes, CAcert.org only keeps the CN attribute in the signed certificate until you have enough points with them. Leave the password empty.

Now you have 2 files, the DOMAIN.ORG.key is the secret private key, you should keep that in a way others cant read it! The DOMAIN.ORG.csr is the certificate signing request, you can think of it as an unsigned public key.

Now register at CAcert, check your mailbox, and activate your account.

Then add your domain to your account, check your mail again. You will need to paste the contents of DOMAIN.ORG.csr for signing here.

If everything goes smoothly you should have your signed public certificate displayed. Copypaste it into a new file DOMAIN.ORG.crt (you will receive the certificate in email too and you can always view your public keys in the CAcert.org web interface after logging in).

Now you should secure your private certificate so nobody else can read them (i also make my certificates immutable here):

```
chmod 400 DOMAIN.ORG.key

chattr +i DOMAIN.ORG.*
```

For simplicity i made a link to the already installed CAcert.org root certificate from this directory (you need to have the app-misc/ca-certificates package installed):

```
ln -s ../../../usr/share/ca-certificates/cacert.org/root.crt /etc/ssl/private/cacert.org
```

Now you are almost ready. Only have to setup postfix to use your shiny new certificate in main.cf:

```
nano -w /etc/postfix/main.cf:

### Transport Layer Security ###

# Server side TLS

smtpd_use_tls = yes

smtpd_tls_ask_ccert = yes

smtpd_tls_received_header = yes

smtpd_tls_key_file = /etc/ssl/private/DOMAIN.ORG.key

smtpd_tls_cert_file = /etc/ssl/private/DOMAIN.ORG.crt

smtpd_tls_CAfile = /etc/ssl/private/cacert.crt

smtpd_tls_CApath = /etc/ssl/certs

# Client side TLS

smtp_use_tls = yes

smtp_tls_key_file = /etc/ssl/private/DOMAIN.ORG.key

smtp_tls_cert_file = /etc/ssl/private/DOMAIN.ORG.crt

smtp_tls_CAfile = /etc/ssl/private/cacert.crt

# Misc TLS

smtp_tls_loglevel = 1

smtpd_tls_loglevel = 1

smtp_tls_session_cache_database = btree:/etc/postfix/smtp_tls_session_cache

smtp_tls_session_cache_timeout = 3600s

smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_tls_session_cache

smtpd_tls_session_cache_timeout = 3600s

tls_random_source = dev:/dev/urandom

```

Finally restart postfix (maybe a reload is enough?):

```
/etc/init.d/postfix restart
```

You can test if its working correctly (you will need to type in the lines EHLO and STARTTLS):

```
$ nc localhost 25

220 mail.domain.org ESMTP Postfix

EHLO domain.org

250-mail.domain.org

250-PIPELINING

250-SIZE 10240000

250-VRFY

250-ETRN

250-STARTTLS

250 8BITMIME

STARTTLS

220 Ready to start TLS
```

Of course you can use these certificates for other purposes. I am using them for pop3s, imaps, https and ldaps too.

Courier IMAP and POP3 servers

First, you need the net-mail/courier-imap package. Second, courier expects both the public and the private key in one file.

```
cd /etc/ssl/private

cat DOMAIN.ORG.key DOMAIN.ORG.crt > DOMAIN.ORG.pem

chmod 400 DOMAIN.ORG.pem

chattr +i DOMAIN.ORG.pem
```

 */etc/courier-imap/imapd-ssl wrote:*   

> IMAPDSSLSTART=YES
> 
> IMAPDSTARTTLS=YES
> 
> IMAP_TLS_REQUIRED=1
> ...

 The same way you can configure pop3s too in /etc/courier-imap/pop3d-ssl.

Apache webserver

```
ln -s ../../ssl/private/DOMAIN.ORG.crt /etc/apache2/ssl/DOMAIN.ORG.crt

ln -s ../../ssl/private/DOMAIN.ORG.key /etc/apache2/ssl/DOMAIN.ORG.key
```

 */etc/apache2/modules.d/41_mod_ssl.default-vhost.conf wrote:*   

> SSLCertificateFile conf/ssl/DOMAIN.ORG.crt
> 
> SSLCertificateKeyFile conf/ssl/DOMAIN.ORG.key
> 
> SSLCACertificatePath /etc/ssl/certs

 (The conf dir is linked from the apache working dir in /usr/lib/apache2 to /etc/apache2.)

OpenLDAP

After these, OpenLDAP is easy: */etc/openldap/slapd.conf wrote:*   

> TLSCertificateFile /etc/ssl/private/DOMAIN.ORG.crt
> 
> TLSCertificateKeyFile /etc/ssl/private/DOMAIN.ORG.key
> 
> TLSCACertificatePath /etc/ssl/certs

 Make sure you dont have broken symlinks in /etc/ssl/certs. If you have, delete them and run c_rehash. Also, because the slapd daemon runs as with his own uid/gid you need to make the private key accessible to him. For example:

```
chown .ldap /etc/ssl/private/DOMAIN.ORG.key

chmod g=r /etc/ssl/private/DOMAIN.ORG.key
```

Hope this guide helps somebody to make it working more smoothly than it was for me.

Have a nice day, bud

References:

http://www.postfix.org/TLS_README.html

http://www.gentoo.org/doc/en/virt-mail-howto.xml

http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/doc/conf.html

https://wiki.slugbug.org.uk/Postfix_TLS

http://www.cacert.org/help.php?id=6Last edited by budee on Sat Jun 02, 2007 9:37 pm; edited 6 times in total

----------

## X-Drum

nice post mate!

now my troubles with TLS+Postfix+CaCert.org are gone:

```

[...]

postfix/smtpd[22867]: warning: need an RSA or DSA certificate/key pair

[...]

```

my main problem was the "Client/Server side TLS" section mess,

i had smtp_tls_* but not smtpd_tls_*

----------

## bluni

I never got any email responses when signing up online with CAcert, tying a comcast, gmail, and yahoo addresses. Is there anything I can do now? I have the same problem with the STARTTLS response.

Thanks,

Brian

----------

## fudge

Great post budee.

Worked like a dream and confirmed using wireshark.

Fudge

----------

## danielrm26

Awesome, this worked for me too. (October 23, 2006)

----------

## SATRAP

Worked for me too  :Very Happy:  ! Thanks !

----------

## lodder_

i have tryed this but i get 

```
warning: cannot get private key from file 
```

pls help me out

----------

## BigBaaadBob

Can you use these certs for IMAP and POP using courier-imap?

----------

## nobspangle

 *BigBaaadBob wrote:*   

> Can you use these certs for IMAP and POP using courier-imap?

 

You can but you will get a warning telling you that the fqdn does not match the common name on the cert.

budee is wrong in his assumption that you can use a certificate for domain.org for any subdomain of domain.org (e.g. mail.domain.org)

The reason it works with postfix is that email doesn't care about the common name of the certificate.

You can request a wildcard certificate for *.domain.org but the legitimacy of these certs is questionable. If your server is called mail.domain.org you should request that as your common name. Don't forget CA cert will assign you several certs.

I like the idea of CA cert but for me it was less use than a self signed cert as I could make the self cert last as long as I wanted where as the CA cert is only for 6 months. I can't see any browsers taking the CA root on board so the whole project is fairly pointless, which is a shame.

----------

## BigBaaadBob

Well, there is always Startcom which is free.

Anyway, if I have a cert that I generated the request for by doing this:

```
 openssl req -new -key ssl.key -out ssl.csr
```

, what do I do to the cert to make it work with courier-imap?

Thanks!

----------

## budee

Changes in v2.0:

Now using *.domain.org in certificates CN

Made clear which file is which key

Not downloading the CAcert.org public key, because its installed with ca-certificates

Do not copy certificates to postfix directory

Add Courier IMAP and POP3 configuration

Add Apache configuration

Add OpenLDAP configuration

In v2.01:

Added some LDAP specific info

----------

## senduran

I followed this guide and everything worked as I hoped: now users must use ssl and tls login to connect and send mail to the other local users or the world.

However, I also managed to kill dead all incoming emails from the world to my users. I don't even see attempts at incoming email in my server logs.

So now I'm suddenly aware I have absolutely no idea how incoming email even works. (I also followed the virt-mail-howto.xml guide initially.)

Do I have to have port 25 open to accept email from the world?

How do I allow connections from the world (ie. no username or password) for incoming mail, but require secure password-protected connections to send mail out?

----------

## senduran

Following myself up, yes port 25 has to be open. Seemingly from some other guide I had this in my main.cf:

```

smtpd_client_restrictions = permit_sasl_authenticated, reject

smtpd_recipient_restrictions =

        permit_sasl_authenticated,

        permit_mynetworks,

        reject_unauth_destination

```

It was the smtpd_client_restrictions that killed my incoming email. With it commented out, all is well. But is the smtpd_recipient_restrictions stuff enough to prevent the world from sending emails from my server? Or is something else needed?

----------

