Client Authentifizierung mit Apache


- Veröffentlicht in freeX 03/02 -



Apache ist der weltweit am häufigsten eingesetzte Web-Server, was Untersuchungen von Netcraft stets aufs neuste belegen. Ein Apache-Server stellt anfragenden Clients verschiedene Daten zur Verfügung, auf die auf unterschiedliche Art zugegriffen werden kann. Teilweise ist es wünschenswert, dass die Daten nur von dazu autorisierten Clients abgerufen werden können. Apache bietet hierzu zwei verschiedene Lösungsansätze, auf die im weiteren Verlauf näher eingegangen wird.

Auf einem Web-Server können die unterschiedlichsten Arten von Daten zur Verfügung gestellt werden, auf die von anfragenden Clients zugegriffen werden kann. Teilweise ist es jedoch wünschenswert, dass auf vereinzelte Daten nur ein beschränkter Zugriff gestattet ist. So ist es beispielsweise denkbar, dass in einem Unternehmen bestimmte, dazu authorisierte Mitarbeiter, einzelne Seiten aufrufen sollen. Oder es werden für einzelne Kunden Daten zur Verfügung gestellt, für die eine besondere Berechtigung erforderlich ist. In diesen Beispielen sowie in ähnlich gelagerten Fällen ist eine Client-Authentifizierung unumgänglich.

Apache bietet zwei Möglichkeiten der Client-Authentifizierung an, zum einen mittels Passwortabfrage und zum anderen über Zertifikate. Vereinfacht gesagt ist die Authentifzierung mittels Client-Zertifikat mit dem grösseren administrativen Aufwand und der höheren Sicherheit verbunden, bei den Passworten ist es entsprechend umgekehrt.




.htpasswd

Mit dem Programm htpasswd ist es möglich den Zugriff für bestimmte Verzeichnisse zu beschränken. Diese Zugriffskontrollen werden über drei Konfigurationsateien wahrgenommen:

.htpasswd
Datei in der die Passworte gespeichert werden, der Aufbau ist ähnlich dem von /etc/passwd.

.htgroup
Datei in der Informationen über die Mitglieder einer Gruppe gespeichert sind. Der Aufbau ist ähnlich dem im /etc/group.

.htaccess
Über diese Datei werden die Zugriffsmechanismen gesteuert. Hier werden einzelne Regeln aufgestellt, das Verzeichnis der Konfigurationsdateien angegeben, Authentifizierungsmethoden festgelegt, usw.

Das folgende Beispiel soll das Zusammenwirken der Dateien .htpasswd und .htaccess verdeutlichen. Die Anwenderin Carol möchte alle Dateien die ihr gehören und die in und unterhalb von /home/carol/public_html sind, durch eine entsprechende Passwortabfrage geschützt werden.

Zuerst wird die Datenbank mit den Passworten angelegt,

$ /usr/local/apache/bin/htpasswd -c .htpasswd carol 
New password: <passwort>
Re-type new password: <passwort>
Adding password for user carol
$

Nach dieser Eingabe wurde eine Datei .htpasswd mit einem Eintrag für die Anwenderin Carol angelgt, die das verschlüsselte Passwort enthält. Das Passwort wurde mit crypt() verschlüsselt, alternativ kann auch mittels MD5, Option -m, oder mit SHA, Option -s, verschlüsselt werden. Die Option -c ist nur bei dem Anlegen einer neuen Datei anzugeben, soll eine bereits bestehende Datei ein neuer Eintrag zugefügt werden, ist keine weitere Option anzugeben.

Die »Passwortdatei« hat nach dem Aufruf das folgende Aussehen:

$ cat .htpasswd 
carol:93Fkjc8EGoNUk
$



.htaccess

Der nächste Schritt besteht darin, die entsprechenden Regeln für die Zugriffskontrollen festzulegen. Dazu ist eine Datei .htaccess anzulegen, in der mehrere Variablen gesetzt werden können.

