HTTPS für einen Mac OS X Webserver

Wireshark_Roundcube_Passwort

Wenn man einen Webserver unter Mac OS X betreibt, und ausserdem möchte, dass die gesamte Kommunikation mit diesem verschlüsselt abläuft, wird man sich früher oder später mit dem mod_ssl-Modul des Apache Webservers befassen. Dieses fantastische Stück Software sorgt beispielsweise dafür, dass nicht jeder der im gleichen WLAN sitzt oder sonst irgendwie den Datenverkehr mitschneiden kann, auch die Usernamen, Passwörter oder sonstige interessante Daten frei Haus erhält. In dem oben stehenden Bild ist mein Login über HTTP schön zu sehen1.

Wie man das ganze unter OS X recht flugs, allerdings auch nicht so richtig geeignet für ein echtes Produktivsystem, hin bekommt wird hier in fünf Schritten beschrieben.

  1. Erstellung einer eigenen Certification Authority (CA)
  2. Erstellung eines Private Key für den Web Server
  3. Erstellung eines Certificate Request für den gerade erstellten Private Key des Webservers
  4. Unterschreiben des Certificate Request mit dem Key der CA
  5. Anpassen der Apache-Configs

Weiter geht es nach dem Klick…

Erstellung einer eigenen Certification Authority

Man erstellt auf der Konsole in seinem “Dokumente” Verzeichnis einen neuen Ordner und wechselt hinein. So sind die Zertifikate hübsch ordentlich aufgehoben.

cd ~/Documents mkdir certs cd certs

In diesem Verzeichnis wird dann mit dem CA.pl Script eine neue Certification Authority erstellt.

/System/Library/OpenSSL/misc/CA.pl -newca

CA certificate filename (or enter to create)

Making CA certificate ... Generating a 1024 bit RSA private key .........++++++ .................++++++ writing new private key to './demoCA/private/cakey.pem' Enter PEM pass phrase:

Verifying - Enter PEM pass phrase:

You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank.

Die folgenden Fragen sollte man so beantworten, dass die Herkunft der CA für Besucher des verschlüsselten Servers erkennbar ist. Bei mir etwa so:

Country Name (2 letter code) [AU]:DE State or Province Name (full name) [Some-State]:NRW Locality Name (eg, city) []:Essen Organization Name (eg, company) [Internet Widgits Pty Ltd]:. Organizational Unit Name (eg, section) []:. Common Name (eg, YOUR name) []:Dennis TestCA Email Address []:dennis@instant-thinking.de

Jetzt existiert in dem certs Verzeichnis eine neue CA in einem eigenen Ordner:

certs/ -- demoCA |-- cacert.pem |-- certs |-- crl |-- index.txt |-- newcerts |-- private |-- cakey.pem `-- serial

Erstellung eines Private Key für den Web Server

Mit dem folgenden openssl Befehl wird nun ein private key für den Webserver erstellt.

openssl genrsa -des3 -out webserver.key 1024

Bei der darauf folgenden Passwortabfrage, sollte man eines wählen, das von dem Passwort der CA abweicht.

Generating RSA private key, 1024 bit long modulus ...................++++++ ................++++++ e is 65537 (0x10001) Enter pass phrase for webserver.key: Verifying - Enter pass phrase for webserver.key:

Aus praktischen Gründen wird jetzt noch ein Schlüssel ohne die Passphrase erstellt:

openssl rsa -in webserver.key -out webserver.nopass.key Enter pass phrase for webserver.key: writing RSA key

Der Schlüssel mit Passphrase ist jetzt webserver.key und der ohne ist webserver.nopass.key.

Diese Übung ist nötig, weil ein Webserver der mit einem Zertifikat mit Passphrase verschlüsselt, diese Passphrase bei jedem Neustart des Servers erwartet. Das würde für einen normalen Mac bedeuten, dass der Start des Systems hängt, da der Apache auf die Eingabe der Passphrase wartet. Man kann den Mac zwar im Verbose-Mode booten und die Eingabe vornehmen, komfortabel ist das aber nicht.

Erstellung eines Certificate Request für den gerade erstellten Private Key des Webservers

Für den gerade erstellten Schlüssel wird nun eine Zertifikatsanforderung2 erstellt. Diese wird dann im nächsten Schritt mit dem Schlüssel der CA unterschrieben.

openssl req -config /System/Library/OpenSSL/openssl.cnf -new -key webserver.key -out newreq.pem -days 3650

Bei der folgenden Abfrage ist es wichtig darauf zu achten, dass bei “Common Name (eg, YOUR name)” der wirkliche Name des Servers eingetragen wird, unter dem er auch später erreichbar sein soll. Bei einem Test auf dem lokalen System wäre das z.B. “localhost” oder “127.0.0.1″. Bei einem Test in einem lokalen Netz ohne Namensauflösung z.B. “192.168.1.6″ und bei einem System das unter einem DNS-Namen erreichbar ist eben dieser. Wenn hier nicht der exakt passende Name des Servers steht wird es später zu Zertifikatsfehlern kommen, YMMV.

Die Extra Attribute “challenge password” und “company name” können leer gelassen werden.

Enter pass phrase for webserver.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value,

If you enter '.', the field will be left blank.

Country Name (2 letter code) [AU]:DE State or Province Name (full name) [Some-State]:NRW Locality Name (eg, city) []:Essen Organization Name (eg, company) [Internet Widgits Pty Ltd]:. Organizational Unit Name (eg, section) []:. Common Name (eg, YOUR name) []:meineadresse.de Email Address []:dennis@instant-thinking.de

Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:

Damit wurde die Zertifikatsanforderung newreq.pem erstellt.

Unterschreiben des Certificate Request mit dem Key der CA

Mit dem folgenden Befehl wird das Unterschreiben der Zertifikatsanforderung angestossen:

/System/Library/OpenSSL/misc/CA.pl -signreq

Using configuration from /opt/local/etc/openssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: b4:cd:0a:12:5b:00:5b:2b Validity Not Before: Aug 25 21:19:04 2009 GMT Not After : Aug 25 21:19:04 2010 GMT Subject: countryName = DE stateOrProvinceName = NRW localityName = Essen commonName = meineadresse.de emailAddress = dennis@instant-thinking.de X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 08:F3:5C:D2:0D:96:3E:2F:53:DA:EF:9D:34:73:B2:16:77:83:94:E0 X509v3 Authority Key Identifier: keyid:01:54:22:97:39:C2:41:2D:17:48:41:6D:BB:A1:C7:F0:B3:88:B4:4F

Certificate is to be certified until Aug 25 21:19:04 2010 GMT (365 days) Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Signed certificate is in newcert.pem

Damit ist das Zertifikat newcert.pem erstellt. Jetzt ist es eine gute Idee ein weiteres Verzeichnis mit dem Namen des Servers zu erstellen und alle für ihn erstellten Dateien hinein zu bewegen.

mkdir meineadresse.de mv webserver.key webserver.nopass.key newreq.pem newcert.pem meineadresse.de/

Das ganze schaut dann etwa so aus:

certs/ |-- demoCA | |-- cacert.pem | |-- certs | |-- crl | |-- index.txt | |-- index.txt.attr | |-- index.txt.old | |-- newcerts | | -- B4CD0A125B005B2B.pem | |-- private | |-- cakey.pem | |-- serial | -- serial.old-- meineadresse.de |-- newcert.pem |-- newreq.pem |-- webserver.key `-- webserver.nopass.key

Anpassen der Apache-Configs

Als letztes wird der Apache-Server für verschlüsselte Verbindungen konfiguriert. Dazu wird zunächst in der Datei /etc/apache2/httpd.conf die Datei httpd-ssl.conf inkludiert in der dann die restlichen Einträge vorgenommen werden. Die passende Zeile ist bereits vorhanden3 und muss nur auskommentiert4 werden.

