Dem Webserver SSL beibringen

Das Aufsetzen eines Joomla-tauglichen Webservers habe ich ja schonmal ausführlich beschrieben. Jetzt stand ich vor der Aufgabe, diesen Webserver SSL-tauglich zu machen. Ich muss zugeben, von SSL und dem Erstellen von Zertifikaten nur wenig Ahnung zu haben. Dementsprechend bin ich auch erstmal einem Tutorial gefolgt, dass im Nachhinein betrachtet sehr rudimentär ist: Ich hatte ein Zertifikat erstellt, hier was kopiert, da was symbolisch verlinkt, den Apache-Webserver etwas umkonfiguriert und SSL lief. Mit Firefox war dieses Tutorial einigermaßen brauchbar. Ich brauchte das Zertifikat nur einmalig genehmigen und es lief. Der Internet Explorer sieht das allerdings etwas anders. Bei jedem neuen Besuch der Seite, beschwerte dieser sich über Zertifikatsfehler, gegen die auch das Importieren des Zertifikats nicht half.

Dank Chris bin ich dann auf die Fährte des Problems gelangt und seine zahlreichen Links und Tipps haben schlussendlich zum Ziel geführt. Meine Nutzer müssen nun nur noch einmalig ein Zertifikate importieren und werden im Internet-Explorer fortan nicht mehr mit Zertifikatfehlern genervt.
Ich habe übrigens Zertifikate selbst erstellen wollen, weil der Webserver nur in einem internen Netz verwendet wird. Er kann und wird somit nicht aus dem Internet angesprochen, womit ich ein kostenpflichtiges (und problemloses) Zertifikat einer Root-CA wie VeriSign überflüssig fand. Andererseits ist das interne Netz ziemlich groß und wird nicht nur von mir und meinen Nutzern verwendet, so dass ich Wert auf die verschlüsselte Übertragung gelegt habe.

Aus diesem Grund war es notwendig, dass ich mich selbst zu einer Certifcate Authority – kurz CA – mache, um meine selbsterstellten Zertifikate zu signieren. Ein Nutzer der Webseite braucht dann nur das CA-Zertifikat importieren und diesem vertrauen. Alle weiteren Zertifikate, die mit diesem signiert sind, werden dann automatisch als vertrauenswürdig eingestuft.

An dieser Stelle möchte ich nun meine Vorgehensweise zusammenfassen, die ich aus Tipps von Chris, Tutorials und persönlichen Trial&Error gesammelt habe.

Zertifikate ertsellen und signieren

Für das Erstellen der Zertifikate habe ich ein Tutorial von HowToForge verwendet, welches sehr ausführlich ist. Allerdings enthält es keine Anleitung zur Installation und vor allem Konfiguration eines Apache. Diesen Punkt habe ich weiter unten ausgeführt.

Zunächst habe ich stumpf nach Anleitung den Ordner ‚CA‘ und darin ’newcerts‘ und ‚private‘ angelegt. Ich habe dies im Home-Verzeichnis von root gemacht, da theoretisch noch andere Personen den Server administrieren können müssen und mein persönlicher Account nur temporär ist. Des Weiteren darf niemand unberechtigtes Zugriff auf diesen Ordner haben, da er Schlüssel enthalten wird, die geheimgehalten werden müssen. Sollte dieser private Schlüssel in falsche Hände gelangen, sind alle damit signierten Zertifikate nicht mehr vertrauenswürdig und müssen gesperrt werden.

server:~# cd /root
server:~# mkdir CA
server:~# cd CA
server:~# mkdir newcerts private

Im Ordner CA werden nun die Dateien ’serial‘ und ‚index.txt‘ erzeugt. ’serial‘ dient – wie der Name schon andeutet – als Quelle für eindeutige Seriennummer und wird bereits beim erstellen mit ’01‘ belegt. Jedesmal wenn ein Zertifikat erstellt wird, wird diese Ziffer automatisch hochgezählt. ‚index.txt‘ stellt eine kleine Datenbank dar, in der meine erstellten Zertifikate verwaltet werden.

server:~# echo '01' >serial
server:~# touch index.txt

Als nächstes wird eine Konfigurationsdatei namens ‚openssl.cnf‘ erstellt

server:~# vi openssl.cnf

und mit folgenden Inhalt befüllt

#
# OpenSSL Konfigurationsdatei
#
dir = .

[ ca ]
default_ca    = CA_default

[ CA_default ]
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/cacert.pem
private_key = $dir/private/cakey.pem
default_days = 365
default_md = md5
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
default_bits = 1024 # size of keys
default_keyfile = key.pem # name of genarted keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
# Variable name          Prombt string
#---------------------      --------------------
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name
stateOrProvinceName = Province or State
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name
commonName_max = 64

