Now with even more awesomesauce.

This is an updated version of my original post.

As Let's Encrypt is probably the best thing happening to the internet for the last decade or two, I wanted to use the certificates with a Kerio Connect installation at a customer. The software documentation advises you to copy and paste the certificate information via their admin web interface. Let's Encrypt certificates expire every 90 days, so that's just not an option for a lazy (read: productive, smart) system administrator. The instance I set this up on is running on Debian Jessie and performed flawless so far. Here's how you do it.

Turn off HTTP

Stop the HTTP service if it is running. Set it to start manually so it won't activate itself again on restart. Change the HTTPS service port to 4483 in the admin panel. The setup won't work otherwise because Certbot needs ports 80 and 443 to verify the domain and get the certificate. If you want to renew the certificates automatically, this is essential.

Install Nginx

Since we don't want to end up doing things manually, and also be able to use standard web ports, we need to set up a reverse proxy in front of Kerio Connect. This is an established practice for all kinds of web applications. It enables us to let the certificate process run without interaction — with the added benefit of being able to host other services and websites on the same server, should we want to.

First, we need to create a web root.

mkdir -p /var/www/mail
chown www-data:www-data /var/www/mail

Then we install nginx and the ssl-cert package, so we have easy access to a self-signed SSL certificate.

apt-get install nginx ssl-cert

Create a file called /etc/nginx/sites-available/kerio-connect.conf with the following content:

server {
    listen      80;
    server_name mail.example.com;
    server_name_in_redirect off;
    rewrite     ^ https://$server_name$request_uri? permanent;
}

server {
    listen      443 ssl;
    server_name mail.example.com;

    ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    location /.well-known {
        alias /var/www/mail/.well-known;
    }

    location / {
        proxy_pass       https://localhost:8843;
        proxy_set_header Host                 $host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Remote-Port        $remote_port;
        proxy_set_header X-Forwarded-Proto    $scheme;
        proxy_redirect  off;
    }
}

Link the file to make it an active site.

ln -s /etc/nginx/sites-available/kerio-connect.conf /etc/nginx/sites-enabled/kerio-connect.conf

Check if the configuration is correct.

nginx -t

If there are no errors, restart Nginx.

systemctl restart nginx.service
Get Certbot
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

Run it once without any parameters to check for dependencies.

./certbot-auto
Create the Certificate

Here, we set a webroot for Certbot to put the test files in so it won't need to open up the ports 80 and 443, which would fail as they are now in use by Nginx.

./certbot-auto certonly --webroot -w /var/www/mail -d mail.example.com

If you're running this the first time, you'll need to enter your email address for emergency usage like revoking a certificate. This only needs to be done once.

Congratulations, you now have a valid SSL certificate on your server.

Actually Using the Certificate

Edit /etc/nginx/sites-available/kerio-connect.conf and change

ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

to the location of our real certificate

ssl_certificate     /etc/letsencrypt/live/mail.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;

Restart Nginx.

To make renewal easy for Kerio Connect, just link the created certificate and key to the appropriate folder inside the Kerio Connect hierarchy.

ln -s /etc/letsencrypt/live/mail.example.com/fullchain.pem /opt/kerio/mailserver/sslcert/mail.crt
ln -s /etc/letsencrypt/live/mail.example.com/privkey.pem /opt/kerio/mailserver/sslcert/mail.key

Now open the admin panel, select Configuration > SSL Certificates and see your certificate appear. Select it and set as active.

That's it.

Renewal

Just run:

./certbot-auto renew

Since we want to automate renewal, set up a cronjob to run periodically. If the certificate is close to expiring, it will be renewed automatically, otherwise it will be kept until the next run.

First copy Certbot to a convenient location. I recommend /usr/local/bin.

cp certbot-auto /usr/local/bin/

Services need to be restarted after a successful renewal to pick up the new certificate. Create a script /root/certbot-post-hook.sh with the following content:

#!/bin/sh
systemctl restart nginx.service
systemctl restart kerio-connect.service

Make it executable and secure it.

chmod 500 /root/certbot-post-hook.sh
chown root:root /root/certbot-post-hook.sh

Create a cronjob file at /etc/cron.d/certbot:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 3 * * * root perl -e 'sleep int(rand(3600))' && certbot-auto -q renew --post-hook "/root/certbot-post-hook.sh"

This entry will run once a day at 3 am as root, sleep for a random number of minutes and run Certbot. The --post-hook parameter is run only when the certificate was in fact replaced, effectively restarting Nginx and Kerio Connect only when needed. The Certbot website recommends running the renewal command two times a day. However, in a production setting, restarting a mail server process as heavy as that Java behemoth Kerio Connect during work hours is often not feasible. Adjust the timing as needed. More than two times a day is overkill and won't make your certificate renewal more reliable.

Conclusion

If you're still running an unsecured mail server, now is the time to change that. It will cost you about 30 minutes and you probably will never have to worry about it again.

Food for Thought

Do yourself a favor and check out mailcow for a more lightweight, more scalable, way more flexible and seriously more performant open source alterative. It leverages the best components for the job and combined with a webmail frontend like RainLoop even looks better. For full groupware functionality, consider SOGo instead of Roundcube when installing. Sure, you'll need to dig into Postfix, Dovecot and the glue holding it together. In the long run you'll be happy you did. Because you will have freed yourself from having to pay for every mailbox over and over again every year, just to receive critical security updates, all the while throwing ever more resources at Kerio so it will continue to run smoothly. Better donate 25% of your current yearly bill to those open source projects. You save, they win.

Here's an idea: set it up as a cheap VPS for you and your friends/trusted colleagues. Test it thoroughly and work out the kinks. Read, learn, research, peruse log files, break it, repair it – be a nerd. I bet you'll like it.

As a system administrator within a small to medium business setting with lots of Outlook clients, you may want to hold off though. Arguably, Kerio Connect works in such a setting and you shouldn't add a possible pain point execs could grill you over. If something breaks, it's Kerio's fault, not yours. The same reason I suppose many companies still employ Microsoft software: execs know it and if it breaks, they can shout at a Microsoft representative, not the IT guy.

Next Post Previous Post