Das Ergebnis sollte so aussehen:

Secure (SSL/TLS) connections

Include /private/etc/apache2/extra/httpd-ssl.conf

In der Datei /etc/apache2/extra/httpd-ssl.conf müssen nun die folgenden Variablen auf die vorhin erstellten Dateien inklusive dem vollen Pfad zeigen:

SSLCertificateFile "/Users/dennis/Documents/certs/meineadresse.de/newcert.pem" SSLCertificateKeyFile "/Users/dennis/Documents/certs/meineadresse.de/meineadresse.de.nopass.key" SSLCACertificateFile "/Users/dennis/Documents/certs/demoCA/cacert.pem" SSLCARevocationPath "/Users/dennis/Documents/certs/demoCA/crl"

Man kann hier auch das DocumentRoot auf einen anderen Pfad als die nicht verschlüsselten Inhalte setzen wenn man das möchte. Das kann dann z.B. so ausschauen:

DocumentRoot "/Users/dennis/Sites/SSL"

Jetzt kann man den Apache mit sudo apachectl graceful neu starten und sollte dann unter https://localhost5 eine verschlüsselte HTTP-Verbindung herstellen können.

Usernamen und Passwörter die oben noch im Klartext zu lesen waren sehen für potentielle Mitlauscher nun nur noch so aus:

wireshark_roundcube_ssl

Und das ist eine gute Sache.

Wenn man ein solches System produktiv einsetzen möchte, sollte man zu allermindestens die CA auf einen anderen Computer auslagern. Noch besser6 wäre es, sich sein Zertifikat von einer richtigen CA unterschreiben zu lassen. Dann müsste man auch nicht mehr mit der unvermeidlichen Fehlermeldung leben, dass das Zertifikat von einer unbekannten CA ausgestellt wurde…

ssl-cert-error

Natürlich kann man für seinen Browser eine passende Ausnahme konfigurieren, für einen Produktivserver ist so etwas aber nicht hinnehmbar.