# Default values for the above,    for the consistency and less typing.
# Variable name            Value
#-----------------------------    ------------------------------------
0.organizationName_default = Meine Firma
localityName_default = Meine Stadt
stateOrProvinceName_default = Mein Bundesland
countryName_default = DE

[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always

[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash

Konfigurationsdatei zum Download (muss anschließend in openssl.cnf umbenannt und an die eigenen Gegebenheiten angepasst werden).

Die Bedeutung der einzelnen Abschnitte können oben erwähnten HowTo entnommen werden. Ab jetzt werden Zertifikate erstellt. Als erstes wird das Zertifikat und der private Schlüssel der CA erstellt:

server:~# openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem↵
-out cacert.pem -days 3650 -config ./openssl.cnf

Mit ‚req -x509‘ wird das eigentliche Zertifikat generiert, ‚-extensions v3_ca‘ gibt dabei die Art des Zertifikats an, wie es im entsprechenden Abschnitt der Konfiguration angegeben ist (hier also ein CA-Zertifikat mit Passwort). Der private Schlüssel wird in das ‚private‘-Verzeichnis geschrieben, des Zertifikat selbst in den aktuellen Ordner. Das Zertifikat der CA selbst erhält eine Lebensdauer von 10 Jahren. Das ist durchaus sinnvoll, da mit Ablauf des CA-Zertifikats alle damit signierten Zertifikate ihre Gültigkeit verlieren würden. Die Gültigkeit der einzelnen Zertifikate ist in der Konfigurationsdatei mit ‚default_days = 365‘ auf ein Jahr festgelegt.

Im nächsten Schritt wird der Zertifikats-Request erstellt, mit dem zukünftig der Webserver authentifiziert werden soll.

server:~# openssl req -new -nodes -out req.pem -config ./openssl.cnf

Im folgenden Dialog sind der „Organizational Unit Name“ (OU), die Kontak-Email-Adresse sowie der „Common Name“ (CN) nacheinander anzugeben. Als OU kann man einen Hinweis daruf geben, wofür das Zertifikat gedacht ist (bsp. eben für den Webserver). Der CN ist die IP oder FQDN des Systems, dass mit diesem Zertifikat authentifiziert werden soll. Im Falle des Webservers wäre das genau die Adresse, die man im Browser angeben würde. Ist der CN falsch und stimmt nicht mit der Adresse überein wird sich der Browser über einen Zertifkatfehler beschweren, da er davon ausgeht, dass das Zertifikat missbraucht wird (dieser Fehler ist mir u.a. auch unterlaufen, weshalb der IE sich so penetrant beschwert hat).
Als Ergebnis erhält man zwei Dateien: den privaten Schlüssel des Zertifikats (key.pem) und den Zertifikats-Request (req.pem). Dieser Request kann übrigens wiederverwendet werden, wenn das Zertifikat nach Ablauf der Gültigkeit erneut signiert werden muss. Beide Dateien sollte man also aufheben.

Nun muss der Zertifikats-Request von der selbsterstellten CA signiert werden. Das abgefragte Passwort ist jenes, welches beim Erstellen des CA-Zertifikats zu Beginn vergeben wurde.

server:~# openssl ca -out cert.pem -config ./openssl.cnf -infiles req.pem

Als Output erhält man das Zertifikat (cert.pem) sowie eine Kopie im Ornder ’newcerts‘, welche die aktuelle Seriennummer (aus ’serial‘) als Namen trägt. Die Datenbank ‚index.txt‘ wurde um einen Eintrag erweitert.
Jede Zeile darin steht für ein Zertifikat. In der ersten Spalte steht ein Buchstabe, der das jeweilige Zertifkat als gültig (V wie valid), abgelaufen (E wie expired) oder zurückgezogen (R wie revoked) kennzeichnet. In der zweiten Spalte ist das Ablaufdatum des Zertifikats angegeben in der Form YYMMDDHHmmssZ (wobei Z für Zulu-Zeit steht – also Greenwich Mean Time). Die dritte Spalte enthält das Rückzugsdatum des Zertifikats und ist beim Status V oder E entsprechend leer. Die vierte Zeile enthält die Seriennummer, die aus der ’serial‘ heraus vergeben wurde. Die fünfte Spalte enthält den Speicherort und die sechste Spalte den Distinguished Name (also C,ST,O,OU und CN wie sie im CA-Zertifikat bzw. dem ausgestellten Zertifikat festgelegt wurden).
Die Ausgabedatei enthält nun die verschlüsselte und die lesbare Version des Zertifikats. Um beides zu trennen ist folgendes nötig:

server:~# mv cert.pem tmp.pem
server:~# openssl x509 -in tmp.pem -out cert.pem

Zu guter Letzt muss das CA-Zertifikat an den Nutzer gebracht werden. Je nach Möglichkeiten kann man es auf Netzlaufwerken oder per Mail den Nutzern zukommen lassen. Man kann das Zertifikat aber auch zum Download als crt-Datei anbieten. Dazu reicht es die Datei ‚cacert.pem‘ in das www-Verzeichnis zu kopieren und umzubennen und die Besitzverhältnisse neu zu regeln.

server:~# cp cacert.pem /var/www/meinpfad/beliebiger_name.crt
server:~# chown www-data:www-data /var/www/meinpfad/beliebiger_name.crt

Das Zertifikat kann nun über die entsprechende Web-Adresse abgerufen werden. Beim Öffnen des Zertifikats wird man in der Regel automatisch durch die lokale Installation geführt. Anschließend sollten alle damit signierten Zertifikate anstandslos von IE und Firefox akzeptiert werden.

Apache SSL-fähig machen

Um den Apache SSL-fähig zu machen, bin ich wie folgt vorgegangen. Ich habe zunächst im Apache-Ordner ein Verzeichnis für Zertifikate angelegt und mein Zertifikat nebst Schlüssel dorthin kopiert.

server:~# mkdir /etc/apache2/ssl
server:~# cp /root/CA/cert.pem /etc/apache2/ssl/cert.pem
server:~# cp /root/CA/key.pem /etc/apache2/ssl/key.pem

Im Ordner ‚/etc/apache2/sites-available‘ habe ich nun eine neue Datei namens ’ssl‘ angelegt

server:~# vi /etc/apache2/sites-available/ssl

und mit folgendem Inhalt befüllt:

<VirtualHost *:443>
DocumentRoot "/var/www/pfad"
  <Directory "/var/www/pfad">
    allow from all
    Options +Indexes
  </Directory>
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/key.pem
</VirtualHost>

Nun noch einen Link unter ’sites-enabled‘ auf die eben erstellte Datei setzen

server:~# ln -s /etc/apache2/sites-available/ssl /etc/apache2/sites-enabled/ssl

Damit der Apache auch weiß, dass er auf Port 443 lauschen soll, notiert man dies in der ‚/etc/apache2/ports.conf‘ mit

Listen 443

Abschließend muss das SSL-Modul akitiviert und Apache neu gestartet werden

server:~# a2enmod ssl
server:~# /etc/init.d/apache2 restart

Alternativ kann man diese Konfiguration auch im Webmin vornehmen. Ab diesem Zeitpunkt sollte der Webserver SSL-verschlüsselt laufen.

Ich hoffe, das ich nichts vergessen oder durcheinander gebracht habe. Wenn doch, möge man mich kurz per Mail, Kommentar oder Twitter darauf hinweisen und ich arbeite dann die Korrektur ein. Ich kann Fehler – gerade im Bereich Apache – nicht aussschließen, da ich durch ein zu schnelles ‚Enter‘ mir zwischenzeitlich die komplette Apache-Konfigurations zerschossen habe.
U.a. bekam ich auch die Fehlermeldung „Could not bind on address [::]:443“ beim Start des Apache, was daran lag, dass – warum auch immer – in der ‚ports.conf‘ zweimal der Eintrag ‚Listen 443‘ stand.

2 Comments

  • Landon Wickizer

    7. September 2011 at 7:10 Antworten

    Ich habe seit ein paar Monaten einen Internetshop in Betrieb genommen. Jetzt läuft der Shop an und die ersten Kunden kaufen ein. Bis jetzt habe ich mir aber noch keinen Kopf um die Sicherheit der Daten von meinen Kunden gemacht. Bei einem Bekannten der auch einen Onlineshop hat gab es schon Komplikationen deswegen hat er sich eine Stapel-Signatur installieren lassen. Was denkt ihr ab wann rentiert es sich so ein Zertifikat zu erwerben und einzusetzen ??

    • Pfefferoni

      11. September 2011 at 13:41 Antworten

      Da so ein Zertifikat nicht die Welt kostet und m.E. als betriebliche Ausgabe an- und absetzbar ist, würde ich schon eines kaufen. Es macht einen seröseren Eindruck und man ist im Falle von Datenklau als Anbieter eher auf der sicheren Seite – meine Meinung. Wie das abschließend rechtlich ausschaut, sollte ein Anwalt bewerten 😉

Post a Comment