AuthUserFile
Angabe des Verzeichnisses in dem sich die Datei .htpasswd befindet, bei der Angabe ist darauf zu achten, dass hier der vollständige Pfad angegeben wird. Aus Sicherheitsgründen sollte diese Datei nie im Dokumentenverzeichnis (DocumentRoot) befinden, da sonst eventuell über das WWW darauf zugegriffen werden kann.

AuthGroupFile
Angabe des Verzeichnisses in dem sich die Datei .htgroup befindet, auch hier ist der vollständige Pfad anzugeben. Auch diese Datei sollte nicht unter DocumentRoot gespeichert werden.

AuthName
Hier kann optional eine Meldung angegeben werden, die bei der Aufforderung zur Eingabe der Anwenderdaten ausgegeben wird. Unterbleibt diese Angabe wird der »Standardtext« genutzt.

AuthType
Mit dieser Angabe wird das Authentifizierungsprotokoll festgelegt. Mit der Angabe Basic erfolgt die Übertragung des Passwortes unverschlüsselt und bei der Angabe von Digest wird das Passwort entprechend verschlüsselt übertragen. Obwohl somit das Digest-Verfahren erste Wahl sein sollte, ist hierzu zu bemerken, dass es von den wenigsten Web-Browsern unterstützt wird.

Limit
Hiermit werden die Kontrollmechanismen genauer definiert, die festlegen, welchen Hosts Zugriff gewährt (allow) oder verweigert (deny) wird, welche Anwender oder Gruppen auf das Verzeichnis zugreifen dürfen (require) die Art des Zugangs sowie die Reihenfolge der Auswertung der jeweiligen Regeln (order).

Die Datei .htaccess kann beispielsweise folgendes Aussehen haben:

$ cat .htaccess              
AuthName "Passwortgeschuetzter Bereich"
AuthType Basic
AuthUserFile /home/carol/public_html/.htpasswd
require user carol
$

Mit diesen Angaben wird dem Apache Web-Server gesagt, dass zur Authentifizierung die »Basic-Methode« verwendet werden soll und bei der Abfrage die Angabe Passwortgeschuetzter Bereich ausgegeben wird. Außerdem wird der Pfad zu .htpasswd und der Anwender angegeben, der sich hier einwählen kann.

Wenn sich ein Anwender mit der Seite von carol verbinden will, überprüft der Server die Datei .htpasswd und benachrichtigt den Client, dass eine Authentifizierung erforderlich ist. Der Client erhält darauf ein Fenster, welches ein entsprechendes Passwort-Dialogfeld enthält.

Abb. 1 Paswortabfrage - htpasswd

Wenn der Anwender eine falsche Anwenderbzeichnung und/oder ein falsches Passwort eingibt, verweigert der Server den Zugriff und bietet einen erneuten Einwahlversuch an. Schlägt die Authorisierung letztlich entgültig fehl wird eine Authentication Required Meldung angezeigt. Diese Fehlermeldung kann über die folgende Direktive geändert werden

ErrorDocument 401 meine_401_fehlermeldung.html

und über die angegebene Datei kann dann eine »aussagekräftigere Ausgabe« angezeigt werden.

Der Zugriff für eine Gruppe verläuft analog zur Zugriffsberechtigung eines einzelnen Anwenders. Zuerst ist die Datei .htgroups zu erstellen, in der die Zugriffsregeln für die Gruppe(n) definiert werden.

Die Bezeichnung der Dateien kann in der Konfigurationsdatei des Web-Servers httpd.conf geändert werden, um so einem möglichen Angreifer die Suche zu erschweren.

Letzlich ist noch darauf zu achten, dass der Server die Dateien lesen kann und die Zugriffsberechtigungen entsprechend gesetzt sind.




.htdigest

Diese Verfahrensweise ist zwar relativ einfach umzusetzen, beinhaltet aber auch einige Nachteile. Dazu gehört insbesondere, dass die Passworte unverschlüsselt übertragen werden. In der Dokumentation von Apache wird davon abgeraten diesen Authentifizierungsmechanismus für sensible Daten zu nutzen, da es für einen potentiellen Angreifer »ein leichtes ist, die Maßnahmen zu umgehen«.

