Zuhause und in vielen KMUs dürfte die Situation wohl ähnlich sein: Man besitzt einen Internetanschluss mit einer festen oder einer dynamischen IP, der per DynDNS-Dienst über einen Domainnamen erreichbar ist. Durch Portforwarding im Router kann man einzelne Geräte (z.B. Webserver) ins öffentliche Netz bringen, jeden Port jedoch nur einmal benutzen. Man müsste also für zwei Webserver zwei unterschiedliche Ports verwenden und diese beim Aufruf auch so mit angeben. Durch einen Reverse-Proxy kann man jedoch kurze sprechende Adressen verwenden, um die verschiedene Server im internen Netz per Subdomain erreichbar zu machen. In etwa so:
- blog.indibit.de -> 192.168.236.12 (WordPress auf Server 1)
- wiki.indibit.de -> 192.168.236.23 (Mediawiki auf Server 2)
Beide Server sind über den Standard-Port 80, bzw. 443 erreichbar sein und können durch die aufgerufene Adresse (Subdomain) blog.indibit.de, bzw. wiki.indibit.de unterschieden werden.
Inhalt
Voraussetzungen
Auf das Thema DynDNS möchte ich an dieser Stelle nicht weiter eingehen. Es gibt unsagbar viele Dienste und Möglichkeiten, das umzusetzen. Damit das Konzept so aufgeht, sollte man möglichst einen Domain-Anbieter nutzen, der einen eigenen DynDNS-Dienst bereitstellt. Ich setze nachfolgend voraus, dass die zu verwendenen Subdomains, in meinem Fall blog.indibit.de und wiki.indibit.de, zuverlässig auf den Internetanschluss zeigen, hinter dem sich die Server befinden.
Weiterhin setze ich voraus, dass es bereits ein Linux-System gibt, auf dem wir gleich Nginx als Reverse-Proxy installieren.
Und ich setze voraus, dass das Portforwarding grundsätzlich klappt, ihr wisst, was das ist und wie ihr das in eurem Router einrichtet. Könnt ihr auch gleich machen – die Ports 80 und 443 auf den Linux-Server weiterleiten, auf dem wir Nginx installieren und der damit zum Reverse-Proxy wird.
Für einen Test wäre es sinnvoll, wenn die Server, die sich hinter dem Reverse-Proxy befinden, schon funktionsfähig wären und deren Webseiten im lokalen Netzwerk erreichbar sind.
Nginx installieren
Als Grundsystem benutze ich eine Virtuelle Maschine mit Ubuntu 20.04 LTS, die eine feste IP (192.168.236.3) im internen Netz zugeordnet bekommen hat. Auf der Kommandozeile setzen wir folgende Befehle ab:
System auf den aktuellen Stand bringen:
$ sudo apt update
$ sudo apt upgrade
Nginx installieren:
$ sudo apt install nginx nginx-extras
Nach Abschluss der Installation sollte der Webserver nun online sein, was sich einfach überprüfen lässt, indem man die IP-Adresse in den Browser eintippt. Es zeigt sich die Standardseite von Nginx:
Reverse-Proxy konfigurieren
Wir befinden uns wieder auf der Kommandozeile. Nginx soll in unserem fall nicht als Webserver fungieren, sondern als Reverse-Proxy, daher schalten wir die Standardseite ab…
$ sudo unlink /etc/nginx/sites-enabled/default
… und erzeugen eine neue Konfiguration
$ cd /etc/nginx/sites-available
$ sudo nano reverse-proxy.conf
Hier definieren wir die beiden Server in sogenannten Server-Blocks und sagen Nginx, was er machen soll.
server { server_name blog.indibit.de; location / { proxy_pass http://192.168.236.12; } } server { server_name wiki.indibit.de; location / { proxy_pass http://192.168.236.23; } }
Wir verlassen den Editor und speichern die Änderungen. Anschließend aktivieren wir die Konfiguration,…
$ sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf
…schauen, ob sie ok ist…
$ sudo nginx -t
…und wenn dem so ist, schalten wir den Reverse-Proxy scharf:
$ sudo nginx -s reload
Es passiert nun folgendes:
Der Besucher gibt in seinem Browser eine der beiden Adressen (blog.indibit.de oder wiki.indibit.de) ein. Über den DNS-Server seines Internetanbieters und den DynDNS-Eintrag bei meinem Domainanbieter landet diese Anfrage nun an meinem Internetanschluss. Mein Router leitet diese Anfrage (Port 80, da Webbrowser) an den Reverse-Proxy weiter. Der Reverse-Proxy wertet nun aus, welche Adresse der Besucher im Browser eingegeben hat und leitet diese Anfrage an den entsprechenden internen Server weiter. Hat der Besucher also wiki.indibit.de eingegeben, so wird die Anfrage an 192.168.236.23 weitergeleitet. Hat er hingegen blog.indibit.de eingegeben, wird die Anfrage an 192.168.236.12 weitergeleitet.
Im Prinzip war es das schon. Wenn man keinen Fehler gemacht hat, funktioniert das System sofort.
Erweiterte Konfiguration
Mit der momentanen Konfiguration funktioniert die Weiterleitung zwar, allerdings können die beiden angeschlossenen Server nicht erkennen, wer darauf zugreift und wie dessen IP-Adresse lautet. Das ist im eigentlich nicht weiter tragisch, aber eventuell benötigt man diese Informationen ja. Wenn diese Informationen am Zielsystem ankommen soll, muss die Konfiguration entsprechend erweitert werden:
server { server_name blog.indibit.de; location / { proxy_pass http://192.168.236.12; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } client_max_body_size 0; } server { server_name wiki.indibit.de; location / { proxy_pass http://192.168.236.23; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } client_max_body_size 0; }
Bei Umgebungen, in denen größere Dateien übertragen werden sollen, zum Beispiel Nextcloud-Installationen, ist außerdem der Parameter client_max_body_size 0;
sinnvoll. Dieser hebt die standardmäßige Dateigrößenbeschränkung auf. Bleibt dieser Wert unverändert, können Dateien mit einer maximalen Größe, von 1 MByte hochgeladen werden. Der Wert kann nach folgendem Schema gesetzt werden: 1K
, 1M
, 1G
, 0
.
Auch diese Änderung wird erst auf entsprechenden Befehl hin übernommen:
$ sudo nginx -s reload
SSL-Verschlüsselung nutzen (und erzwingen)
Eine verschlüsselte Verbindung ist ein nicht ganz unwichtiger Aspekt. Sie ersetzt zwar keine sicheren Passwörter, dennoch werden Bösewichte daran gehindert, den Datenstrom ohne weiteres mitzulesen. Ein echter Vorteil des Reverse-Proxys ist, dass man mit ihm auch Verbindungen zur Servern absichern kann, die eine Verschlüsselung nicht selbst unterstützen (zum Beispiel der Loxone Miniserver Gen. 1).
Mit Let’s Encrypt gibt es eine kostenfreie Zertifizierungsstelle und certbot
nimmt einem die Arbeit fast vollständig ab.
certbot
ab, indem er täglich per Cron-Job prüft, wielange die Zertifikate noch gültig sind und diese 30 Tage vor Ablauf erneuert. Der Cron-Job wird automatisch eingerichtet. Also beginnen wir mit der Installation auf der Kommandozeile des Reverse-Proxy-Servers:
$ sudo apt install certbot python3-certbot-nginx
Anschließend führen wir certbot
aus:
$ sudo certbot --nginx
Es ist wichtig, dass der Reverse-Proxy soweit läuft und beide internen Server über ihre jeweils zugewiesene Subdomain erreichbar sind, da die Zertifizierung sonst fehlschlägt.
Der Ablauf sieht in etwa so aus:
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel):
Hier hinterlegen wir eine Email-Adresse, über die wir für wichtige Informationen erreichbar sind und drücken Enter
.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel:
Nutzungsbedingungen mit A
akzeptieren.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o:
Für den Newsletter anmelden (Y
) oder lieber keine unnötigen Mails erhalten (N
)?
Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: blog.indibit.de 2: wiki.indibit.de - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel):
Da wir certbot
mit dem Parameter --nginx
aufgerufen haben, erkennt er entsprechend der Konfiguration die beiden Server, die erreichbar sein sollen. Mit dem einfachen Betätigen der Enter
-Taste wählen wir beide aus.
Obtaining a new certificate Performing the following challenges: http-01 challenge for smarthome.sebastiankoehler.de http-01 challenge for testserver.sebastiankoehler.de Waiting for verification... Cleaning up challenges Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/reverse-proxy.conf Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/reverse-proxy.conf Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
In diesem Schritt bietet uns certbot
nun an, Nginx so zu konfigurieren, dass eine verschlüsselte Verbindung erzwungen wird. Die Reverse-Proxy-Konfiguration wird in diesem Fall automatisch angepasst und man muss sich um nichts mehr kümmern.
1
keine Änderung vornehmen
2
alle HTTP-Anfragen auf HTTPS umzuleiten
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/reverse-proxy.conf Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/reverse-proxy.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://blog.indibit.de and https://wiki.indibit.de You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=blog.indibit.de https://www.ssllabs.com/ssltest/analyze.html?d=wiki.indibit.de - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/blog.indibit.de/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/blog.indibit.de/privkey.pem Your cert will expire on 2020-11-02. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Noch einmal die neue Konfiguration übernehmen:
$ sudo nginx -s reload
Von nun an sollten alle Verbindungen verschlüsselt ablaufen, was man auch mit einem Blick in die automatisch angepasste reverse-proxy.conf
erahnen kann.
server { server_name blog.indibit.de; location / { proxy_pass http://192.168.236.12; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } client_max_body_size 0; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/blog.indibit.de/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/blog.indibit.de/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 } server { server_name wiki.indibit.de; location / { proxy_pass http://192.168.236.23; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } client_max_body_size 0; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/blog.indibit.de/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/blog.indibit.de/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 } server { if ($host = blog.indibit.de) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name blog.indibit.de; return 404; # managed by Certbot } server { if ($host = wiki.indibit.de) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name wiki.indibit.de; return 404; # managed by Certbot }
Es wurden nicht nur die SSL-Parameter hinzugefügt, sondern auch zwei zusätzliche Server-Blocks, die alle http-Anfragen mit einer 301-Weiterleitung (permanent verschoben) auf https umleiten. Sollte ein Client sich nicht weiterleiten lassen, bekommt er den Fehler 404 (nicht gefunden) angezeigt.
Renew der Zertifikate
Bleibt eigentlich nur noch eins: prüfen, ob sich die Zertifikate erneuern lassen. Ich hatte ja oben schon geschrieben, dass certbot
das alles alleine macht, da er täglich per Cron-Job dazu ermuntert wird. Dennoch kann ein Test nicht schaden.
Im echten Leben würde man dazu folgenden Befehl verwenden:
$ sudo certbot renew
Da die Zertifikate aber noch brandneu sind wird dieser Befehl mit einer entsprechenden Meldung einfach abgebrochen. Um das dennoch zu testen, steht der Parameter --dry-run
zur Verfügung. Der gesamte Befehl sieht dann also so aus:
$ sudo certbot renew --dry-run
Wenn alles glatt läuft erhält man folgende Ausgabe:
Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/blog.indibit.de.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator nginx, Installer nginx Renewing an existing certificate Performing the following challenges: http-01 challenge for blog.indibit.de http-01 challenge for wiki.indibit.de Waiting for verification... Cleaning up challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed with reload of nginx server; fullchain is /etc/letsencrypt/live/blog.indibit.de/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/blog.indibit.de/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Im Prinzip war das schon alles, was wichtig ist. Aber es geht natürlich noch mehr.
Mehr Struktur bei mehreren Servern
Wenn man nur zwei Server nutzt ist das Ganze noch übersichtlich. Hat man jedoch mehrere Server, oder will sich von vornherein offen halten, später noch etwas zu skalieren, dann kann man die komplette Konfiguration auch modular aufbauen. Vom Grunde her ändert sich dabei garnicht soviel, man teilt die Konfiguration einfach so auf, dass man eine Datei je Server nutzt. Je nach Art des nachgeschalteten Webservers kann die Reihenfolge, wie die Konfiguration geladen wird, entscheidend sein, daher kann die Dateibezeichnung wichtig werden (siehe Abschnitt zum Exchange-Server).
In unserem Beispiel würde das so aussehen:
1. Konfigurationsdatei: /etc/nginx/sites-available/S10_blog.conf
mit folgendem Inhalt:
server { server_name blog.indibit.de; location / { proxy_pass http://192.168.236.12; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } client_max_body_size 0; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/blog.indibit.de/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/blog.indibit.de/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 } server { if ($host = blog.indibit.de) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name blog.indibit.de; return 404; # managed by Certbot }
2. Konfigurationsdatei: /etc/nginx/sites-available/S20_wiki.conf
mit folgendem Inhalt:
server { server_name wiki.indibit.de; location / { proxy_pass http://192.168.236.23; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } client_max_body_size 0; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/blog.indibit.de/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/blog.indibit.de/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 } server { if ($host = wiki.indibit.de) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name wiki.indibit.de; return 404; # managed by Certbot }
Einfach die alte Konfiguration deaktivieren…
$ sudo unlink /etc/nginx/sites-enabled/reverse-proxy.conf
…die beiden neuen Konfigurationsdateien aktivieren…
$ sudo ln -s /etc/nginx/sites-available/S10_blog.conf /etc/nginx/sites-enabled/S10_blog.conf
$ sudo ln -s /etc/nginx/sites-available/S20_wiki.conf /etc/nginx/sites-enabled/S20_wiki.conf
…und die Änderungen übernehmen:
$ sudo nginx -s reload
Nun läuft alles wie vorher, allerdings lassen sich nun auf einfache Art und Weise beliebig Server hinzufügen oder entfernen. Die alte Konfigurationsdatei kann gelöscht werden.
Microsoft Exchange-Server 2016 hinter einem Reverse-Proxy
Alles zuvor beschriebene wird mit den meisten Netzwerkgeräten, die einen Webserver integriert haben, funktionieren. Microsoft Exchange ist jedoch ein Sonderling und muss gesondert berücksichtigt werden, wenn dieser hinter dem Reverse-Proxy arbeiten soll. Bevor ihr das hier Beschriebene ausprobiert stellt zuvor sicher, dass der Exchange-Server zu 100% zuverlässig läuft, wenn die Ports direkt zu ihm weitergeleitet sind.
Folgendes gilt es zu berücksichtigen:
- Ein Exchange-Server mag keine Let’s Encrypt-Zertifikate und lässt sich damit auch nicht ohne Fehlermeldung betreiben. Da ich voraussetze, dass der Exchange 100% zuverlässig läuft, besitzt er auch schon ein Zertifikat, das wir zusätzlich für den Reverse-Proxy nutzen.
- Die Reverse-Proxy-Konfiguration für den Exchange-Server muss vor allen anderen geladen werden, damit sie einwandfrei funktioniert.
- Im IIS-Manager muss Standardauthentifizierung für
EWS
undmapi
aktiviert werden.
Folgende Parameter gelten in meiner Umgebung:
- Der Exchange-Server soll über
owa.mycompany.de
undautodiscover.mycompany.de
von außen erreichbar sein - Die Windows-Server-Domäne heißt
ad.mycompany.de
- Der interne DNS-Name des Exchange-Servers lautet
srv-exc1.ad.mycompany.de
Zertifikat installieren
In meinem Fall liegt das Zertifikat des Exchange-Servers als ca-bundle
vor und besteht aus 3 Dateien (die Dateinamen können bei euch natürlich anders lauten):
cert_exc.ca-bundle
cert_exc.crt
key.txt
Diese Dateien werden per WinSCP ins Benutzer-Home-Verzeichnis auf dem Reverse-Proxy-Server kopiert. Dann geht es per SSH auf der Kommandozeile weiter: das Zertifikat anpassen und im Zertifikatsspeicher ablegen:
$ sudo cat cert_exc.crt cert_exc.ca-bundle >> /etc/ssl/certs/_exchange-cert.crt
$ sudo cp key.txt /etc/ssl/certs/_exchange-key.txt
Reverse-Proxy-Konfiguration
Wir erzeugen die Konfigurationsdatei /etc/nginx/sites-available/S01_exchange.conf
mit folgendem Inhalt:
server { listen 80; server_name owa.mycompany.de autodiscover.mycompany.de; # Redirect any HTTP request to HTTPS return 301 https://$server_name$request_uri; error_log /var/log/nginx/exchange-error.log; access_log /var/log/nginx/exchange-access.log; } server { listen 443 ssl; server_name owa.mycompany.de autodiscover.mycompany.de; # Enable SSL ssl_certificate /etc/ssl/certs/_exchange-cert.crt; ssl_certificate_key /etc/ssl/certs/_exchange-key.txt; ssl_session_timeout 5m; # Set global proxy settings proxy_read_timeout 360; proxy_http_version 1.1; proxy_buffering off; proxy_request_buffering off; proxy_pass_request_headers on; proxy_pass_header Date; proxy_pass_header Server; proxy_pass_header Authorization; 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 $scheme; proxy_set_header Accept-Encoding ""; proxy_set_header Connection "Keep-Alive"; more_set_input_headers 'Authorization: $http_authorization'; more_set_headers -s 401 'WWW-Authenticate: Basic realm="srv-exc1.ad.mycompany.de"'; client_max_body_size 0; location /owa { proxy_pass https://srv-exc1.ad.mycompany.de/owa; } location /OWA { proxy_pass https://srv-exc1.ad.mycompany.de/owa; } location /EWS { proxy_pass https://srv-exc1.ad.mycompany.de/EWS; } location /ews { proxy_pass https://srv-exc1.ad.mycompany.de/EWS; } location /Microsoft-Server-ActiveSync { proxy_pass https://srv-exc1.ad.mycompany.de/Microsoft-Server-ActiveSync; } location /mapi { proxy_pass https://srv-exc1.ad.mycompany.de/mapi; } location /MAPI { proxy_pass https://srv-exc1.ad.mycompany.de/mapi; } location /rpc { proxy_pass https://srv-exc1.ad.mycompany.de/Rpc; } location /RPC { proxy_pass https://srv-exc1.ad.mycompany.de/Rpc; } location /oab { proxy_pass https://srv-exc1.ad.mycompany.de/OAB; } location /OAB { proxy_pass https://srv-exc1.ad.mycompany.de/OAB; } location /autodiscover { proxy_pass https://srv-exc1.ad.mycompany.de/Autodiscover; } location /Autodiscover { proxy_pass https://srv-exc1.ad.mycompany.de/Autodiscover; } error_log /var/log/nginx/exchange-ssl-error.log; access_log /var/log/nginx/exchange-ssl-access.log; }
Anschließend wieder die Konfiguration aktivieren und Nginx neu laden:
$ sudo ln -s /etc/nginx/sites-available/S01_exchange.conf /etc/nginx/sites-enabled/S01_exchange.conf
$ sudo nginx -s reload
Internetinformationsdiense (ISS) konfigurieren
Bleibt noch die Konfiguration der Authentifizierung. Leider kann die kostenfreie Variante von Nginx nicht mit NTLM
umgehen, also müssen wir dem Exchange-Server mitteilen, dass er auch Standard-Authentifizierung akzeptieren soll. Dafür starten wir den Internetinformationsdienste (IIS)-Manager, navigieren links im Baum nach SRV-EXC1
-> Sites
-> Default Web Site
-> EWS
, wählen dort Authentifizierung …
…und aktivieren die Standardauthentifizierung:
Das Gleiche machen wir nochmal für mapi
:
Die Änderungen sind sofort aktiv, ein Server-Neustart oder Ähnliches ist nicht nötig. Der Exchange-Server sollte nun auch hinter dem Reverse-Proxy erreichbar sein, inkl. Zugriff über Outlook und auf „Automatische Antworten“.
Einschränkungen
Obwohl das ganze im praktischen Einsatz sehr gut funktioniert, gibt es in bestimmten Konstellationen dennoch eine kleine Einschränkung: Wird eine VPN-Verbindung ins Firmennetzwerk hergestellt und Outlook erst danach gestartet, wird die Windows-Authentifizierung NTLM genutzt.
Wenn die VPN-Verbindung nun getrennt wird, wird auch die Verbindung zu Outlook getrennt, da der Weg über Windows-Authentifizierung nicht mehr zur Verfügung steht. Je nach sonstiger Konfiguration von Outlook wird die Verbindung eventuell nicht von alleine aufgebaut und es erscheint ein Fenster, in dem das Passwort für den Zugang eingegeben werden soll. Selbst, wenn man das Passwort 100 mal eingibt, wird sich Outlook nicht verbinden. In diesem Fall muss man Outlook beenden und erneut starten, damit die Verbindung per Standard-Authentifizierung hergestellt wird.
Der andere Weg, erst Outlook starten und anschließend VPN, funktioniert ohne Unterbrechung, da die Standard-Authentifizierung sowohl über VPN, als auch das Internet zur Verfügung steht.
Es gibt sicherlich Wege, wie man das beheben kann. Zum Beispiel generell nur Standard-Authentifizierung verwenden, lokal, wie über VPN, wie von extern. Oder Outlook zu einem erneuten Verbindungsversuch überreden. Ich habe jedoch bisher noch keinen ausprobiert, da das ganze für mich kaum eine Einschränkung bedeutet und somit kein Bedarf vorhanden ist.
- Proxmox: „Failed to connect to Server“ mit Safari auf MacOS - 28. Januar 2023
- Loxone: Benachrichtigung per Telegram - 15. Januar 2022
- Telegram: Nachrichten per Bot von der Heimautomation aufs Handy - 2. Januar 2022
16 Comments