Reverse Proxy mit SSL und Authentifizierung
SSL-Verschlüsselung und Authentifizierung für Websites, auf die über einen Reverse Proxy zugegriffen wird
Websites, auf die über einen Reverse Proxy zugegriffen wird, brauchen nur bis zum Proxy mittels eines SSL-Zertifikates gesichert werden. Damit ist auch der Zugang über eine Authentifizierung geschützt.
In einem anderen Artikel dieses Blog wurde beschrieben, wie man mit der Einrichtung eines Webservers als Reverse Proxy den Zugriff auf Websites ermöglichen kann, auch wenn diese sich auf einem Arbeitsplatzrechner in einem privaten Netzwerk befinden.
In diesem Artikel soll der Zugriff auf die Website auf dem Arbeitsplatzrechner mit einer Authentifizierung geschützt und daher auch mit SSL verschlüsselt werden.
Voraussetzungen
Es wird davon ausgegangen, dass die grundlegende Einrichtung des Proxy sowie des Arbeitsplatzrechners gemäß dem oben zitierten Artikel abgeschlossen ist.
Im nachfolgenden wird wieder das Laptop namens Caboto sowie der Server im Internet namens Cayenne verwendet. Die Website für einen Kunden unter der Adresse https://customer1.mydomain.de/
ist sowohl auf dem Laptop als auch vom Rechner des Kunden aufrufbar.
SSL-Verschlüsselung einrichten
Ohne Frage wird man den Zugriff auf die Website customer1.mydomain.de
nur unter https
ermöglichen wollen – insbesondere dann, wenn man Formulare verwendet (z.B. für ein Login) oder die gesamte Website mit einer Authentifizierung vor unbefugtem Zugriff schützen möchte. Letzteres dürfte nicht zuletzt auch im Interesse des Kunden sein – zumindest solange die Website noch in der Entwicklung befindlich ist.
Glücklicherweise ist die Ausstellung eines Zertifikates dank Let's Encrypt heutzutage weder mit großem Aufwand noch mit Kosten verbunden. Die genaue Vorgehensweise ist für alle möglichen Betriebssysteme und Webserver auf der Website von Let's Encrypt beschrieben aber natürlich ist es auch möglich, ein Zertifikat einer anderen Zertifizierungstelle zu verwenden.
Für das hier beschriebene Szenario stellt sich lediglich die Frage ob die SSL-Verschlüsselung auf dem Arbeitsplatzrechner (Caboto), dem Proxy-Server (Cayenne) oder auf beiden eingerichtet werden soll.
In der Regel ist nur die Einrichtung auf dem Proxy-Server notwendig und sinnvoll, da lediglich der Weg der Anfrage vom Browser des Client bis zum Proxy-Server per Zertifikat geschützt werden muss. Vom Proxy-Server zum eigentlichen Webserver auf Caboto läuft die Anfrage ja ohnehin durch den mit SSH verschlüsselten Tunnel und muss nicht und sollte auch nicht zusätzlich verschlüsselt werden.
Somit ist lediglich auf Cayenne die Konfiguration des Webservers bzw. des virtuellen Hosts anzupassen, so dass Anfragen mit http
zu https
umgeleitet werden und Anfragen mit https
korrekt bedient werden.
Dafür müssen auf dem Proxy-Server die Apache-Module mod_alias
und mod_ssl
aktiviert sein. Bei Verwendung eines Zertifikats von Let's Encrypt würde die Konfiguration von oben wie folgt erweitert:
<VirtualHost <IP>:80>
ServerName customer1.mydomain.de
RedirectPermanent / https://customer1.mydomain.de/
</VirtualHost>
<VirtualHost <IP>:443>
ServerName customer1.mydomain.de
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/customer1.mydomain.de/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/customer1.mydomain.de/privkey.pem
SSLCACertificatePath /etc/ssl/certs/
ProxyRequests Off
ProxyPass / http://localhost:8881/
ProxyPassReverse / http://localhost:8881/
ProxyPreserveHost On
</VirtualHost>
Der erste virtuelle Host dient jetzt lediglich dazu, unverschlüsselte Anfragen direkt auf verschlüsselte Anfragen umzuleiten. Die Proxy-Anweisungen werden in einem zweiten virtuellen Host untergebracht, dessen Kommunikation mit dem Browser des Client mit Hilfe der zusätzlichen SSL-Anweisungen verschlüsselt wird.
Nach einem Neustart des Webservers auf Cayenne kann die Website von außerhalb des Rechners Caboto nur noch mit https
aufgerufen werden. Findet dennoch ein Aufruf mit http
statt, wird dieser direkt zu seinem https
-Pendant weitergeleitet.
Auf dem Proxy findet somit eine sogenannte "SSL-Terminierung" statt, d.h. der Webserver auf Cayenne entschlüsselt die Anfrage und reicht sie unverschlüsselt, aber durch den bestehenden SSH-Tunnel an den Webserver auf Caboto weiter. Die unverschlüsselte Antwort des Webservers auf Caboto wird auf Cayenne wieder verschlüsselt, bevor sie an den Client weitergereicht wird.
Authentifizierung erzwingen
Jetzt kann die Website des Kunden mit einer Authentifizierung geschützt werden, ohne dass Passwörter im Klartext unverschlüsselt übermittelt werden. Am besten ist dies durch die Einrichtung einer einfachen Authentifizierung am Webserver, der sogenannten "Basic Authentication" zu realisieren.
Auch hier stellt sich wieder die Frage, ob diese auf dem Arbeitsplatzrechner, dem Proxy-Server oder auf beiden eingerichtet werden soll. Die Antwort kann hier allerdings nicht so eindeutig ausfallen. Vielmehr kommt es auf die Rahmenbedingungen an.
Auf jeden Fall wird man den Zugriff von außerhalb des lokalen Rechners schützen wollen, d.h. wenn dieser über den Proxy stattfindet, was für die Einrichtung des Zugriffschutzes auf dem Proxy-Server spricht. Falls man allerdings mit nur einem Proxy mehrere virtuelle Hosts auf dem dahinterliegenden Webserver bedienen möchte, von denen nicht alle durch Authentifizierung geschützt werden sollen, würde es Sinn machen, die Authentifizierung dorthin zu verlagern. Ein solches Szenario wird in einem späteren Artikel vorgestellt.
Die einfache Authentifizierung ist auf dem Webserver nach der Aktivierung der Module mod_auth_basic
, mod_authn_file
und mod_authz_user
möglich. Diese Module sind üblicherweise bereits im Standard aktiviert. Die Konfiguration würde wie folgt aussehen:
<VirtualHost <IP>:80>
ServerName customer1.mydomain.de
RedirectPermanent / https://customer1.mydomain.de/
</VirtualHost>
<VirtualHost <IP>:443>
ServerName customer1.mydomain.de
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/customer1.mydomain.de/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/customer1.mydomain.de/privkey.pem
SSLCACertificatePath /etc/ssl/certs/
ProxyRequests Off
ProxyPass / http://localhost:8881/
ProxyPassReverse / http://localhost:8881/
ProxyPreserveHost On
<Location "/">
AuthType Basic
AuthName "Restricted"
AuthUserFile "/etc/apache2/credentials"
Require valid-user
</Location>
</VirtualHost>
In diesem Beispiel wird die Authentifizierung anhand der Informationen, die in der Datei /etc/apache2/credentials
gespeichert sind, durchgeführt. Die Datei enthält Benutzernamen und die zugehörigen Passwörter. Zur Erstellung und Verwaltung dieser Datei gibt es das Programm htpasswd
, das bei der Installation des Apache Webserver automatisch mitinstalliert wird.
Um die Datei erstmals zu erstellen und den Benutzer kunde1
mit dem Passwort geheim
anzulegen, würde der Aufruf wie folgt aussehen:
$ sudo htpasswd -c /etc/apache2/credentials kunde1
New password:
Re-type new password:
Adding password for user kunde1
$ cat /etc/apache2/credentials
kunde1:$apr1$Z9YgFwA.$RhglifUzDRxUu/Z6VaQjI1
Wie man sieht wird das Passwort in der Datei verschlüsselt gespeichert.
Nach einem erneuten Start des Webservers ist der Aufruf der Website von außerhalb des Rechners Caboto nicht nur verschlüsselt, sondern auch nur nach einer erfolgreichen Authentifizierung erreichbar. Vom Arbeitsplatzrechner Caboto kann man jedoch weiterhin die Website unverschlüsselt und ohne Authentifizierung aufrufen.
Ausnahmen von der Authentifizierung
Möglicherweise macht es Sinn, für spezifische Anwendungsfälle Ausnahmen von der Authentifizierung einzurichten, z.B. für die Erneuerung des mit certbot
ausgestellten Zertifikates von Let's Encrypt.
Vorausgesetzt, das Zertifikat wurde mittels HTTP Validierung ausgestellt und soll damit auch erneuert werden, ist zunächst eine Ausnahme für den Proxy einzurichten, sodass Anfragen für die URL /.well-known
nicht vom Proxy erfasst werden:
ProxyPass /.well-known !
Der Webserver muss dann allerdings wissen, wie Anfragen auf URLs, die mit .well-known
beginnen, behandelt werden müssen. Dafür muss der Konfiguration ein weiterer Location Block und ein Alias hinzugefügt werden:
Alias "/.well-known" "/home/uwe/vhosts/uwe-gehring.de/customer1/htdocs/.well-known"
<Location "/.well-known">
AuthType None
Require all granted
</Location>
Wichtig ist, dass dieser Location Block nach dem ersten Block in die Konfiguration eingefügt wird, da er eine Ausnahme zum vorhergehenden Block darstellt.
Insgesamt würde die Konfiguration dann wie folgt aussehen:
<VirtualHost <IP>:80>
ServerName customer1.mydomain.de
RedirectPermanent / https://customer1.mydomain.de/
</VirtualHost>
<VirtualHost <IP>:443>
ServerName customer1.mydomain.de
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/customer1.mydomain.de/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/customer1.mydomain.de/privkey.pem
SSLCACertificatePath /etc/ssl/certs/
ProxyRequests Off
ProxyPass /.well-known !
ProxyPass / http://localhost:8881/
ProxyPassReverse / http://localhost:8881/
ProxyPreserveHost On
<Location "/">
AuthType Basic
AuthName "Restricted"
AuthUserFile "/etc/apache2/credentials"
Require valid-user
</Location>
Alias "/.well-known" "/home/uwe/vhosts/uwe-gehring.de/customer1/htdocs/.well-known"
<Location "/.well-known">
AuthType None
Require all granted
</Location>
</VirtualHost>
Nach einem weiteren Neustart des Webservers kann die Erneuerung des Zertifikats mit certbot
durchgeführt werden, was man leicht mit einem Testlauf von certbot
überprüfen kann.
Zusammenfassung und Ausblick
Der Zugriff auf Websites über einen Reverse Proxy ermöglicht die Verschlüsselung der Verbindung, ohne dass die Website auf dem Arbeitsplatzrechner selbst mit SSL abgesichert werden muss, was Ressourcen auf dem Arbeitsplatzrechner spart. Gleichzeitig ist die Verbindung aus dem Internet verschlüsselt, was die Übermittlung eines Passwortes im Rahmen einer Authentifizierung sicher macht.
In späteren Artikeln geht es um weitere Aspekte wie z.B.
- Mehrere Websites zur Verfügung stellen
- Zwischenspeichern von Inhalten auf dem Reverse Proxy
- Content-Filter für komplexe Websites