Apache bietet jedoch auch einen gesicherten Passwortschutz an, der auf dem Modul mod_auth_digest basiert. Bei DSO-Unterstützung muss das Modul in der Konfigurationsdatei bei den Direktiven LoadModule sowie AddModule angegeben sein.

Wurde Apache ohne DSO-Unterstützung installiert läßt sich das Vorhandensein folgendermaßen überprüfen:

# /usr/local/apache/bin/httpd -l
Compiled-in modules:
....
  mod_auth_digest.c
....

Das Modul mod_digest erfüllt prinzipiell den gleichen Zweck, sollte aber nicht genutzt werden, da es von vielen Web-Browsern nicht unterstützt wird.

Die Verwendung von htdigest verläuft ähnlich wie die von htpasswd. Zunächst ist von dem Anwender eine neue Passwort-Datei zu generieren.

$ /usr/local/apache/bin/htdigest -c .htdigest "Passwortgeschutzter Bereich" dave
Adding password for dave in realm Passwortgeschutzter Bereich.
New password: <passwort>
Re-type new password: <passwort>
$

Anschliessend ist die Datei .htaccess anzulegen, die beispielsweise folgendermaßen aussehen kann:

$ cat .htaccess   
AuthName "Passwortgeschuetzter Bereich"
AuthType Digest
AuthDigestFile /home/carol/public_html/.htdigest
require user dave
$

Hier wird abweichend zum ersten Beispiel als AuthType entsprechend Digest angegeben und der Pfad zu der Datei .htdigest. Mit diesen Schritten wird jede weitere Authentifizierung auf MD5 basieren und die Passworte könne nicht im Klartext abgefangen werden.

Allerdings ist auch diese Variante nicht »das Gelbe vom Ei«. Obwohl, wie in der Dokumentation von Apache nachgelesen werden kann, weitaus mehr Browser unterstützt werden als mit dem Vorgängermodul, werden auch gleichzeitig verschiedene Browser aufgeführt die keine Unterstützung bieten. Dazu gehören unter anderem Netscape und Mozilla. Die Digest-Authentifizierung kann dagegen mit Opera ab Version 4.0 und Internet Explorer ab Version 5.0 durchgeführt werden.

Aus diesem Grund wird als sichere Variante zur Authentifizierung mit SSL-Zertifikaten geraten.




Secure Socket Layer

Das Secure Socket Layer (SSL) Protokoll lässt sich auf zweierlei Arten mittels Apache realisieren. Zum als »Apache-SSL Komplettpaket« und zum anderen mittels dem von Ralf Engelschall entwickelten Zusatzmodul mod_ssl, welches im Allgemeinen häufiger genutzt wird. Dabei handelt es sich mehr um eine »reine Glaubensfrage«, als um etwas anderes. Letztlich bieten beide Lösungen die gleiche Funktionalität.

SSL basiert unter anderem auf der asymmetrischen Verschlüsselung, das bedeutet, dass ein Browser bei dem Aufbau einer HTTPS-Verbindung den öffentlichen Schlüssel des Servers erhält, mit dem alle Daten vom Client zum Server verschlüsselt werden. Damit ein Client der Identität des SSL-Servers vertrauen kann, weist dieser die Korrektheit seines öffentlichen Schlüssels, durch die Bestätigung einer Certification Authority (CA) nach. Die Signaturen der bekannten CAs sind in vielen Browsern bereits importiert, so dass eine lückenlose Überprüfung erfolgen kann. Auf diese Weise kann sichergestellt werden, dass ein Client seine Kreditkartennummer auch dem angenommenen Server übermittelt und die Daten während der Übertragung von Dritten nicht mitgelesen werden können.

Aber auch das umgekehrte Szenario ist denkbar, dass ein Server nur einem beschränkten Kreis von Anwendern Zutritt gewähren möchte. Dazu gibt der Server von ihm selbst oder einer anderen CA generierte Client-Zertifikate aus. Wenn eine SSL-Verbindung aufgebaut wird, kann sich der Client dem Server gegenüber als vertrauenswürdig erweisen. Auf diese Weise wird quasi eine Verbindung des »wechselseitigen Vertrauens« zwischen Client und Server aufgebaut.




