I’ll show how to obtain a certificate with letsencrypt and how to add it Postfix and Dovecot. As a side effect it fixes mail-sending in Wordpress.
apt-get upgrade broke mail sending from Wordpress. The setup is similar to the one covered in Tutorial: Use personal gmail with @yourdomain.com, but basically, it’s like this: mails are sent using a local Postfix instance and Dovecot is used for SMTP authentication.
Investigating the mail log shed a little light on the cause:
Apr 4 14:51:32 garagehaven postfix/smtpd: SSL_accept error from localhost[127.0.0.1]: 0 Apr 4 14:51:32 garagehaven postfix/smtpd: warning: TLS library problem: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1262:SSL alert number 48:
Clearly the problem was related to SSL. To dig further, I created the following Wordpress mail sending test.
<?php require( dirname( __FILE__ ) . '/wp-blog-header.php' ); $message = 'test'; wp_mail( 'email@example.com', 'subject', 'message'); ?>
And ran it with hhvm.
$ hhvm mail-test.php Warning: SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /srv/www/garagehaven/wp-includes/class-smtp.php on line 344
The certificate can’t be verified, and some PHP code chokes. This is no surprise, because, shame on me, I used a self-signed certificate. Luckily, with letsencrypt.org we can now obtain a certificate. This is how to install it.
Obtaining a certificate with letsencrypt
Check out the letsencrypt tool from github
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
/opt/letsencrypt/letsencrypt-auto certonly -a webroot --webroot-path=/srv/www/garagehaven -d garagehaven.dk
Wait. Was that it? How did letsencrypt know that we are indeed on that domain. Easy, it added a file to the webroot. Fetched it and voila – a once so painful process eliminated.
Add certificate to Postfix and Dovecot
postconf 'smtpd_tls_key_file = /etc/letsencrypt/live/garagehaven.dk/privkey.pem' postconf 'smtpd_tls_cert_file = /etc/letsencrypt/live/garagehaven.dk/cert.pem' postconf 'smtpd_tls_CAfile = /etc/letsencrypt/live/garagehaven.dk/chain.pem'
ssl_cert = </etc/letsencrypt/live/garagehaven.dk/cert.pem ssl_key = </etc/letsencrypt/live/garagehaven.dk/privkey.pem
And reload the services
$ postfix reload $ dovecot reload
And Wordpress can now send mails again.
Update certificate automatically with CRON
The certificate times out after 90 days. Thus, it’s essential to automate updates. But, that’s easy with cron and letsencrypt.
$ crontab -e 1 3 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log 5 3 * * 1 /etc/init.d/postfix reload 10 3 * * 1 /usr/sbin/dovecot reload
Every monday at 3am, certificates are checked and renewed if stale.
No fiddling with openssl. No pasting signatures into a CA. No frustration. Just one simple command to rule them all. Letsencrypt people – you rock!