APACHE-Webserver und SSL-Authentifizierung
Verfasser: Jaroslav Imrich
Dieser Artikel beschreibt Konfigurationstechniken des Moduls mod_ssl , das eine Funktionalität von Apache HTTPD erweitert , um das SSL-Protokoll zu unterstützen. Der Artikel befasst sich mit der Authentifizierung von Servern (Einweg-SSL-Authentifizierung) sowie mit der Authentifizierung von Clients mithilfe von Zertifikaten (Zweiweg-SSL-Authentifizierung).
Einführung
Wenn Sie sich entschieden haben, ein SSL-Protokoll (Secure Sockets Layer) auf Ihrem Webserver zu aktivieren, möchten Sie möglicherweise dessen Funktionalität erweitern, um die Integrität und Vertraulichkeit der in ungesicherten Netzwerken übertragenen Daten zu gewährleisten. Dieses Protokoll mit der Kombination von PKI-Prinzipien (Public Key Infrastructure) kann jedoch neben der Integrität und Vertraulichkeit auch eine Authentifizierung zwischen beiden Seiten ermöglichen, die an der Client-Server-Kommunikation beteiligt sind.
Mit der Einweg-SSL-Authentifizierung kann ein SSL-Client die Identität des SSL-Servers bestätigen. Der SSL-Server kann jedoch keine Identität des SSL-Clients bestätigen. Diese Art der SSL-Authentifizierung wird vom HTTPS-Protokoll verwendet, und viele öffentliche Server auf der ganzen Welt bieten auf diese Weise Dienste wie Webmail oder Internetbanking an. Die SSL-Clientauthentifizierung erfolgt auf einer „Anwendungsschicht“ des OSI-Modells, indem der Client Authentifizierungsdaten wie Benutzername und Kennwort eingibt oder eine Grid-Karte verwendet.
Die bidirektionale SSL-Authentifizierung, auch als gegenseitige SSL-Authentifizierung bezeichnet, ermöglicht es dem SSL-Client, die Identität des SSL-Servers zu bestätigen, und der SSL-Server kann auch die Identität des SSL-Clients bestätigen. Diese Art der Authentifizierung wird als Clientauthentifizierung bezeichnet, da der SSL-Client seine Identität dem SSL-Server unter Verwendung des Clientzertifikats anzeigt. Die Clientauthentifizierung mit einem Zertifikat kann eine weitere Sicherheitsebene hinzufügen oder sogar die Authentifizierungsmethode wie Benutzername und Kennwort vollständig ersetzen.
In diesem Dokument wird die Konfiguration beider Arten der Einweg-SSL-Authentifizierung und der Zweiweg-SSL-Authentifizierung erläutert.
Ausstellung von OpenSSL-Zertifikaten
In diesem Abschnitt wird kurz beschrieben, wie Sie alle erforderlichen Zertifikate mit einer openssl-Anwendung erstellen. Der gesamte Prozess der Ausstellung von OpenSSL-Zertifikaten ist einfach. Für den Fall, dass eine größere Anzahl von ausgestellten Zertifikaten erforderlich ist, wäre das unten beschriebene Verfahren unzureichend. Daher empfehle ich für diesen Fall die Verwendung des CA-Moduls von OpenSSL . Es wird erwartet, dass der Leser über Grundkenntnisse in PKI verfügt. Aus diesem Grund werden alle Schritte nur kurz beschrieben. Bitte folgen Sie diesem Link, wenn Sie Ihr Wissen über die Public-Key-Infrastruktur auffrischen möchten .
Alle Zertifikate werden mithilfe der OpenSSL-Anwendung und der Konfigurationsdatei openssl.cnf ausgestellt. Bitte speichern Sie diese Datei in einem Verzeichnis, in dem Sie alle openssl-Befehle ausführen würden. Bitte beachten Sie, dass diese Konfigurationsdatei optional ist und wir sie nur verwenden, um den gesamten Prozess zu vereinfachen.
openssl.cnf:
[ req ]
default_md = sha1
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = Country
countryName_default = SK
countryName_min = 2
countryName_max = 2
localityName = Locality
localityName_default = Bratislava
organizationName = Organization
organizationName_default = Jariq.sk Enterprises
commonName = Common Name
commonName_max = 64
[ certauth ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
crlDistributionPoints = @crl
[ server ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
nsCertType = server
crlDistributionPoints = @crl
[ client ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = clientAuth
nsCertType = client
crlDistributionPoints = @crl
[ crl ]
URI=http://testca.local/ca.crl
Als ersten Schritt müssen Sie eine selbstsignierte Zertifikatzertifizierungsstelle generieren. Sobald Sie zur Eingabe des Werts "Common Name" aufgefordert werden, fügen Sie die Zeichenfolge "Test CA" ein:
# openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes \
-keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer
Wenn Sie beim Ausführen des obigen Befehls keine Komplikationen festgestellt haben, finden Sie in Ihrem aktuellen Verzeichnis eine Datei "ca.key" mit dem privaten Schlüssel der Zertifizierungsstelle (CA) und ca.cer mit dem selbstsignierten Zertifikat.
Im nächsten Schritt müssen Sie einen privaten SSL-Schlüssel für den Server generieren:
# openssl genrsa -out server.key 2048
Um eine Zertifikatsignierungsanforderung im PKCS # 10-Format zu generieren, verwenden Sie den folgenden Linux-Befehl als allgemeinen Namen. Sie können den Hostnamen angeben, z. B. "localhost".
# openssl req -config ./openssl.cnf -new -key server.key -out server.req
Mit selbstsignierter Zertifizierungsstelle Serverzertifikat mit der Seriennummer 100 ausstellen:
# openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key \
-set_serial 100 -extfile openssl.cnf -extensions server -days 365 -outform PEM -out server.cer
Die neue Datei server.key enthält den privaten Schlüssel des Servers und die Datei server.cer ist selbst ein Zertifikat. Die Zertifikatssignierungsanforderungsdatei server.req wird nicht mehr benötigt, sodass sie entfernt werden kann.
# rm server.req
Generierten privaten Schlüssel für SSL-Client:
# openssl genrsa -out client.key 2048
Was den Server auch für den Client betrifft, müssen Sie eine Zertifikatsignierungsanforderung generieren. Als allgemeinen Namen habe ich die Zeichenfolge "Jaroslav Imrich" verwendet.
# openssl req -config ./openssl.cnf -new -key client.key -out client.req
Stellen Sie mit Ihrer selbstsignierten Zertifizierungsstelle ein Client-Zertifikat mit der Seriennummer 101 aus:
# openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key \
-set_serial 101 -extfile openssl.cnf -extensions client -days 365 -outform PEM -out client.cer
Speichern Sie den privaten Schlüssel und das Zertifikat des Clients in einem PKCS # 12-Format. Dieses Zertifikat wird durch ein Kennwort gesichert und dieses Kennwort wird in den folgenden Abschnitten verwendet, um das Zertifikat in den Zertifikatmanager des Webbrowsers zu importieren:
# openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12
Die Datei "client.p12" enthält einen privaten Schlüssel und das Zertifikat des Clients. Daher werden die Dateien "client.key", "client.cer" und "client.req" nicht mehr benötigt, sodass diese Dateien gelöscht werden können.
# rm client.key client.cer client.req
Einweg-SSL-Authentifizierung
Sobald der private Schlüssel und das Zertifikat des Servers bereit sind, können Sie mit der SSL-Konfiguration des Apache-Webservers beginnen. In vielen Fällen besteht dieser Prozess aus zwei Schritten: Aktivieren von mod_ssl und Erstellen eines virtuellen Hosts für Port 443 / TCP.
Das Aktivieren von mod_ssl ist sehr einfach. Sie müssen lediglich die Datei httpd.conf öffnen und das Kommentarzeichen aus der Zeile entfernen:
LoadModule ssl_module modules/mod_ssl.so
Nur weil der Server die HTTPS-Anforderungen an Port 443 in bedient, ist es wichtig, Port 433 / TCP in der Konfigurationsdatei der Apachen durch Hinzufügen einer Zeile zu aktivieren:
Listen 443
Die Definition eines virtuellen Hosts kann auch in der Datei "httpd.conf" definiert werden und sollte wie folgt aussehen:
ServerAdmin [email protected]
DocumentRoot /var/www
Options FollowSymLinks
AllowOverride None
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
LogLevel warn
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/ssl_access.log combined
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.cer
SSLCertificateKeyFile /etc/apache2/ssl/server.key
BrowserMatch ".*MSIE.*"
nokeepalive ssl-unclean-shutdown
downgrade-1.0 force-response-1.0
Im obigen Beispiel aktiviert die Direktive "SSLEngine on" den virtuellen Host mit SSL-Unterstützung. Die Direktive "SSLCertificateFile" definiert einen vollständigen Pfad des Serverzertifikats und schließlich definiert die Direktive "SSLCertificateKeyFile" einen vollständigen Pfad zum privaten Schlüssel des Servers. Wenn der private Schlüssel durch ein Passwort gesichert ist, wird dieses Passwort nur beim Starten des Apache-Webservers benötigt.
Alle Änderungen an der Datei https.conf, wie die obigen Änderungen, erfordern einen Neustart des Webservers. Wenn beim Neustart Probleme auftreten, liegt dies wahrscheinlich an Konfigurationsfehlern in Ihrer https.conf-Datei. Der tatsächliche Fehler sollte im Fehlerprotokoll von deamon angezeigt werden.
Das Testen einer Funktionalität unserer neuen Konfiguration kann mithilfe eines Webbrowsers erfolgen. Der erste Versuch, eine Verbindung herzustellen, zeigt mit Sicherheit eine Fehlermeldung an, dass der Versuch, das Serverzertifikat zu überprüfen, fehlgeschlagen ist, da der Aussteller des Zertifikats unbekannt ist.
Durch das Importieren des CA-Zertifikats in den Webbrowser mithilfe des Zertifikatmanagers wird dieses Problem behoben. Um einem Mozilla Firefox-Browser ein Zertifikat hinzuzufügen, navigieren Sie zu "Einstellungen> Erweitert> Verschlüsselung> Zertifikate anzeigen> Berechtigungen" und aktivieren Sie während des Imports das Kontrollkästchen "Dieses Zertifikat kann Websites identifizieren".
Der nächste Versuch, eine Verbindung zum Webserver herzustellen, sollte erfolgreich sein.
Wenn Sie vermeiden möchten, dass das Zertifikat einer Zertifizierungsstelle in den Webbrowser importiert werden muss, können Sie ein Serverzertifikat von einer kommerziellen Behörde kaufen, deren Zertifikate vom Webbrowser verteilt werden.
Zweiwege-SSL-Authentifizierung
Wenn Sie entschieden haben, dass Sie von jedem Client eine Zertifikatauthentifizierung benötigen, müssen Sie lediglich die folgenden Zeilen in eine Konfigurationsdatei für den virtuellen Host einfügen:
SSLVerifyClient require
SSLVerifyDepth 10
SSLCACertificateFile /etc/apache2/ssl/ca.cer
Die Anweisung "SSLVerifyClient require" stellt sicher, dass Clients, die kein gültiges Zertifikat von einigen der vertrauenswürdigen Zertifizierungsstellen bereitstellen, nicht mit dem SSL-Server kommunizieren können. Einige Zertifizierungsstellen verlassen sich auf eine andere Zertifizierungsstelle, die sich möglicherweise noch auf eine andere usw. stützt. Die Anweisung "SSLVerifyDepth 10" gibt an, wie weit unten in der Kette der CA-Abhängigkeit der Server das von der CA signierte Zertifikat als gültig akzeptiert. Wenn beispielsweise die Anweisung SSLVerifyDepth den Wert 1 enthält, muss das Client-Zertifikat direkt von Ihrer vertrauenswürdigen Zertifizierungsstelle signiert werden. In diesem Artikel wird das Client-Zertifikat direkt von der Zertifizierungsstelle signiert. Daher ist der einzig sinnvolle Wert für die SSLVerifyDepth-Direktive 1. Die letzte Direktive "SSLCACertificateFile" gibt einen vollständigen Pfad zu einem Zertifikat der Zertifizierungsstelle an, mit dem das Zertifikat eines Clients signiert wurde.
Vergessen Sie nicht, Ihren Apache-Webserver nach Änderungen an den Konfigurationsdateien neu zu starten:
# apachectl graceful
Wenn Sie versuchen, ohne Client-Zertifikat eine Verbindung zum SSL-Server herzustellen, wird eine Fehlermeldung angezeigt:
Sie müssen lediglich ein zuvor erstelltes Client-Zertifikat in PKCS # 12-Form in den Zertifikatmanager von Firefox im Abschnitt „Ihre Zertifikate“ importieren. Diese Aufgabe können Sie ausführen, indem Sie zum Menü und dann zu "Einstellungen> Erweitert> Verschlüsselung> Zertifikate anzeigen> Ihre Zertifikate" navigieren. Während des Imports werden Sie aufgefordert, ein Kennwort einzugeben, das bei der Erstellung des Zertifikats festgelegt wurde. Abhängig von der von Ihnen verwendeten Browserversion müssen Sie möglicherweise auch das Hauptkennwort für das Software-Token festlegen, das vom Browser zum sicheren Speichern von Zertifikaten verwendet wird.
Wenn Sie erneut versuchen, eine Verbindung zum SSL-Server herzustellen, zeigt der Browser automatisch ein entsprechendes Zertifikat für die SSL-Serverauthentifizierung an.
Nach Auswahl eines gültigen Zertifikats wird die Verbindung zum SSL-Server gewährt.
Ein weiterer Vorteil der SSL-Authentifizierung
Werte aus einem Client-Zertifikat können von der Webanwendung zur genauen Identifizierung des Benutzers verwendet werden. Es ist einfach, eine Direktive "SSLOptions + StdEnvVars" zu verwenden, und mode_ssl liefert Informationen aus einem Client-Zertifikat sowie ein Zertifikat selbst an die angegebene Webanwendung.
Dieser Vorgang nimmt viel Laufzeit des Servers in Anspruch. Daher wird empfohlen, diese Funktion für Dateien mit einer bestimmten Erweiterung oder für Dateien in einem bestimmten Verzeichnis zu verwenden, wie im folgenden Beispiel gezeigt:
SSLOptions +StdEnvVars
SSLOptions +StdEnvVars
Eine Liste der verfügbaren Variablen finden Sie in der Dokumentation zu mod_ssl. Zugriff auf Variablen, sofern meine mod_ssl sprachspezifisch ist. Der Vollständigkeit halber finden Sie hier ein Beispiel eines in Perl geschriebenen CGI-Skripts, das einen „allgemeinen Namen“ des Clients anzeigt:
#!/usr/bin/perl
use strict;
print "Content-type: text/htmln";
print "n";
print $ENV{"SSL_CLIENT_S_DN_CN"}
Hier ist eine Ausgabe des Skripts nach seiner Ausführung durch den SSL-Webserver:
Mod_ssl unterstützt auch die Verwendung der oben genannten Variablen direkt aus der Serverkonfiguration. Auf diese Weise können Sie den Zugriff auf bestimmte Ressourcen für Mitarbeiter eines bestimmten Unternehmens einschränken:
SSLRequire %{SSL_CLIENT_S_DN_O} eq “Jariq.sk Enterprises”
Diese Variablen können auch in Verbindung mit der Konfigurationsanweisung "CustomLog" verwendet werden, um die Protokollierung der Zugriffsdetails eines Clients zu ermöglichen. Weitere Informationen finden Sie in der offiziellen mod_ssl-Dokumentation.
Fazit
Wenn Sie noch nichts über die bidirektionale SSL-Authentifizierung gehört haben, haben Sie sich wahrscheinlich nach dem Lesen dieses Artikels gefragt, warum diese Art der SSL-Authentifizierung in der Produktionsumgebung nicht häufig verwendet wird. Die Antwort ist einfach: Kryptische Vorgänge, die bei SSL-Verbindungen verwendet werden, sind im Hinblick auf die Webserverressourcen schwer zu verarbeiten. Es ist möglich, die Leistung des Webservers durch sogenannte SSL-Beschleuniger (Karten mit einem für kryptische Operationen optimierten Prozessor) zu steigern. In vielen Fällen sind SSL-Beschleuniger jedoch teurer als der Server selbst. Daher ist die bidirektionale SSL-Authentifizierung für die Verwendung in der Webserverumgebung nicht attraktiv.
Linux Apache2-spezifische Hinweise:
Das Öffnen eines Ports 443 ist nicht erforderlich, wenn eine Konfigurationsdatei /etc/apache2/ports.conf eine IfModule-Anweisung mod_ssl.c definiert hat:
Listen 443
Das Aktivieren des SSL-Moduls kann erfolgen durch:
a2enmod ssl
Wenn die Direktive IfModule mod_ssl.c in /etc/apache2/ports.conf definiert ist, aktiviert der Befehl a2enmod ssl auch automatisch das Listening auf Port 443.
Die Definition der virtuellen Hostdatei muss geringfügig geändert werden:
BrowserMatch “.*MSIE.*” \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0