Zertifikat generieren

Das SSL-Protokoll basiert auf asymmetrischer Kryptographie. Jeder Kommunikationsteilnehmer, insbesondere der SSL-Server, benötigt zunächst ein Schlüsselpaar, bestehend aus privatem und öffentlichen Schlüssel. Im Zusammenhang mit den Schlüsseln ist insbesondere folgendes zu beachten:

Die benötigten Schlüssel werden mit dem OpenSSL-Paket erzeugt, welches beispielsweise wie folgt aufgerufen werden kann,

# openssl genrsa -des3 -out server.key 1024

Bei diesem Aufruf ein RSA-Schlüsselaar mit einer Länge von 1024 Bit (default 512 Bit) erzeugt und als in der Datei key.pem abgespeichert. Der private Schlüssel wird zusätzlich mit einem Kennwort geschützt, welches bei jeder Freigabe (beispielsweise bei jedem Start des SSL-Servers) einzugeben ist. Der private Schlüssel kann auch »ungeschützt« abgelegt werden (Aufruf ohne die Option -des3).

In der »ersten Testphase« ist es mitunter hilfreich, den privaten Schlüssel zunächst nicht mit einer Passphrase zu versehen. Soll diese zu einem späteren Zeitpunkt vergeben werden, ist folgende Befehlsfolge aufzurufen:

# openssl -in server.key -des3 -out new_server.key

Analog dazu kann eine bestehende Passphrase auch wieder »entfernt« werden.

# openssl -in server.key -out new_server.key

Mit dem Schlüssel kann ein selbstsigniertes Server-Zertifikat mit dem folgenden Aufruf erzeugt werden:

# openssl req -new -x509 -days 730 -key server.key -out server.crt

Nachdem das Programm aufgerufen wurde, werden verschiedene Angaben abgefragt, aus denen sich der sogenannte Distinguished Name (DN) zusammensetzt. Die jeweiligen Attribute hierzu werden in der Datei openssl.cnf festgelegt. Bei der Angabe des Common Name (CN) ist zu beachten, dass hier die Bezeichnung der Domain angegeben wird, da andernfalls das Zertifikat von anfragenden Web-Browsern nicht überprüft werden kann. Mit Ausnahme des CN (im Zusammmenhang mit SSL-Zertifikaten) können die Attribute über die Konfiguration individuell angepasst werden.

Das Zertifikat wird in der Datei server.crt gespeichert und hat eine Gültigkeitsdauer von zwei Jahren.

Das Zertifikat kann mit dem folgenden Aufruf angezeigt werden:

# openssl x509 -in server.crt -noout -text



SSL-Zertifikat in Apache einbinden

In diesem Zusammenhang erfolgt deshalb an dieser Stelle lediglich der Hinweis, dass sich die Dateien server.crt und server.key, in den mit den Direktiven

SSLCertificateFile     <pfad zu>server.crt
SSLCertificateKeyFile  <pfad zu>server.key

angegeben Verzeichnissen befinden. Die Dateirechte für diese Dateien sollten so restriktiv wie möglich gesetzt werden.

Anschließend kann Apache neu gestartet werden und das Zertifikat mit der URL https://.... getestet werden.




Client-Zertifikat

Damit sich ein Client gegenüber dem SSL-Server mit einem Zertifikat authentifizieren kann, ist ein sogenannter Request (Anfrage) zu erzeugen. Dieser wird anschließend, nach der Überprüfung der Identität des Client und den Zertifikatsangaben, mit dem öffentlichen Schlüssel einer CA signiert.

Als erstes ist auch hier zunächst ein Schlüsselpaar zu generieren:

$ openssl genrsa -des3 -out dave.key

Durch den folgenden Aufruf wird der Request erzeugt:

$ openssl req -new -key dave.key -out dave.req

Nachdem der Befehl aufgerufen wurde wird zunächst nach der Passphrase für den privaten Schlüssel gefragt und anschließend sind die Attribute zu setzen, aus denen sich der DN zusammensetzt.

