kerio_connect_header

Kerio Connect – Let’sEncrypt SSL mit Nginx als Reverse Proxy

Veröffentlicht von

Seitdem die Let’s Encrypt-Initiative die kostenlose Erstellung von SSL-Zertifikaten ermöglicht, lassen sich vergleichsweise einfach selbstsignierte Zertifikate austauschen, um beispielsweise Sicherheitswarnungen gängiger Browser verschwinden zu lassen und die Kommunikation mit eigenen Webseiten zu verschlüsseln.

Dies bietet sich auch für Kerio Connect und dessen Webmail-Client an. Da standardmäßig bereits Dienste von Kerio Connect auf den Ports aktiv sind, die auch vom Let’s Encrypt-Certbot zur Erstellung eines Zertifikats benötigt werden, ist die Implementierung nicht ganz trivial.

Um das alles auch noch relativ komfortabel und unabhängig definierten Ports zu machen, kann man den Webserver Nginx als Reverse Proxy vor Kerio Connect schalten.

Nginx als Reverse Proxy – Vorteile

Was macht den Aufbau mit Nginx nun komfortabler als eine direkte Verwendung des Let’s Encrypt-Certbots auf Ebene des Kerio Connect-Webservers?

In meinem Szenario soll Nginx einfach auf den HTTP(S)-Ports 80 und 443 alle ankommenden Anfragen annehmen und gemäß der eigenen Konfiguration weiterleiten. Dabei ist es völlig egal, auf welchen Ports andere Server, wie beispielsweise der Webserver von Kerio Connect, auf eingehende Anfragen warten.

Dadurch fällt das Forwarding dienstspezifischer Ports gänzlich weg. Port 80 und 443 müssen extern erreichbar sein und verweisen auf den Nginx-Server.

In Bezug auf Let’s Encrypt ergibt sich ein weiterer Vorteil: Die ausgestellten Zertifikate werden von Nginx verwaltet und an einen anfragenden Client ausgeliefert. Für Nginx gibt es ein angepasstes Certbot-Paket, das die einfache und automatisierte Erstellung von Let’s Encrypt- SSL-Zertifikaten ermöglicht, ohne dass vorher andere Serverdienste gestoppt werden müssten, welche die benötigten Ports blockieren.

CentOS 7.3 als Basis

Alle weiteren Erläuterungen beziehen sich auf meinen Systemaufbau, bestehend aus einem virtuellen Server mit CentOS 7.3 als Betriebssystem für Kerio Connect. Ein entsprechendes Paket ist bei Kerio im Downloadcenter verfügbar.

Ich gehe davon aus, dass Kerio Connect bereits auf dem System installiert ist. Dieser Vorgang ist auch denkbar einfach. Ein rpm-Befehl startet den Installer, der durch das Setup führt.

Schritt 1: Ports in Kerio Connect ändern

Da Port 80 und Port 443 vom Let’s Encrypt-Certbot zum Abrufen eines SSL-Zertifikats benötigt werden, dürfen keine Sockets durch andere Dienste auf diesen Ports bestehen. Standardmäßig lauschen hier HTTP und HTTPS des Kerio Connect Webmail-Dienstes und müssen daher im Admin-Webinterface auf (beliebige) andere Ports verlegt werden.

In meinem Fall schalte ich HTTP vollständig ab, weil ich den Webmail-Dienst ausschließlich über sicheres HTTP mit dem Let’s Encrypt-Zertifikat zur Verfügung stellen möchte.

kerio_connect_dienste
Übersicht der Kerio Connect-Dienste und Dienstports

Schritt 2: Nginx installieren

Sobald der Kerio Connect-Webserver auf einem anderen Dienstport als 80 bzw. 443 arbeitet, kann das Nginx-Paket für CentOS installiert werden.

sudo yum install nginx

Eine Standardkonfiguration wird automatisch vorgenommen, sodass der Webserver direkt per http antwortet. Das Nginx-Webroot ist an dieser Stelle unwichtig und wird nicht weiter konfiguriert. Nginx soll Dateien im Webroot nicht ausliefern, sondern ausschließlich als Proxy fungieren und Anfragen direkt weiterleiten.

Schritt 3: Paket certbot-nginx installieren

