freeX: Sichere Verbindungen mit Apache
|
Sichere Verbindungen mit Apache
| |
Ein Teil der Informationen, die zwischen dem Webserver und dem Browser ausgetauscht werden, müssen gesichert werden, damit sie von keiner Stelle zwischen beiden mitgehört werden können. Die Lösung dazu heißt SSL.
|
|
1. Secure Sockets Layer |
Normalerweise laufen alle Verbindungen zwischen einem Browser und einem Webserver unverschlüsselt ab. Daher ist es technisch möglich, daß der gesamte Verkehr von jeder Station, die zwischen Browser und Server liegt, mitgehört werden kann. Das ist normalerweise nur unschön, kann jedoch vernachlässigt werden. Insbesondere wenn lediglich Nachrichten oder Artikel im Web gelesen werden oder eine Suchmaschine bedient wird, ist es vernachlässigbar. Dieser Verkehr hat keine besondere Relevanz und aus dem Mithören können Dritte unmittelbar keine Vorteile ziehen. Natürlich ist es unschön zu wissen, daß andere Personen genau wissen, welche Webseiten man sich anschaut, doch lassen sich diese Informationen nur selten mißbrauchen.
Anders sieht es jedoch dann aus, wenn man sich nicht nur die Waren ansieht, sondern sie auch direkt im Web bestellen möchte. Nicht selten soll dann direkt per Kreditkarte bezahlt werden. In diesem Fall soll man seine Kreditkarten-Nummer und ähnliches auf einer Webseite eingeben, die Daten werden anschließend auf den Server übertragen.
Abbildung 1: SSL wird vor der Applikation eingefügt
Jetzt wird die Sache schon kritisch. Was passiert, wenn jemand diese Nummer mitgelesen hat? Kann vielleicht eine dritte Person mit meiner Kreditkarte einkaufen? Sie wurde in ein normales Web-Formular eingetragen und mit POST an den Webserver übermittelt. Die Kreditkarten-Nummer aus dem Datenstrom herauszufiltern ist mit etwas Programmierarbeit kein Problem, es gibt bestimmt schon fertige Tools, mit deren Hilfe Form-Daten aus mitgeschnittenem HTTP-Verkehr visualisiert werden.
Derartige Verbindungen im World Wide Web sollten daher auf jeden Fall verschlüsselt werden, so daß ein sogenannter Sniffer in der Mitte nicht in der Lage ist, aus dem mitgeschnittenen Datenstrom die Original-Daten zu extrahieren. Eine herkömmliche HTTP-Verbindung wird jedoch nicht verschlüsselt. Hier muß also anders vorgegangen werden.
Secure Sockets Layer
Der Schlüssel zum Erfolg liegt in der Verwendung einer weiteren Netzwerkschicht oberhalb der bisherigen, jedoch vor dem Anwendungs-Protokoll HTTP: dem Secure Sockets Layer (SSL). Wird dieses in Verbindung mit dem HTTP-Protokoll verwendet, dann findet der gesamte Informationsaustausch zwischen dem Webserver und dem Browser verschlüsselt statt. Um diese Art vom herkömmlichen HTTP-Protokoll zu unterscheiden, wird es HTTPS genannt, URLs beginnen mit dem Protokoll »https« anstatt »http«. Damit die Unterscheidung auch für die Software deutlich ist, wird ein anderer als der HTTP-Port (80) verwendet. Für HTTPS ist der TCP-Port 443 vorgesehen.
Die eigentliche Verschlüsselung übernimmt OpenSSL, eine freie Implementierung von SSL. Für den Webserver Apache gibt es zwei Implementierungen dazu. Das getrennte Projekt »apache-ssl« enthält gleich von Anfang an die Unterstützung für SSL. Änderungen am Apache müssen jedesmal in dieses Projekt getrennt aufgenommen werden. Die zweite Implementierung ist ein eigenständiges Modul »mod_ssl.so«, das ebenfalls getrennt vom Apache entwickelt und gewartet wird. Dieses muß nur zum jeweiligen Apache hinzugeladen werden.
Es sollte die zweite Variante verwendet werden, auf die im folgenden näher eingegangen wird. Bei dieser muß das Projekt nicht mühsam alle Änderungen im Apache wieder und wieder übernehmen, was die Pflege und Entwicklung des Moduls erheblich erleichtert. Das Modul wird separat von modssl.org bezogen oder es ist in der Distribution bereits enthalten (z.B. bei Debian: »libapache-mod-ssl« aus dem Archiv non-US, zu installieren mit »apt-get install libapache-mod-ssl«).
|
Falls das Modul nicht in der verwendeten Distribution enthalten ist und auch nicht von Dritt-Anbietern zur Verfügung gestellt wird, muß es direkt vom Quellcode installiert werden. Dazu wird das Quellcode-Paket zuerst von http://www.modssl.org/ als ».tar.gz«-Datei gezogen. Anschließend wird es mit »tar xfz« ausgepackt. Zu beachten ist, daß das mod_ssl-Paket zur Version vom Apache passen muß. Zu welcher Apache-Version es paßt, geht aus der Versionsnummer hervor (im Beispiel unten wird von der Version z.B. 1.3.20 vom Apache ausgegangen). Wenn sowohl die Entwickler-Pakete zum Apache, OpenSSL und libssl installiert sind, geht es weiter mit dem Aufruf des »configure«-Skriptes: ./configure --with-ssl=SYSTEM --with-apxs=/usr/bin/apxs Der Pfad muß möglicherweise an die lokalen Gegebenheiten angepaßt werden. Nach dem Aufruf steht ein »Makefile« zur Verfügung, mit dem das Paket nun durch dem Aufruf von »make« übersetzt wird. Wenn soweit alles geklappt hat, wird das Paket anschließend mit »make install« installiert. $ wget http://www.modssl.org/source/mod_ssl-2.8.4-1.3.20.tar.gz $ tar xfz mod_ssl-2.8.4-1.3.20.tar.gz $ cd mod_ssl-2.8.4-1.3.20 $ ./configure --with-ssl=SYSTEM --with-apxs=/usr/bin/apxs $ make $ sudo make install | |
| mod_ssl selbst compilieren | |
Schlüssel und Zertifikat erstellen
Nach der Installation muß ein Zertifikat samt Schlüsseln erstellt werden, die von diesem Modul bei jedem Start gelesen werden. Mit Hilfe dieser Schlüssel und Zertifikate wird jede Verbindung zwischen Browser und Webserver authentifiziert. Eine Certificate Authority (CA) stellt normalerweise sicher, daß die Organisation, zu der der Schlüssel gehört, tatsächlich die angegebene Organisation (oder Person) ist. Der Schlüssel muß daher von einer CA unterschrieben werden.
Die meisten Browser sind so eingestellt, daß sie bekannten CA's (z.B. VeriSign oder Thawte) von vornherein vertrauen. Wenn das Zertifikat daher von einer bekannten CA unterschrieben ist, kann der Browser den Schlüssel des Webservers automatisch verifizieren und als richtig einstufen.
Gültige Schlüssel und Zertifikate zu erstellen, ist etwas umständlich, es sind mehr Einstellungen vorzunehmen als z.B. bei der Erstellung eines GnuPG-Schlüssels. Um es für den Administrator einfacher zu machen, haben die Entwickler des mod_ssl-Moduls ein Skript beigelegt, das den automatisierbaren Teil der Schlüssel-Generierung übernimmt.
Am einfachsten ist es daher, das Zertifikat mit dem Skript »mkcert.sh« anzulegen (liegt im Quellcode im Verzeichnis »pkg.sslsup«). Das Programm benötigt beim Aufruf 10 Parameter, die auf der Kommandozeile übergeben werden müssen. Das folgende Beispiel kann als Richtwert genommen werden. Dabei liegt die Konfiguration vom Apache in »/etc/apache« und die Module liegen in »/usr/lib/apache«. Snake Oil ist das von mod_ssl verwendete Beispiel, eine nicht-existierende Organisation mit dem Namen eines angeblichen Wunder-Elixiers, das natürlich nicht hält, was es verspricht.
mkcert.sh make "" openssl /usr/lib/apacheRSA "" "" "" /etc/apache
Als Typ wird einer der folgenden Werte angegeben:
| 1 | Spiel-Zertifikat, selbstunterschriebenes Snake Oil-Zertifikat |
| 2 | Test-Zertifikat, unterschrieben von der Snake Oil CA |
| 3 | Eigenes Zertifikat, unterschrieben von eigener CA |
| 4 | Ein bestehendes Zertifikat |
| Tabelle 1: Zertifikat-Typen | |
Typ 4 ist für Zertifikate von bekannten CA's vorgesehen. Zum Testen bieten sich 1 oder 2 an. Benutzer der Debian-Distribution haben es bei der Generierung etwas leichter, sie müssen lediglich das Programm »mod-ssl-makecert« ohne Parameter aufrufen, das den obigen Aufruf selbständig vornimmt.
Während der Erstellung des Zertifikats müssen Sie, abhängig vom verwendeten Typ, weitere Einstellungen vornehmen, in welchem Land Sie sich befinden, wie die Organisation heißt, wie Sie per Mail zu erreichen sind u.s.w. Der Schlüssel selbst kann (und sollte) zum Schluß mit einer Passphrase verschlüsselt auf der Festplatte gespeichert werden.
Modul einbinden
Als nächstes wird das Modul in die Konfiguration des Web-Servers eingebunden. Dazu wird es zusammen mit den anderen Modulen in die Konfigurationsdatei »/etc/apache/httpd.conf« aufgenommen. Der Eintrag sollte ungefähr wie folgt aussehen:
LoadModule ssl_module /usr/lib/apache/1.3/mod_ssl.so
Zusätzlich sollten Sie das »setenvif«-Modul installieren. Falls es noch nicht geladen wird, aktivieren Sie es mit der folgenden Zeile in der gleichen Datei:
LoadModule setenvif_module /usr/lib/apache/1.3/mod_setenvif.so
Ist auch dieses Modul eingebunden, wird eingestellt, daß der Webserver nicht nur auf dem normalen HTTP-Port auf Anfragen warten soll, sondern auch auf dem speziellen HTTPS-Port 443. Das geschieht mit dem folgenden bedingten Block, der ebenfalls in die Datei »httpd.conf« geschrieben wird:
<IfModule mod_ssl.c> Listen 80 Listen 443 </IfModule>
Prinzipiell muß dieses Konstrukt nicht verwendet werden. Sollte das SSL-Modul versehentlich entfernt werden, bleibt die Apache-Konfiguration so jedoch gültig. Die folgenden zusätzlichen Anweisungen werden daher auch jeweils in einem bedingen Block geschrieben. Alternativ werden lediglich die beiden »Listen«-Zeilen in die Konfigurationsdatei geschrieben.
Als nächstes wird das SSL-Modul konfiguriert. Als funktionierendes Beispiel soll dieser Abschnitt dienen. Auf der beiliegenden CD befindet sich eine kommentierte Variante (»mod-ssl.conf«).
<IfModule mod_ssl.c> AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl SSLPassPhraseDialog builtin SSLSessionCache dbm:/var/run/ssl_scache SSLSessionCacheTimeout 300 SSLMutex file:/var/run/ssl_mutex SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule>
Ein Host pro Zertifikat
Erst jetzt können die virtuellen Hosts konfiguriert werden, so daß auch eine URL der Form »https://server/pfad« vom Webserver erkannt und entsprechend verarbeitet wird. Zu beachten ist an dieser Stelle, daß pro IP-Nummer nur ein einziges Zertifikat verwendet werden kann. Das Zertifikat ist an den Rechnernamen bzw. an die IP-Nummer gebunden, da die Verschlüsselung vor den eigentlichen HTTP-Befehlen stattfindet und die Schicht, die ver- und entschlüsselt, nicht die Interna des HTTP-Protokolls kennt.
<VirtualHost www.bincool.de:443> <IfModule mod_ssl.c> SSLEngine on SSLCertificateFile /etc/apache/ssl.crt/server.crt SSLCertificateKeyFile /etc/apache/ssl.key/server.key SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown </IfModule> ServerName www.bincool.de ServerAdmin joey@bincool.de DocumentRoot /var/www/www.bincool.de TransferLog /var/log/apache/www.bincool.de/access.log ErrorLog /var/log/apache/www.bincool.de/error.log CustomLog /var/log/apache/www.bincool.de/combined.log combined </VirtualHost>
Wichtig ist bei diesem Eintrag, daß hinter dem Rechnernamen bzw. der IP-Nummer »:443« steht. Damit wird sichergestellt, daß nicht der normale HTTP-Port, sondern der HTTPS-Port für diesen virtuellen Host verwendet wird. Die für SSL spezifischen Einstellungen werden wieder in einen bedingten Block geschrieben. Zum Schluß kommen die normalen Einträge, die man für fast jeden virtuellen Host verwendet.
Abbildung 2: Detail-Informationen zu einem Zertifikat
Wenn die angegebenen Verzeichnisse (insbesondere auch die für die Log-Dateien benötigten) vorhanden sind, wird der Apache neu gestartet. Dazu muß als erstes die Passphrase eingegeben werden, damit das SSL-Modul die verschlüsselten Daten lesen und verarbeiten kann. Jetzt ist der Apache voll funktionsbereit und bearbeitet sowohl HTTP- als auch HTTPS-Anfragen. Wenn ein Browser nun eine »https://«-URL anfordert, wird das neue Zertifikat ausgetauscht und überprüft. Abhängig vom verwendeten Browser muß das Zertifikat manuell akzeptiert werden.
Die Verbindung testen
Eine herkömmliche HTTP-Verbindung testet man üblicherweise direkt mit dem Programm »telnet«. Wenn man einen Fehler reproduzieren und beheben möchte, sollte man keinen Browser, schon gar nicht einen grafischen, benutzen. Je komplexer der Browser aufgebaut ist, desto mehr potentielle Fehlerquellen tun sich einem auf. So kommt man dem eigentlichen Problem nicht unbedingt näher. Leicht verzweifelt man am eingestellten Proxy oder Cache und greift unwissentlich gar nicht auf de Webserver zu, auf dem das eigentliche Problem liegt.
Daher bietet sich für die Fehlersuche das Programm »telnet« an. HTTP ist ein Text-Protokoll, eine HTML-Seite besteht ebenfalls aus Text. Die benötigten HTTP-Befehle sind minimal, so daß man sie sich zudem leicht merken kann. Im Prinzip wird nur der Befehl "GET" benötigt, der als Parameter einen Pfad oder eine URL sowie die Version des Protokolls erfordert. Der normale Webserver wird somit wie folgt getestet:
telnet localhost 80 GET / HTTP/1.0
Anschließend wird zweimal »Enter« gedrückt. Zurückgeliefert wird nun die Hauptseite des Webservers. Dieses funktioniert mit SSL nicht, obwohl das höhere Protokoll weiterhin HTTP ist. Bevor dort jedoch mit HTTP-Befehlen gearbeitet werden kann, muß zuerst die Verschlüsselung-Schicht durchlaufen werden. Das ist mit »telnet« etwas umständlich.
Abhilfe schafft jedoch OpenSSL, denn die Entwickler haben einen einfachen SSL-Client mitgeliefert. Mit diesem verbindet man sich zum SSL-Webserver, die Ver- und Entschlüsselung wird transparent vorgenommen, so daß man anschließend direkt mit HTTP-Befehlen arbeiten kann. Mit dem folgenden Befehl wird die Verbindung zu einem HTTPS-Server aufgebaut:
openssl s_client -connect:443
Wer zusätzlich Informationen über die ausgetauschten Schlüssel und Zertifikate erhalten möchte, erweitert die Befehlszeile mit »-state -debug«.
Autonomer Neustart
Bei jedem Neustart vom Apache fragt das SSL-Modul nach der Passphrase, die jedesmal erneut eingegeben werden muß. Auf einer Workstation, die nur dann eingeschaltet oder neu gestartet wird, wenn der Besitzer bzw. Administrator neben ihr steht, ist das möglicherweise akzeptabel. Doch wie sieht es aus, wenn es sich um einen Server handelt, der im Maschinensaal steht? Oder wenn der Rechner noch eine Stufe weiter weg steht, beim Provider an einer potenten Anbindung, und so quasi keine Chance besteht, dort eine Tastatur und einen Monitor anzuschließen?
Für diesen Fall muß man sich darauf verlassen, daß das System nicht kompromittiert wird und die bisher verschlüsselte Datei unverschlüsselt auf dem Rechner gespeichert werden darf. Die Datei ist dann nicht mehr gesichert als die Datei »/etc/shadow«, in der die Paßwörter gespeichert sind.
Damit der Apache wieder ohne Interaktion startet, wird die Datei entschlüsselt und anschließend anstatt der bisherigen unverschlüsselt gespeichert. Es reicht nicht aus, ein leeres Paßwort zu verwenden, da der Dialog, der das Paßwort erfragt, kein leeres Paßwort akzeptiert. Wer beim Anlegen des Zertifikats vorausschauend kein Paßwort angegeben hat, darf den Schritt als Übung wiederholen, um im nächsten Schritt die Datei zu entschlüsseln.
Bei der fraglichen Datei handelt es sich um »/etc/apache/ssl.key/server.key«. Von dieser wird zuerst eine Kopie angelegt:
cp server.key server.key.orig
Anschließend wird die Datei entschlüsselt und in der ursprünglichen Datei gespeichert. Dazu wird wieder das OpenSSL-Paket direkt benötigt:
openssl rsa -in server.key.org -out server.key
Die Datei »server.key« ist jetzt nicht mehr verschlüsselt, daher muß unbedingt sichergestellt werden, daß sie nur von »root« gelesen werden kann und nicht von beliebigen Benutzern. Das geschieht zusätzlich mit der folgenden Anweisung:
chmod 400 server.key
Wenn der Webserver von nun an neu gestartet wird, benötigt er nicht mehr die Eingabe der Passphrase und kann somit wieder vollständig autonom starten.