Viele Leser dieses Blogs haben sich einen Artikel zum Thema „Exchange Server und Reverse Proxy“ gewünscht. Zwar gibt es hier schon HowTos mit Kemp, Sophos und F5, jedoch scheint es auch Bedarf an Open-Source Lösungen zu geben. Daher gibt es an dieser Stelle mal ein HowTo für die Nutzung von Apache als Reverse Proxy für Exchange Server.
Prinzipiell ist die Verwendung einen Reverse Proxys in Verbindung mit Exchange Servern eine gute Idee. Gerade in vielen kleinen Umgebungen wird oft ein simples NAT der Ports 80 und 443 am Router zum Exchange Server eingerichtet. Dies hat allerdings zur Folge, dass der Exchange Server mit all seinen Protokollen, Schnittstellen und Diensten im Internet veröffentlicht wird. Kommen dann noch vernachlässigte Updates oder Zero-Day Exploits hinzu, ist es nur eine Frage der Zeit bis dem Exchange Server Böses widerfährt.
Ein Reverse Proxy kann schon etwas Abhilfe schaffen, denn es lässt sich besser kontrollieren, welche Exchange Dienste veröffentlicht werden. Beispielsweise kann via Reverse Proxy der Zugriff auf das Exchange Admin Center deaktiviert werden. Einige Leser haben auch die Frage gestellt, wie nur OWA aus dem Internet erreichbar gemacht werden kann, alle anderen Protokolle wie ActiveSync oder MAPIoverHTTP aber nicht.
FunFakt: Viele automatisierten Angriffe laufen schon ins Leere, nur weil ein Reverse Proxy vorhanden ist. HTTP Header entspricht nicht „IIS“, dann auf zum nächsten Ziel…
In diesem Artikel geht es zunächst um die Installation und die Konfiguration von Apache als Reverse Proxy für Exchange. Im nächsten Artikel wird diese Konfiguration dann etwas erweitert.
Betriebssystem installieren
Als Betriebssystem habe ich Ubuntu Server 22.04 Minimal verwendet. Nach der Standardinstallation habe ich nur die Netzwerkkonfiguration durchgeführt, sowie NTP für die Zeitsynchronisation konfiguriert.
Ubuntu Server kann hier runtergeladen werden:
Ubuntu läuft bei mir in einer kleinen VM mit 2 vCPUs und 4GB RAM.
Firewall installieren und einschalten
Die Firewall UFW kann mit den folgenden Befehlen installiert und konfiguriert werden. Die Konfiguration lässt dabei alle ausgehenden Verbindungen zu, eingehend werden nur HTTP, HTTPS und SSH zugelassen:
apt-get install ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow http
ufw allow https
ufw enable
ufw status
Apache installieren und Module aktivieren
Damit Apache als Reverse Proxy für Exchange verwendet werden kann, muss Apache zunächst installiert und die notwendigen Module geladen werden:
apt-get install apache2
a2enmod headers
a2enmod rewrite
a2enmod proxy_http
a2enmod ssl
a2dismod mpm_event
a2enmod mpm_prefork
echo "ServerName 127.0.0.1" >> /etc/apache2/apache2.conf
systemctl restart apache2
Apache als Reverse Proxy für Exchange Server
Apache als Reverse Proxy
cd /etc/apache2/sites-available/
a2dissite 000-default.conf
touch 001-exchange-proxy.conf
a2ensite 001-exchange-proxy.conf
In die Datei „001-exchange-proxy.conf“ kann nun die Proxy Konfiguration für Exchange eingefügt werden:
#ServerLimit 300
#MaxRequestWorkers 300
MaxConnectionsPerChild 1
#FrontEnd Server Settings
#------------------------
define FrontEndServerName outlook.frankysweblab.de
define FrondEndServerAlias autodiscover.frankysweblab.de
define FrontEndServerAdmin webmaster@frankysweblab.de
#Exchange Server IP
#------------------------
define BackEndServerIP 192.168.100.112
#Only redirect http to https and some logging
<VirtualHost *:80>
ServerName ${FrontEndServerName}
ServerAlias ${FrondEndServerAlias}
ServerAdmin ${FrontEndServerAdmin}
#Logging
ErrorLog /var/log/apache2/exchange_80_error.log
CustomLog /var/log/apache2/exchange_80_access.log combined
ProxyRequests Off
#redirect http to https
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
#HTTPS Virtual Host for Exchange Server
<VirtualHost *:443>
ServerName ${FrontEndServerName}
ServerAlias ${FrondEndServerAlias}
ServerAdmin ${FrontEndServerAdmin}
ErrorLog /var/log/apache2/exchange_443_error.log
CustomLog /var/log/apache2/exchange_443_access.log combined
Header always set X-Frame-Options SAMEORIGIN
Header set Server Apache
Header unset X-AspNet-Version
Header unset X-OWA-Version
Header unset X-Powered-By
RequestHeader unset Expect early
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
RequestHeader edit Transfer-Encoding Chunked chunked early
RequestHeader unset Accept-Encoding
TimeOut 1800
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
Redirect / /owa/
#OWA
ProxyPass /owa https://${BackEndServerIP}/owa
ProxyPassReverse /owa https://${BackEndServerIP}/owa
ProxyPass /OWA https://${BackEndServerIP}/OWA
ProxyPassReverse /OWA https://${BackEndServerIP}/OWA
#MAPIoverHTTP
ProxyPass /mapi https://${BackEndServerIP}/mapi
ProxyPassReverse /mapi https://${BackEndServerIP}/mapi
#EWS
ProxyPass /ews https://${BackEndServerIP}/ews
ProxyPassReverse /ews https://${BackEndServerIP}/ews
ProxyPass /EWS https://${BackEndServerIP}/EWS
ProxyPassReverse /EWS https://${BackEndServerIP}/EWS
#OAB
ProxyPass /oab https://${BackEndServerIP}/oab
ProxyPassReverse /oab https://${BackEndServerIP}/oab
ProxyPass /OAB https://${BackEndServerIP}/OAB
ProxyPassReverse /OAB https://${BackEndServerIP}/OAB
#ActiveSync
ProxyPass /Microsoft-Server-ActiveSync https://${BackEndServerIP}/Microsoft-Server-ActiveSync connectiontimeout=900
ProxyPassReverse /Microsoft-Server-ActiveSync https://${BackEndServerIP}/Microsoft-Server-ActiveSync
<Directory /Microsoft-Server-ActiveSync>
SSLRenegBufferSize 31457280
</Directory>
#AutoDiscover
ProxyPass /autodiscover https://${BackEndServerIP}/autodiscover
ProxyPassReverse /autodiscover https://${BackEndServerIP}/autodiscover
ProxyPass /Autodiscover https://${BackEndServerIP}/Autodiscover
ProxyPassReverse /Autodiscover https://${BackEndServerIP}/Autodiscover
ProxyPass /AutoDiscover https://${BackEndServerIP}/AutoDiscover
ProxyPassReverse /AutoDiscover https://${BackEndServerIP}/AutoDiscover
AddDefaultCharset ISO-8859-1
<Directory />
Order deny,allow
Deny from all
</Directory>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
#SSL Settings
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA38
SSLHonorCipherOrder off
#SSL Certificate
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
</VirtualHost>
Die Zeilen 7-9 und 13 müssen an die eigene Umgebung angepasst werden.
apache2ctl -t
systemctl reload apache2
systemctl status apache2
Zertifikat von Let’s Encrypt konfigurieren
LetsEncrypt
apt-get install certbot python3-certbot-apache
Zertifikat holen
certbot --apache
apache2ctl -t
systemctl reload apache2
systemctl status certbot.timer
Apache als Reverse Proxy inkl. Zertifikat von Let’s Encrypt sind nun schon mal fertig konfiguriert. Jetzt kann getestet werden.
Tests
Um zu testen ob der Proxy fehlerfrei funktioniert, eignet sich ein externer Client natürlich am besten. Falls gerade kein Testrechner zur Verfügung steht, lässt sich schnell eine VM in Azure oder AWS erstellen und mit Outlook versorgen.
In meinem Fall habe ich eine Azure VM benutzt um Outlook und OWA zu testen. In meinem Fall funktionieren Outlook und OWA problemlos. Im Fehlerfall können die Apache Logfiles weiterhelfen. Die Logs werden unter /var/log/apache2 gespeichert:
Relevant sind die diese beiden Logfiles:
- exchange_443_access.log
- exchange_443_error.log
Lasst euch im Access Log nicht von den HTTP 401 (Unauthorized) Fehlern erschrecken, das ist eine Eigenheit des NTLM Protokolls. Auf die HTTP 401 Fehler sollte bei erfolgreicher Verbindung ein HTTP 200 (OK) folgen:
Bis hierher solltet ihr wenig Probleme mit dem Reverse Proxy haben, denn die Verbindungen der Clients werden nahezu unverändert an Exchange weitergeleitet.
Fazit
Apache lässt sich recht einfach als Reverse Proxy für Exchange einsetzen, jedoch bringt meiner Meinung nach diese Konfiguration noch keinerlei Sicherheitsgewinn. Die Konfiguration aus diesem Artikel eignet sich eher, wenn unter einer einzelnen öffentlichen IP noch weitere Dienste auf Port 443 veröffentlicht werden sollen. Mit etwas Anpassung wäre es beispielsweise möglich die Verbindungen je nach DNS-Name zu unterschiedlichen Servern zu routen.
Immerhin sorgt diese Konfiguration schon einmal dafür, dass das Exchange Admin Center nicht aus dem Internet erreichbar ist. Die meisten Anfragen zum Thema Reverse Proxy und Exchange Server hatten den Hintergrund, dass der Zugriff auf EAC aus dem Internet blockiert werden soll. Mit Exchange 2019 lässt sich diese Anforderung allerdings auch etwas einfacher lösen:
Einige Leser wollten nur bestimmte Protokolle wie ActiveSync und OWA im Internet freigeben, dies ist mit der jetzigen Konfiguration problemlos möglich. Wer beispielsweise kein EWS veröffentlichen möchte, kommentiert einfach diesen Block aus der Apache Konfiguration aus:
#EWS
ProxyPass /ews https://${BackEndServerIP}/ews
ProxyPassReverse /ews https://${BackEndServerIP}/ews
ProxyPass /EWS https://${BackEndServerIP}/EWS
ProxyPassReverse /EWS https://${BackEndServerIP}/EWS
Interessanter wird es im nächsten Artikel, denn dort kommt zusätzlich mod_security als Web Application Firewall (WAF) zum Einsatz.