Unter CentOS gibt für Nginx ein angepasstes Certbot-Paket, das sich mit folgendem Befehl installieren lässt:

sudo yum install certbot-nginx

Schritt 4: Nginx-Konfiguration für Kerio Connect

Nach der Installation von Nginx und dem passenden Certbot-Paket, kann die Konfiguration des Nginx-Proxies vorgenommen werden, Eine entsprechende Konfigurationsdatei wird im Verzeichnis /etc/nginx/conf.d/ angelegt, das über die Nginx-Konfiguration inkludiert ist.

vim /etc/nginx/conf.d/reverseproxy.conf

Die Blöcke Server{} definieren grundsätzlich, auf welchem Dienstport welcher servername (Domain) zu erreichen und wo das Webroot zu finden ist.

In meinem Fall leitet Nginx durch die Einträge von Certbot alle HTTP-Anfragen an name1.domain.de direkt auf HTTPS um. Das Let’s Encrypt-Zertifikat für name1.domain.de wird an alle HTTPS-Anfragen ausgeliefert und diese Anfragen schließlich an den neu definierten Kerio Connect.Port weitergereicht.

ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;

server {
 listen 80;
 server_name name1.domain.de;
 server_name_in_redirect off;

# Redirect non-https traffic to https
 if ($scheme != "https") {
    return 301 https://$host$request_uri;
 } # managed by Certbot

}

server {
 add_header Strict-Transport-Security "max-age=0;";
 listen 443 ssl;
 server_name name1.domain.de;
 ssl on;
 ssl_certificate /etc/letsencrypt/live/name1.domain.de/fullchain.pem; # managed by Certbot
 ssl_certificate_key /etc/letsencrypt/live/name1.domain.de/privkey.pem; # managed by Certbot

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;
 proxy_connect_timeout 600;
 proxy_send_timeout 600;
 proxy_read_timeout 600;
 send_timeout 600;
 }
}

server {
listen 443 ssl;
 server_name name2.domain.de;
 ssl on;
 ssl_certificate /etc/letsencrypt/live/name2.domain.de/fullchain.pem; # managed by Certbot
 ssl_certificate_key /etc/letsencrypt/live/name2.domain.de/privkey.pem; # managed by Certbot

location / {
 proxy_pass https://192.178.5.7;
 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;
 }
}

Die Einträge zum SSL-Zertifikat in dieser Konfigurationsdatei werden durch Certbot selbst vorgenommen, wenn dieser mit dem Schalter –nginx ausgeführt wird.

sudo certbot --nginx -d name1.domain.de -d name2.domain.de

Weiter ist an meiner Konfiguration zu erkennen, dass neben der Proxykonfiguration für Kerio Connect eine weitere (externe) Umleitung einer weiteren Domain name2.domain.de auf Port 443 defininiert ist.

Dies ließe sich auch noch für eine beliebige Anzahl weiterer Hosts umsetzen, sodass eine zentrale Stelle für die Verwaltung von Let’s Encrypt SSL-Zertifikaten entsteht.

Dabei ist selbstverständlich zu beachten, dass die A-Einträge für alle behandelten Domains auf die IP-Adresse dieses Servers zeigen müssen.

Nach Abschluss dieser Einstellungen ist das Webmail-Webinterface von Kerio Connect per HTTPS erreichbar und weist das gültige Let’s Encrypt-Zertifikat aus.

kerio_ssl_webmail
Let’s Encrypt SSL-gesichertes Webmail-Interface

Wie konfiguriert, leitet Nginx außerdem alle HTTP-Anfragen auf HTTPS um.

Schritt 5: Vollständige Integration des SSL-Zertifikats in Kerio Connect

Zwar ist nun die Webmail-Komponente von Kerio Connect verschlüsselt erreichbar, jedoch verfügt Kerio Connect über weitere Dienst auf anderen Ports. Dazu zählen beispielsweise auch das Administrationsinterface auf Port 4040 sowie alle E-Mail-bezogenen Dienste wie IMAP(S) oder POP3(S).

