Das hier wird mal wieder einer dieser etwas längeren Artikel, da es einiges zu beschreiben gibt. Es geht hierbei um die technische Einrichtung von einem Reverse Proxy, der eine dahinter liegende Webseite / Applikation schützen soll. Dies könnte entweder eine Webseite sein, oder aber auch ein Mailserver. Da bei vielen Firmen z.B. ein Microsoft Exchange zum Einsatz kommt, möchte man diesen nicht direkt ans Internet setzen, sondern nochmal eine zusätzliche Absicherung dazwischen setzen. Hierbei bestehen dann mehrere Möglichkeiten: Die Anfragen werden angenommen und nach intern weitergeleitet, es gibt keine weitere Authentifizierung oder Absicherung. Dies wird bei Exchange z.B. häufig gemacht, um nicht den IIS als Webserver direkt im Internet stehen zu haben, sondern um einen apache oder nginx zu verwenden.
Neben einer Weiterleitung nach intern gibt es noch die Möglichkeit, die Verbindung nur mit vertrauenswürdigen Geräten aufzubauen. Dieses Vertrauen kann mit einem Client-Zertifikat erreicht werden, was sich auf dem Endgerät befindet. Das Verfahren wird als „Certificate Based Authentication“, kurz „CBA“, bezeichnet.
Meldet sich ein Client oder Endgerät am Reverse Proxy, fragt dieses das Zertifikat ab. Ist kein Zertifikat vorhanden oder der Anwender wählt kein Zertifikat aus, wird die Kommunikation unterbunden und der Benutzer erhält eine Meldung, dass die Kommunikation abgewiesen wurde. Dies sorgt dann dafür, dass nur noch ausgewählte Geräte die Verbindung aufbauen können.
Ein paar Worte vorne weg
Ich nutze die Technik primär dazu, Exchange Server hinter einem Reverse Proxy zu verstecken und nur Geräte mit einem Client-Zertifikat zu erlauben. Hört sich erstmal super an, dass niemand ohne validiertes Zertifikat zum Exchange Server kommt (von extern versteht sich). Hierbei muss allerdings klar sein, dass nicht jede Art von Zugriff mittels Client-Zertifikat möglich ist. Nutze ich eine Mail-Applikation auf meinem Handy, die keine Zertifikate unterstützt, kann ich diese nicht an den Exchange Server anbinden. Weiterhin funktioniert nicht jedes Mailprogramm mittels Zertifikat-basierter Authentifizierung, Outlook z.B. nicht, was bei vielen Firmen ein Unding ist, also wird es nicht durchgesetzt. Man sollte sich vorher Gedanken und Tests machen, ob dies eine valide Lösung ist, oder ob es danach mehr Probleme als vorher gibt.
Zusätzlich sollte auch gesagt werden, dass dies natürlich nicht dafür sorgt, dass mein Mailserver zu 100% geschützt ist und niemand an das System ran kommt. Es erschwert den Zugriff für ungewünschte Personen, und man zeigt sich „nach außen“ hin mit einem nginx / apache2 Webserver, was viele automatische Scanner schon weiterziehen lässt, da man nicht mit einem IIS antwortet. Das alleine ist gut, aber natürlich kein 100%iger Schutz, es ist halt ein Baustein im Sicherheitskonzept.
Installation Reverse Proxy für einen Microsoft Exchange Server 2019
Debian Linux
Beginnen wir mit der Installation von unserem Reverse Proxy. Ich verwende dazu ein Debian Linux in der aktuellen Version 11 (Bullseye). Wir machen eine gewöhnliche Grundinstallation ohne Desktop und ohne sonstigen Schnick-Schnack, lediglich die Basis-Tools sowie SSH für einen Remote-Zugriff werden installiert. Wie man so eine Installation durchführt sollte klar sein, ich beschreibe das an dieser Stelle nicht nochmal in der Tiefe.
Nginx
Für den Reverse Proxy nutzen wir nginx. Die Installation geschieht ganz einfach mittels
apt install nginx -y
Nach der Installation aktivieren wir den Autostart des Webservers
systemctl enable nginx
Danach muss noch das Filter-Addon installiert werden, dieses wird für Exchange benötigt. Zusätzlich installieren wir noch den certbot und das nginx-Plugin dafür.
apt install -y libnginx-mod-http-headers-more-filter certbot python3-certbot-nginx
nginx-Konfiguration für Exchange
Im ersten Schritt deaktivieren wir die Standard-Konfiguration
unlink /etc/nginx/sites-enabled/default
Nun können wir unsere eigene, persönliche Konfiguration erstellen.
nano /etc/nginx/sites-available/mail.zueschen.eu.conf
Diese Konfiguration enthält die folgenden Einstellungen:
server {
listen 80;
server_name mail.zueschen.eu;
location / {
proxy_pass https://10.10.10.10;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Die beiden fett markierten Einträge müssen angepasst werden auf den Namen, unter dem der Server erreichbar ist, und dann auf die IP-Adresse, die intern für die Kommunikation verwendet wird.
Nun kann die Konfiguration aktiviert werden, und der Webserver kann einmal neu geladen werden.
ln -s /etc/nginx/sites-available/mail.zueschen.eu.conf /etc/nginx/sites-enabled/mail.zueschen.eu.conf
systemctl restart nginx
Anfragen von Let’s Encrypt Zertifikat
Im nächsten Schritt können wir unser öffentliches Zertifikat anfragen. Die geht am einfachsten per Wizard über den Befehl
certbot
Wir müssen im Wizard die notwendigen Einstellungen tätigen, und wenn alles korrekt eingestellt ist, haben wir nach kurzer Zeit unser Zertifikat. Mit diesem können wir dann unsere Webserver-Konfiguration erweitern.
Die vollständige Konfiguration ohne CBA
Wir müssen nun die Konfiguration von unserem Mailserver erweitern und alle notwendigen Einstellungen hinzufügen und konfigurieren. Meine Konfiguration sieht wie folgt aus:
server {
server_name mail.zueschen.eu;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mail.zueschen.eu/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mail.zueschen.eu/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / { proxy_pass https://10.10.10.10; }
location /owa { proxy_pass https://10.10.10.10/owa; }
location /exchange { proxy_pass https://10.10.10.10/exchange; }
location /ews { proxy_pass https://10.10.10.10/ews; }
location /mapi { proxy_pass https://10.10.10.10/mapi; }
location /rpc { proxy_pass https://10.10.10.10/rpc; }
location /oab { proxy_pass https://10.10.10.10/oab; }
location /autodiscover { proxy_pass https://10.10.10.10/autodiscover; }
location /Microsoft-Server-ActiveSync { proxy_pass https://10.10.10.10/Microsoft-Server-ActiveSync; }
location /ecp { proxy_pass https://10.10.10.10/ecp; }
proxy_pass_request_headers on;
proxy_pass_header Date;
proxy_pass_header Server;
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-Forwarded-Proto https;
more_set_input_headers 'Authorization: $http_authorization';
proxy_set_header Accept-Encoding "";
more_set_headers -s 401 'WWW-Authenticate: Basic realm="mail.zueschen.eu"';
proxy_read_timeout 3600;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
access_log /var/log/nginx/mail.zueschen.eu-access.log;
error_log /var/log/nginx/mail.zueschen.eu-error.log;
}
server {
if ($host = mail.zueschen.eu) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name mail.zueschen.eu;
return 404; # managed by Certbot
}
Ist die Konfiguration angepasst, müssen wir den nginx einmal neu laden.
systemctl reload nginx
Mit dieser Konfiguration können wir nun schon testen, ob wir uns erfolgreich mit dem Mailserver per OWA oder ECP verbinden können. Klappt was nicht, ist das access- bzw das error-Log sehr hilfreich.
Die Einbindung von Zertifikaten
Wenn wir nun im nächsten Schritt eine CBA einrichten wollen, werden hierfür natürlich Zertifikate benötigt. Diese lassen sich über mehrere Möglichkeiten erstellen, naheliegend wäre eine evtl. schon vorhandenen Windows PKI. Ich habe in meinem Fall XCA verwendet, eine eigenständige Software die unter Windows, Linux oder Mac verfügbar ist. Die Projektseite, auf der man auch den Download der Software beziehen kann, ist unter https://hohnstaedt.de/xca/ zu finden.
Nach der sehr schnell durchgeführten Installation muss als erstes eine neue Datenbank erstellt werden, in die alle Zertifikate, Vorlagen und Einstellungen usw. gespeichert werden.
Vergeben Sie ein langes und sicheres Kennwort, um die Zertifikate zu schützen.
Info: Der Erstellen-Assistent heißt auch „öffnen“, nicht verwirren lassen von der Namensgebung. Die Datei wird erstellt und kann danach genutzt werden.
Die Erstellung von Vorlagen
Als nächstes benötigen wir Vorlagen. Diese Vorlagen funktionieren als, wie der Name schon sagt, Vorlagen für die Zertifikate, die wir später ausstellen.
Überlegen Sie sich gut, wie lange Sie ihre Zertifikate ausstellen. Ein Client-Zertifikat, was 20 Jahre läuft, ist zwar problemlos in dieser Zeit nutzbar, sollte es aber mal abhanden kommen, und Sie haben keine Sperrliste, ist dieses Zertifikat bis zu 20 Jahre lang gültig. Bei einem Zwischenfall müssten Sie also im schlimmsten Fall ein komplett neues CA-Zertifikat erzeugen, und ALLE Zertifikate austauschen. Das kann sehr unschön werden und sehr viel Zeit beanspruchen. Gehen Sie lieber hin und führen eine vernünftige und realistische Dauer ein, inkl. einem Prozess wie sie die Zertifikate austauschen können. Dieser Prozess passiert am besten automatisch, so dass Sie sich nur noch um die Ausstellung bzw. die Verlängerung kümmern müssen.
Wir erstellen insgesamt drei Vorlagen, von denen wir später zwei nutzen (CA und Client). Damit man aber auch direkt Server-Zertifikate erstellen kann, und der Weg der gleiche ist, machen wir das hier direkt mit. Wer nur den absolut minimalen Weg gehen möchte, erstellt die Vorlagen 1 und 3:
- Eine CA-Vorlage
Hiermit erstellen wir unser Master-Zertifikat unserer eigenen PKI. Dieses Zertifikat signiert dann im weiteren Verlauf unsere Server- und Client-Zertifikate - Ein Server-Zertifikat
Diese Vorlage wird verwendet, um ein Zertifikat für einen Server zu erstellen. In unserem konkreten Szenario nicht verwendet, aber ich dachte ich beschreib es einfach mal mit. Nutzbar z.B. für Webserver und Webseiten. - Ein Client-Zertifikat
Mit dieser Vorlage können wir für unsere Benutzer und Geräte Zertifikate ausstellen
Beginnen wir mit der CA-Vorlage. In der Software wechseln wir in den Reiter Vorlagen und wählen rechts den Menüpunkt Neue Vorlage.
Im Fenster, was dann auftaucht, wählen wir [default] CA aus. Damit werden die wichtigsten Werte und Einstellungen schon mal für uns gesetzt.
In unserer Vorlage müssen wir nun einige Daten eintragen, und ein paar Einstellungen vornehmen. Im ersten Reiter Inhaber tragen wir ein, von wem diese CA ist und wie sie intern genannt wird.
Wichtig: Lassen Sie an dieser Stelle den commonName frei!
Die Einstellungen im zweiten Reiter Erweiterungen können Sie so belassen wie voreingestellt, falls Sie mit mehr oder weniger als 10 Jahren Laufzeit arbeiten möchten, können Sie hier die Gültigkeitsdauer anpassen.
Der Reiter Schlüsselverwendung sieht bei mir wie folgt aus:
Netscape hat die folgenden Einstellungen. Hier wäre es noch möglich, eine CRL (eine Sperrliste für Zertifikate) anzugeben oder weitere Einstellungen zu setzen. In meiner Demo-Umgebung ist dies nicht gesetzt, bei dem Einsatz in einer produktiven Umgebung sollte aber sehr stark darüber nachgedacht werden, ob man nicht eine Sperrliste einführt und somit die Chance hat, Zertifikate zurückzuziehen.
Der Reiter Erweitert zeigt noch weitere Einstellungen, hier habe ich keine direkten Änderungen vorgenommen.
Damit haben wir nun eine neue Vorlage für eine CA erzeugt. Dieses Spiel müssen wir noch zwei Mal wiederholen: Einmal mit der Vorlage [default] TLS_client und einmal mit [default] TLS_server.
TLS_server Vorlage
Hier werden im ersten Reiter Inhaber wieder die Daten benötigt, commonName wird erneut freigelassen. Alle weiteren Einstellungen in den folgenden Screenshots:
Damit haben wir die Vorlage für ein Server-Zertifikat erstellt. Weiter geht es mit der Vorlage für die Client-Zertifikate, der Vorgang ist identisch, außer das die Einstellungen leicht abweichen.
TLS_client Vorlage
Wir erstellen eine neue Vorlage, und wählen hier [default] TLS_client als Vorlage aus. Unter Inhaber wieder die Daten eintragen, commonName frei lassen, und dann noch die weiteren Einstellungen prüfen / anpassen.
Die Erstellung der privaten Schlüssel
Im nächsten Schritt erstellen wir nun private Schlüssel. Dies geschieht über den ersten Reiter Privater Schlüssel. Hier wählen wir Neuer Schlüssel, benennen diesen Schlüssel, und wählen dann Schlüsseltyp und Schlüssellänge aus. Ich empfehle hier einen Schlüssel mit 4096 bit und RSA als Schlüsseltyp.
Mehr müssen wir nicht machen, der Schlüssel wird erzeugt und steht dann zur Verfügung.
Die Erstellung der Zertifikate
Weiter geht es nun mit der Erzeugung unserer eigentlichen Zertifikate. Hierzu wechseln wir in den Reiter Zertifikate und wählen rechts den Menüpunkt Neues Zertifikat.
Im ersten Reiter Herkunft können wir unten unsere Vorlage auswählen, die wir vorher erzeugt haben. Haben wir diese ausgewählt, können wir alle getätigten Einstellungen in der Vorlage anwenden mit einem Klick auf Alles übernehmen.
Dadurch haben wir nun unter Inhaber bereits die Daten eingetragen, die in der Vorlage enthalten sind. An dieser Stelle können wir nun unter commonName den Namen unserer CA wählen und eintragen. Unter diesem Namen ist das Zertifikat dann z.B. in unserem Client in der Liste der vertrauenswürdigen Stammzertifizierungsstellen sichtbar. Der Interne Name kann ebenfalls gesetzt werden ganz oben in dem Bereich. Im unteren Bereich müssen wir nun unseren vorher erzeugten Schlüssel auswählen. Falls noch kein Schlüssel erzeugt wurde, kann dies direkt nachgeholt werden mit dem Button Erstelle einen neuen Schlüssel.
Die weiteren Einstellungen sollten eigentlich durch unsere Vorlage schon so gesetzt sein, wie wir sie haben möchten. Dazu zählt z.B. unter Erweiterungen der Typ des Zertifikats, dies muss Zertifikats Authorität sein.
Sind alle Einstellungen korrekt, kann das Zertifikat mit einem Klick auf OK erzeugt werden, und taucht direkt danach auf in der Übersicht der verfügbaren Zertifikate.
Das Zertifikat kann nun auch exportiert und zur weiteren Verwendung verteilt werden. Hier zeigt die Software eine ihrer großen Stärken, nämlich der einfache und gute Export in das gewünschte Format der Wahl.
Für unseren Reverse Proxy benötigen wir das Zertifikat als .pem Datei.
Das eigentliche Client-Zertifikat
Nun können wir ein Zertifikat für ein Endgerät erstellen, welches sich am ReverseProxy anmelden soll. Hierzu wählen wir wieder die Option Neues Zertifikat. Wichtig ist hier jetzt, dass wir dieses Zertifikat von unserer CA signieren lassen, und nicht selber signieren.
Unter Inhaber können wir nun einen Internen Namen sowie den commonName angeben. Ich habe in diesem Fall den Namen der Person eingetragen, welche das Zertifikat bekommt. So ist eine gute Zuordnung möglich, und man weiß genau wem dieses Zertifikat gehört. Alternativ wäre natürlich auch die Personalnummer, der Anmeldename oder sonstige Merkmale möglich. Wichtig ist, dass eine Zuordnung möglich ist, und nicht jeder das gleiche Zertifikat nutzt (Thema Sperrliste, Verlust usw.).
Damit das Zertifikat mit einem eigenen, privaten Schlüssel ausgestattet wird, muss ein neuer Schlüssel erzeugt werden, da wir aktuell noch keinen Schlüssel für diesen Benutzer haben. Das geschieht ganz einfach mit einem Klick auf Erstelle einen neuen Schlüssel. Ich behalte in meinem Fall den Namen bei, und passe die Schlüssellänge auf 4096 an.
Nach der Bestätigung, dass ein neuer Schlüssel erstellt wurde, wird er automatisch, wie im vorderen Screenshot sichtbar, eingebunden. Die weiteren Einstellungen sollten (durch die Vorlage) passen. Nach einem Klick auf OK wird das Zertifikat erzeugt und ist (unterhalb der CA) sichtbar.
Die Erweiterung von nginx zur Erzwingung von Client-Zertifikaten
Damit wir nun die Zertifikate nutzen und erzwingen können, müssen wir dies in die nginx Konfiguration einbringen. Dazu sind nur zwei weitere Zeilen notwendig:
# custom config
ssl_client_certificate /etc/nginx/certs/zueschen.eu-CA.pem;
ssl_verify_client on; # von off auf on gestellt
Speichert das CA-Zertifikat als .pem-Datei, ladet es auf euren Reverse Proxy Server hoch (ich habe es unter /etc/nginx/certs/ abgelegt), und bindet es in eure Konfiguration ein. Sobald die Konfiguration gespeichert wurde, und nginx die neue Konfiguration geladen hat (systemctl reload nginx), wird ein Client-Zertifikat fällig.
Ruft ihr jetzt an dieser Stelle die Webseite vom dahinter liegenden Exchange Server auf, erscheint die folgende Fehlermeldung:
Um der Webseite nun ein Client-Zertifikat anbieten zu können, muss das erzeugte Client-Zertifikat einmal als .pfx-Datei exportiert, und dann auf dem Client importiert werden. Das PFX-Format hat den Vorteil, dass der private Schlüssel enthalten ist, weiterhin ist die Datei mit einem Kennwort geschützt. Die schützt die Datei auf dem Transportweg, falls ihr sie Kollegen oder anderen Personen zur Verfügung stellen müsst.
Ist das Client-Zertifikat importiert, und die Webseite vom Exchange wird erneut aufgerufen (Seite schließen und neu öffnen, F5 bringt nix), meldet sich der Browser und fragt nach, welches Client-Zertifikat genutzt werden soll:
Bestätige ich das Zertifikat, erscheint die Login-Seite vom Exchange OWA Service.
Die Sperrliste mit in die nginx Konfiguration einarbeiten
Damit der nginx Server auch die Sperrliste abfragt, muss dies ebenfalls in der Konfiguration angegeben werden. Da man hier „nur“ eine Datei angeben kann, sollte man in diesem Fall die Sperrliste von der angegebenen Adresse per cron-Job runterladen, ablegen und dann in der Konfiguration angeben. Der entsprechende Parameter wäre ssl_crl: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_crl
Ausklammern von Unterseiten, die keine CBA erfordern
Sollten Unterseiten existieren, die nicht mittels Zertifikat aufrufbar sein müssen, ist dies ebenfalls möglich. Die Konfiguration hierfür hat mir ein Kumpel gerade geschickt, der auf diesen Artikel aufmerksam wurde, danke dafür 🙂
Weitere Einstellungen und Möglichkeiten
Nachdem diese Einstellungen gesetzt sind, ist der Mailserver durch den Reverse Proxy inkl. CBA geschützt. Man könnte an dieser Stelle jetzt noch diverse weitere Dinge machen, um die Sicherheit noch weiter zu erhöhen und die Anwendung etwas zu personalisieren. Diese Dinge wären unter anderem:
- Der nginx sollte weiter gehärtet werden, so dass er z.B. seine eigene Versionsnummer nicht mehr in der Fehlermeldung ausgibt.
- TLS sollte ausschließlich zum Einsatz kommen, hier sollten die alten und anfälligen Versionen 1.0 und 1.1 ausgeschlossen werden.
- Die Anzahl der gleichzeitigen Zugriffe pro IP-Adresse sollte evtl. limitiert werden, je nach Nutzung des Servers.
- Zugriffe von Bots könnten abgewiesen werden.
- Man könnte den Proxy noch um ModSecurity erweitern, ein Modul was eine Firewall mit in den Proxy einzieht und ungewollte Abfragen und Befehle unterbindet.
- HSTS könnte aktiviert werden.
- Die Fehlermeldung, wenn ein Client sich ohne ein Zertifikat anmeldet, könnte personalisiert werden. Auf der Seite könnten z.B. auch Kontaktinformationen angegeben werden, an wen man sich wenden muss, wenn es Probleme gibt. Oder halt auch nicht, je nach dem wie viele Anrufe und Mails ihr so haben möchtet 😉
- Grundsätzlich sollte das System aktuell und auf Stand gehalten werden. Hier sollte ein Automatismus implementiert werden, der alle x Stunden oder Tage Updates installiert.
- Das die Kiste gesichert werden sollte, steht sicherlich außer Frage. Macht das bitte auch, ihr wisst ja: Kein Backup – Kein Mitleid!
Das alles hier zu beschreiben sprengt den Rahmen, es gibt dazu einige gute Anleitungen im Netz, ich schaue mal ob ich nachgelagert das ein oder andere Thema hier nochmal auffasse und beschreibe.
Fazit
In diesem Artikel haben wir einen nginx Webserver auf einem Debian 11 System als Reverse Proxy für einen Exchange Server 2019 implementiert und eingerichtet. Wir haben Zertifikate eingerichtet und erstellt, mit denen eine Anmeldung an dem System mittels Client-Zertifikaten erzwungen wird.
Hi, das ist super lieb von dir! die Anleitung funktioniert bei mir nur für die OWA.
Outlook funktioniert leider nicht.
dort kommt immer eine Passwortabfrage.
hast du eine Idee?
wir haben die domain mail.firma.de als A Record als Webserver und autodiscover.firma.de als CNAME auf die Mail Subdomain im webhoster gelegt.
Gruß
Hallo Florian,
wie bereits in den Vorbemerkungen im Block „Ein paar Worte vorweg“ erwähnt, funktioniert die Anbindung von einem Outlook über den Reverseproxy mit CBA nicht, weil Outlook das nicht unterstützt. Eine Möglichkeit, dass zu umgehen, wäre die Nutzung von einem VPN auf dem Client mit Outlook.
Schönen Gruß
Jan