Analog kann auch mit dem Server-Zertifikat verfahren werden, wenn dies nicht selbstsigniert sondern von einer kommerziellen CA oder eigenen Root-CA signiert werden soll.

Der Request des Anwenders dave kann mit dem öffentlichen Schlüssel des Servers wie folgt signiert werden:

# openssl ca -cert server.crt -keyfile server.key \
    -out dave.crt -in dave.req

Bei diesem Aufruf kann sich eine »kleinere Merkwürdigkeit« bemerkbar machen. OpenSSL setzt voraus, dass in dem in der Konfigurationsdatei zu dir angegebenen Verzeichnis ein Unterverzeichnis newcerts vorhanden ist. Diese wird allerdings bei der Installation nicht angelegt und ist mit mkdir nachzuholen. Anschließend (und evt. weiteren Pfadangaben) sollten sich beim Signieren keinerlei Probleme mehr ergeben.

Die Datei dave.crt enthält das von dem Server signierte Client-Zertifikat des Anwenders dave. Damit sich dieser gegenüber dem SSL-Server mit seinem Zertifikat authentifizieren kann, ist dieses in seinen Web-Browser zu importieren. Dazu ist zuerst das Zertifikat in ein »importierbares Format« umzuwandeln (erfolgt in der Regel ebenfalls bei der CA). Das PKCS#12 Dateiformat kann von den meisten Web-Browsern importiert werden. Dabei handelt es sich um einen Standard, der ein Format definiert, mit dem Zertifikate und Schlüssel außerhalb von Anwendungen gespeichert werden können.

# openssl pkcs12 -export -inkey dave.key -name "Dave" \
    -in dave.crt -certfile server.crt -out dave.p12

Die Datei dave.p12 kann beispielsweise in Netscape über die Menüführung

Sicherheit -> Zertifikate -> Eigene -> Zertifikat importieren

importiert werden.

Abb. 2 - Client-Zertifikat importieren

In diesem Zusammenhang sollte beachtet werden, dass bevor das Client-Zertifikat importiert wird, zunächst das Server-Zertifikat importiert werden muss.




Apache anpassen

Damit zukünftig der Zugang zu den Daten des SSL-Servers nur noch nach erfolgreicher Client-Authtifizierung erfolgt, sind in der Datei httpd.conf die folgenden Direktiven anzugeben:

SSLVerifyClient  require
SSLVerifyDepth   2

Mit der ersten Direktive wird die Vorlage eines gültigen Client-Zertifikats verlangt, abweichend kann hier auch none, optional oder optional_no_ca angegeben werden. Die zweite Angabe legt fest, wie tief die Zertifikatskette überprüft wird, bevor entschieden wird, dass das Zertifikat ungültig ist.




Client-Authentifizierung

Nachdem die Konfigurationsdatei des SSL-Servers entsprechend angepasst wurde, die Zertifikate in Dave's Browser importiert wurden und der Server neu gestartet wurde, erfolgt bei der nächsten Verbindung die folgende Abfrage:

Abb. 3 - Angabe des SSL-Client Zertifikats

Anschließend ist das entsprechende Zertifikat auszuwählen und bei positiver Überprüfung des Servers wird der Zugang gewährt. Andernfalls wird der Zugang abgelehnt.

Abb. 4 - Angabe des SSL-Client Zertifikats




Fazit

Die Authentifizierung von Web-Clients mittels Apache wurde auf zwei verschiedene Arten dargestellt, wobei sich die Passwort-Authentifizierung als einfachere und unsichere Methode gegenüber den Möglichkeiten im Zusammenhang mit Zertifikaten erwiesen hat. In diesem Zusammenhang ist allerdings zu beachten, dass es sich bei dem Beispiel nur um einen »kurzen Abriss« handelt und nicht um eine parxisgerechte Endlösung. Das OpenSSL-Paket bietet insgesamt eine Vielzahl von Möglichkeiten, die jeweils individuell anzupassen sind.

Weitere Anhaltspunkte bieten die Seiten von Apache und mod_ssl.




| Home | Artikel | Bücher | Touren | Photos | Impressum |
Rücksprachen, Anmerkungen, Anregungen, .... bitte an info@noatun.net