Daher sollte das in den vorherigen Abschnitten erzeugte und in Nginx eingebundene SSL-Zertifikat auch in Kerio-Connect integriert werden. Über die Web-Administration ließe sich der Inhalt der Zertifikate nur manuell einfügen und in der Datei mailserver.cfg gibt es keine entsprechenden Parameter.

Es werden jedoch alle Zertifikate geladen, die sich im Kerio-Verzeichnis /opt/kerio/mailserver/sslcert/ befinden. Also ist es wohl die beste Methode hier einfach einen Symlink zu den von Let’s Encrypt gespeicherten Zertifikaten zu erzeugen.

ln -s /etc/letsencrypt/live/name1.domain.de/fullchain.pem /opt/kerio/mailserver/sslcert/mail.crt
ln -s /etc/letsencrypt/live/name2.domain.de/privkey.pem /opt/kerio/mailserver/sslcert/mail.key

Nach einem Neustart des Kerio Connect-Dienstes wird das Zertifikat auch in der Web-Administration gelistet und kann als Standard gesetzt werden. Somit werden auch andere SSL-gesicherte Dienste mit dem Let’s Encrypt-Zertifikat bereitgestellt.

kerio_connect_ssl_administration
Let’s Encrypt-SSL-Zertifikat im Kerio Connect-E-Mail-Server

Schritt 6: Automatische Erneuerung der SSL-Zertifikate

Let’s Encrypt-Zertifikate sind nur 90 Tage lang gültig und müssen dann aktiv erneuert werden. Um dies zu automatisieren, ist ein Eintrag in der crontab nötig.

sudo crontab -e

Im daraufhin geöffneten Editor trage ich beispielsweise ein, dass jeden Tag um 0:30 Uhr durch den Certbot geprüft werden soll, ob das SSL-Zertifikat erneuert werden muss.

30 0 * * * /usr/bin/certbot renew --quiet

Falls wir uns der maximalen Gültigkeitsdauer nähern, wird das Let’s Encrypt-Zertifikat auf dem Server erneuert.

8 Kommentare

  1. Hallo Sascha,

    ja, so etwas ähnliches hatte ich auch – einen 504 Gateway Timeout. Hast du auch folgende Parameter in dem Server-Block deiner nginx-Konfiguration? In der verlinkten Anleitung sind die Einstellungen nämlich nicht zu sehen:

    proxy_redirect off;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    send_timeout 600;
    proxy_http_version 1.1;

  2. Hi,

    ist besser aber noch nicht weg. Große Probleme macht noch das Versenden von Anhängen. Da macht der Proxy direkt zu. Hast Du da noch ein Setting was man optimieren kann?

    1. Hallo,
      was heißt denn „macht direkt zu“? Gibt es einen HTTP-Statuscode?
      Was steht ggf. in /var/log/nginx/error.log?

      Teste auch mal den Parameter client_max_body_size 25M; im Server-Block der nginx-Konfiguration.

  3. Hi,

    steht bei uns sogar auf 50M.

    Im Log taucht häufig :

    upstream timed out (110: Connection timed out) while reading response header from upstream,…. auf

  4. Hi,

    we were getting Nginx gateway timeouts during peak hours with more than 100 active Kerio Webmail users. The more users, the higher was the chance to get a timeout pop-up. As recommended in various blogs, we increased proxy_read_timeout to 3h and that worked for several months until recently. After updating Kerio Connect to 9.2.6 Patch 2, the pop-ups started appearing again. We’ve been able to solve the problem by decreasing LongPollTimeout from 600 to 100 (and later to 30) in mailserver.cfg, as recommended here:
    http://aplawrence.com/Forum/kerio-not-responding.html

    It is necessary to stop Kerio Connect (service kerio-connect stop) before editing mailserver.cfg.

  5. Hi,

    Disregard the above comment, we were completely wrong. Kerio Connect 9.2.6 introduced a limit for a number of simultaneous connections per IP, which is by default set to 100. Since we have hundreds of users and most of them work from the same building and from the same IP address, we quickly ran out of the limit for Webmail (aka HTTPS service). We missed the error messages in the logs, because they appeared under Logs > Security.

    The fix is as simple as changing MaxConnectionsIP for service-https in mailserver.cfg from 100 to any higher value of your liking. It is necessary to stop Kerio Connect before editing mailserver.cfg.

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.