(via: Apple & macosxhints.com)

  1. Und nein, mein Passwort ist üblicherweise nicht “test123″ []
  2. gültig für 10 Jahre []
  3. in meiner Installation war es die Zeile 473 []
  4. Also die Raute “#” vor der Zeile löschen []
  5. bzw. der jeweiligen Adresse []
  6. aber auch mit Kosten verbunden []
  • A.U.

    Vielen Dank für die ausführliche Anleitung. Das war bislang die verständlichste für mich. Habe ich mir sofort gebookmarkt! Ein echtes Must-Have.

    Gruß

  • http://instant-thinking.de der Dennis

    Schön dass dir der Post weitergeholfen hat, vielen Dank für dein Feedback!

  • Manuel

    Hi Dennis

    Was meinst Du genau mit “…nicht so richtig geeignet für ein echtes Produktivsystem”? Ich habe für unser Büro einen 10.6 Server aufgesetzt und kann über einen DynDNS von aussen auch auf verschiedene Dienste wie Kalender und so zugreifen. DynDNS bietet auch SSL Zertifikate an.

    Ich frage mich, ob ich meine Installation nun mit SSL abrunden soll. Deine Anleitung käme da sehr gelegen. Aber wie Du sicher erkennst, setzen wir den Kram zu 100% produktiv ein, nicht nur wegen lustig.

    Wo genau sind deine Vorbehalte?

    Gruss, Manuel

  • http://instant-thinking.de der Dennis

    @Manuel:

    Ich meinte damit, dass es keine gute Idee ist ein selbst signiertes Zertifikat zu verwenden, wenn eine große Zahl von unbekannten Usern den SSL-gesicherten Service nutzen will.

    Diese würden dann nämlich immer die Meldung über ein ungültiges (weil nicht von einer “richtigen” CA unterschriebenes) Zertifikat erhalten und das macht sich einfach nicht gut.

    Wenn du für dein Büro einen klar umrissenen Anwenderkreis hast dem du sagen kannst, dass diese Meldung ok ist, oder noch besser, deren Browser du passend für deine CA konfigurieren kannst klappt das super mit einem selbst unterschriebenen Zertifikat.

    Das Problem ist halt nicht die Güte der Verschlüsselung (die ist bei selbst unterschriebenen Zertifikaten genau so toll wie bei offiziellen), sondern die Identifikation des Servers und dessen Betreiber und das darauf beruhende Vertrauen.

    DynDNS schreiben ausserdem zu ihren Zertifikaten:

    “Third-party SSL certificates cannot be used with our free Dynamic DNS hosts, including the certificates we offer. You may use self-signed certificates for Dynamic DNS hosts. If you need the security of our certificates for business transactions or corporate use, you may wish to create your own domain registration and DNS service and purchase SSL certificates for your new domain.”

    Mit den kostenlosen Standard-DynDNS Domains klappt das also, ich vermute wegen den dynamischen IPs, eh nicht.

    Ich hoffe das bringt dich nach vorn…

  • Manuel

    Hi Dennis

    Danke für die Antwort. Ja, ich denke ich wage mal den Sprung und erwerbe ein Zertifikat bei DynDNS. Werde mich aber sicher noch etwas in die Materie einlesen müssen, vor allem wenn ich auf dem OS X Server beginne, irgendwelche Verzeichnisse per Terminal umzubiegen. Werd wohl erst das ganze System spiegeln und dann mit den Arbeiten loslegen.

    Gruss, Manuel

  • http://instant-thinking.de der Dennis

    @Manuel:

    Wie gesagt, ich befürchte du wirst mit einer dynamischen IP keinen Erfolg haben und eine richtige Domain nebst IP brauchen.

    Dennoch würde ich gerne von deinen Erfahrungen hören. Das System vor deinen Tests zu spiegeln ist eine gute Idee. Gerade wenn der Server produktiv ist…

  • Manuel

    OK, dachte erst ich hätte das falsch interpretiert in deiner ersten Antwort auf meinen Kommentar. Ich denke es sollte mit dynamischer IP und dem DynDNS funzen. Aus irgendeinem Grund bieten die Jungs ja den Service von Zertifikaten an: http://www.dyndns.com/services/sslcert/ssltypes.html

    Ich weiss, das klingt etwas stur von meiner Seite. Aber ich habe den Ehrgeiz, so viel wie möglich über DynDNS abzuwickeln. Die Swisscom hier in der Schweiz verlangt immer noch ein Schweinegeld für eine statische IP. Und dagegen führe ich meinen ganz eigenen kleinen Krieg auf meine Weise. ;-)

    Ich werde gerne berichten, ob’s dann tatsächlich tut was es soll.

  • Stefan

    Hi Dennis,

    wirklich die beste Beschreibung zu diesem Thema die ich bisher gefunde habe! Zur einfachen Zertifikatsverwaltung habe ich das Tool http://xca.sourceforge.net/ gefunden und damit ein selbstsigniertes root CA und ein Server CA erstellt. Nach Import des selbsterstellten Zertifikats in die keycain wird jedoch in /etc/certificates das file .key nicht erstellt und damit das Zertifikat nicht anerkannt. Beim Import eines gekauften wird die .key aber erstellt. Woran kann das liegen?

  • http://instant-thinking.de der Dennis

    Stefan: Danke für das Lob. Warum die Geschichte mit xca nicht so funktioniert wie erwartet kann ich dir leider nicht treffend beantworten.

    Vielleicht liegt es an einem der zahlreichen unterstützten Ausgabeformate? Vielleicht solltest du da als erstes Nachforschungen anstellen und das Format des gekauften Zertifikats mit deinem xca-Export vergleichen…

    Ich wünsche dir viel Erfolg!