Sie sind hier: Zentrale | Server-Einrichtung | SSL-Integration
Unterthemen:
 Harry Boeck - Heimserver

SSL-Integration

Hier meine Erlebnisse / Erfahrungen mit der SSL-Integration in Apache 2.x unter Windows 98...

Ursprünglich war ich gerade dabei, eine eigentlich triviale Aufgabe aus dem SGD-Lehrgang "Datenbankentwickler" zu Ende zu bringen. Es ging um Zugangsbeschränkung auf dem Server und die dazu notwendige Authentifizierung.
Nun hat sowas ja aber keinen Zweck, wenn die Zugangsdaten und nach der Anmeldung die eventuellen Sitzungsdaten über einen offenen Kanal übers Internet übertragen werden. Sie stellen dann nichts weiter dar als eine Verschleierung gegenüber zufällig in dieselbe Richtung schauenden Augen, haben aber keinerlei Schutzfunktion. Eben diese Schutzfunktion sollte ja aber nun realisiert werden. Einfach nur eine Zugriffs-Datei zu definieren, fand ich hier ein bisschen zu leicht als Aufgabenstellung. Für angemessen würde ich halten: "Richten Sie einen SSL-Bereich auf Ihrem Server ein und beschränken Sie den Zugriff auf Nutzer mit Hilfe einer htaccess-Datei" - verbunden natürlich damit, dass in das Ausbildungsmaterial ein entsprechender Abschnitt aufzunehmen wäre.
Außerdem: Da habe ich seit etwa 2000 laufend gemeckert, wen ich auf Websites gestoßen bin, die noch kein SSL für ihre oder meine vertraulichen Daten eingerichtet hatten, und dann soll ich so eine minderwertige Lösung abliefern? Nicht mit mir! Kommt gar nicht in Frage!
Jedenfalls habe ich das jetzt abgehandelt...

2006-04-02 Vorbereitung

Ich setze hier einfach mal einen Auszug aus dem Protokoll rein, das ich während der Suche nach der SSL-Lösung geführt habe...

- Wir wird effektiv der Zugriffsbereich für das Ziel auf dem Server in Abhängigkeit vom Benutzer beschränkt? -> Wir benötigen Verzeichnisverwaltung von Apache in Verbindung mit SSL! - Irgendwas Besonderes an SSL zu beachten? -> Nein (ganz normale PGP-artige Anwendung). - Allerdings habe ich noch nie die laut Dokumentation mögliche Authentifizierung mittels vorgefertigter persönlicher Certifikate im Internet gesehen. Wird mal auszubrobieren sein... -> SSL ist in der aktuellen Binär-Distribution von Apache für Windows nicht enthalten. Die aktuell verwendete Apache-Version ist: 2.0.55, binär für Win32 Die aktuell höchste Apache-Version mit SSL ist: 2.2.0, source only - Ein alternatives SSL-Paket für Apache ist "Apache-SSL" (der Ursprung des integrierten SSL-Pakets und parallel weiterentwickelt). DAS wird ebenfalls nur als Source vertrieben. -> Ob ich nun das eine oder das andere will, ich MUß zwingend GCC wieder zum Laufen bringen! -> GCC-Installation: -> GCC wird nur als Source vertrieben. Seine Compilation setzt zwingend ein bereits existierendes GCC voraus! -> CygWin wird auf der Homepage von GCC als hinreichende Voraussetzung angegeben. -> CygWin erneut installiert (ich hatte noch ein altes rumzuliegen, was aber schon wieder mächtig veraltet war...) Problem: Das CygWin ist ja ein ziemlich umfangreiches Paket, was offenbar auch jede Menge GUI-Module und massenhaft Programme hat, die ich allesamt unter Windows nicht benötige, weil ich deren Äquivalente oder besseres bereits zu laufen habe. Es ist ja praktisch ein vollständiges Linux-System einschließlich solcher Scherze wie graphisches GUI, Apache-Server usw. ICH will doch nur ein minimales GCC-Environment, um für meinen Windows-Apache ein Modul oder halt den kompletten Windows-Apache in einer höheren Version kompilieren zu können! Außerdem bin ich an einer Neucompilation von GCC überhaupt nicht interessiert! -> CygWin minimal mit GCC-Komponenten installiert. Eventuell müssen wir später nochmal ein paar Module nachladen... -> Rückzug zur Apache-Compilation... - Apache-Installation - Quellen geholt: Apache-2-2-0-win32-src-rev2.zip - entpackt in ein Projektverzeichnis - irgendwelche Anleitungen zur Installation? Ja: In der Dokumentation vom Apache 2.0 bereits enthalten... - "Compiling Apache for MS Windows": "MSVC 5 required" Soll das 'n Witz sein?! EBEN war doch bitteschön noch von GCC die Rede, oder?! ...Ähhhm, nein: Bei Apache war nur von Compilierung die Rede. Der GCC war meine Idee... -> Fallback zur allgemeinen Unix-Installation (wir haben ja cygwin)... Requires nur noch Disk Space und GCC 2.7.2! Prima. Haben wir! - Extracted haben wir mit WinRar, Thanks! - Configuren versuchen wir mal auf der cygwin-Kommandozeile... -> Ah, ja: Die Shell ist ähnlich zu benutzen wie 4dos. Gut. Hmmm, unterstützt aber kein Copy & Paste... - Dokumentation zu Configure: - nur Erwähnung der Optionen, KEINE Beschreibung der Möglichkeiten oder Notwendigkeiten -> WAHRSCHEINLICH benötige ich --build=BUILD (undokumentiert) --host=HOST (undokumentiert) --target=TARGET (undokumentiert) - WAHRSCHEINLICH WILL ich --prefix=\server\apache --enable-so --enable-mods-shared=most --disable-actions --disable-asis --disable-cgi --disable-cgid --enable-ssl - Versuch der Ermittlung der unterstützten Optionen für die Parameter build...target: - Volltextsuche in der Dokumentation von Apache 2.0: Kein verwertbarer Treffer - Volltextsuche mit Google: keine sinnvollen Treffer, weil "--" und "=" grundsätzlich unterdrückt werden. Was dann rauskommt, hat mit der Anfrage absolut nichts mehr zu tun... -> Fallback zur Ermittlung der möglichen Optionen über config.guess: -> Ein Script dieses Namens existiert nicht. Na toll! Es existiert aber im build-Verzeichnis... Und wenn man reinguckt sieht man sogar die möglichen Optionen... ...Nur ist da nichts für sowas wie "native Windows" oder wenigstens MSVClibs oder so... -> --build=i686-pc-cygwin --host= i686-pc-??? ?? --target= i686-pc-??? ?? - Der "alte" Apache ist gegen die Win32-DLLs und gegen MSVCRT gelinkt. Sowas sollte doch eigentlich auch mit irgendwelchen anderen Targets möglich sein, oder? -> Weiter suchen im Internet nach irgendwelchen Strohhalmen... -> Alle Versprechen, die Compilation - oder manchmal eben auch "Installation" genannt - des Apache 2.x mit SSL zu covern, sind leere solche... Es läuft IMMER darauf hinaus, dass es NUR bis Apache 1.3.4 SSL-Unterstützung gab, nie ohne den Hinweis, dass eben jene Apaches vor 2.x unter Windows unstabil wären. Na toll! Nicht eine einzige Hilfe zur Compilation FÜR native Win32... -> Versuch, eine Anfrage in ein Support- oder User-Forum für Apache (2.x) zu stellen... - http://httpd.apache.org/dev/ hat ganz hinten unten einen Link auf einen Support Webring... -> http://p.webring.com/hub?ring=apachesupport -> http://www.apachelounge.com/ -> http://www.apachelounge.com/article.php?sid=18 -> http://tud.at/programm/apache-ssl-win32-howto.php3 -> http://raibledesigns.com/wiki/Wiki.jsp?page=ApacheSSL mit der Suggestion, dass dort eine Anleitung sei, die Apache 2.x-Versionen mit SSL abdeckt... -> 2.o.x-BINARIES MIT SSL (!) bei http://hunter.campbus.com/ -> JA, die sind da! (Zumindest der Bezeichnung nach...) Und zwar eine Version 2.0.55 (also meine installierte)! -> Download! -> Anschauen der Distribution (ich brauche ja nur das mod_ssl.so)... - neu hinzugekommen -> kopiert - bin\libeay32.dll - bin\ssleay32.dll - bin\openssl.exe - bin\iconv\*.so (eine ganze Menge Dateien, offenbar sowas wie zeichen-fonts, 5 Dateien aus bin\ enthalten den String "iconv", übrigens schon in der "alten" Apache-Installation!) - mehrere DLLs in bin\ mit anderem Datum/Dateigröße, aber ohne Versionsänderung -> übergangen - ergänzte Text-Dateien mit Lizenzen usw. sowie neue Textdateien zu SSL -> kopiert nach doc\. - Alle Module in modules\ neu compiliert und dabei geändert: Alle haben 4 Bytes weniger (gesamt 192 Bytes Änderung - stimmt). Allerdings keine einzige Versionsänderung. -> übergangen - Modules\mod_ssl.so neu -> kopiert - Lesen der Readmes: - OPENSSL-README.txt: geringe Einschränkungen hinsichtlich patentierter Ciphers (das ist OK und verschmerzbar, ich selbst bevorzuge eh Blowfish) - OPENSSL-NEWS.txt: History, momentan noch nicht weiter interessant, für Fehlerfälle... - To do: Konfiguration des SSL-Betriebes und Test: - !!To do: Prüfen der Integrität der Distribution

2006-04-02 ff. Zertifikatseinrichtung

So, nun hapert es noch an den Zertifikaten... Sobald ich die SSLEngine einschalte, meldet der Server einen Fehler beim Start (und startet natürlich nicht). Und zwar von wegen:

"Server should be SSL-aware but has no certificate configured [Hint: SSLCertificateFile]"

Immerhin steht da ja schon ein sinnvoller Hinweis zur Behebung. Ich hatte bisher alle Konfiguraions-Direktiven weggelassen, von denen ich noch nicht eindeutig wusste, was sie bedeuten sollen.

Eigentlich sollte das doch ganz trivial sein, solange man keine hochorganisierte Ausweis-Kontrolle einrichten möchte, sondern einfach nur eine verschlüsselte Datenübertragung, bei der eine Anfälligkeit für Man-in-the-Middle normal ist und hingenommen wird: Der Server sollte ein temporäres Schlüsselpaar generieren können, genauso wie der Client, davon sollten die öffentlichen Schlüssel ausgetauscht werden können und dann sollte alles schon in Butter sein, oder?

Eine SSL-Verbindung, bei der tatsächlich eine Man-in-the-Middle-Attacke verhindert werden kann, indem nämlich sowohl Server als auch Client mit über andere Wege vermittelten richtigen "Ausweisen", also Schlüsseln, die von rechtlich zur Verantwortung ziehbaren Personen, die der jeweiligen Kommunikationspartei als vertrauenswürdig eingestuft wurden, mit deren Schlüsseln gegengezeichnet wurden (wobei deren öffentliche Schlüssel auch wieder über nochmal unabhängige dritte Wege zu verteilten und sorgfältig zu prüfen wären) gegenseitig ihre Authentizität prüfen, ist mir nämlich im öffentlichen WWW noch nie begegnet.

Sowas dürfte im Normalfall nämlich absoluter Overkill sein und vollkommen unzumutbar für Otto Normalverbraucher. Gerade eben wurde ich beim Schreiben unterbrochen, um einem Otto-Normalverbraucher zu zeigen, wie er ein Bild einscannen und per Email verschicken kann. Glauben Sie mir, ich WEIß wovon ich rede!

Außerdem dürfte das oben genannte den staatlichen Gewalt-Institutionen wie Polizei und Geheimdiensten ein Dorn im Auge sein. Ich gehe also mal davon aus, dass eine Schlüssel-Infrastruktur, die tatsächlich im mathematischen Sinne KORREKT funktioniert, weder vom Staat noch von öffentlichen Anbietern noch von Otto Normalverbraucher überhaupt gewollt wird.

Dann bleiben wir also dabei hängen, dass für eine 0815-Datenübertragung sowohl Server als auch Client sich temporär ein Schlüsselpaar auswürfeln sollen, dann die öffentlichen Teile austauschen und dann mit der Übertragung von Daten (zur Vorbereitung der symmetrischen Verschlüsselung) beginnen sollen. Das hat ja nun mit Zertifikaten herzlich wenig zu tun, oder?

Suche nach Anleitungen

OK, gehen wir mal die Dokumentation systematisch durch...

Erster Anlaufpunkt: Die englische Originaldokumentation zum Apache ("SSL/TLS Strong Encryption: An Introduction")...
Ganz zu Anfang ist ein Verweis auf den originalen Artikel von Frederick J. Hirsch. Ich gehe zunächst davon aus, dass der nicht totale Selbstbefriedigung sein soll und eine signifikante Bedeutung in der hier liegenden Dokumentation hat...
Der Link zum in der Dokumentation zur Apache-Version 2.0.55 ist veraltet. Funktionieren tut der in der Dokumentation zum aktuellen Apache 2.2.0: http://httpd.apache.org/docs/2.2/ssl/

Das dahinterliegende Dokument http://home.comcast.net/~fjhirsch/Papers/wwwj/article.html ist die Vorlage für die Apache-Dokumentation gewesen und offenbar umfangreicher. Es enthält wie die Apache-Dokumentation einen allgemeinen Teil zu Funktionsprinzipien von Public-Key-Verfahren (den wir uns schenken können, weil nichts neues drin steht) und Beispiele zur Einrichtung eines SSL-Systems mit Apache, allerdings unter Verwendung von einem ausführbaren Programm namens "ssleay(.exe ?)". Ich habe bei meiner SSL-Bibliothek sowas nicht gesehen. Stattdessen liegt bei mir ja etwas namens "openssl.exe". Sollten die beiden äquivalent sein?

Ahhhh, ja: Das ist ja ein Kommandointerpreter wie eine 4dos- oder MySQL-Konsole. Na mal sehn...
Ja! Es ist das Äquivalent.

Jetzt schaue ich doch nochmal rüber in die Apache-Dokumentation, ob da in einem Unterbereich zum SSL nicht doch auch die Beispiele zur Einrichtung enthalten sind...

Nein, dort wird ausschließlich die Konfiguration des Adapters "mod_ssl.so", der eben die Adaption des Apache an das Modul OpenSSL erledigt, diskutiert (also wie beispielsweise dem Adapter mitzuteilen ist, DASS irgendwo ein Zertifikat rumliegen würde), aber nirgendwo z.B. die Einrichtung der eventuell notwendigen Zertifikate (obwohl ich die immer noch für Schnulli halte - siehe oben...).
(Es gibt genau die Bereiche "Apache SSL/TLS Encryption" mit den Unterthemen "Introduction", "Compatibility", "How-To", "FAQ" und "Glossary" sowie das "Apache Module mod_ssl". Keine dieser Dokumentationen enthält tatsächlich ausreichende Erklärungen oder Beispiele zur Einrichtung des SSL-Betriebes. Nur Falldiskussionen zur Modifikation des Verhaltens eines bereits erfolgreich laufenden Systems.
P.S.: Da hatte ich nicht richtig hingeschaut. Im hinteren Bereich der FAQs kommen jene Beispiele, die im Original-Artikel meiner Meinung nach systematischer adressiert und auffindbar sind...

Zurück zur Dokumentation der Bibliothek "SSLeay"...
Relevant für die Einrichtung eines Systems scheint der Bereich ab "6. SSLeay Examples" bis Anhang zu sein...
Da im betreffenden Dokument keine Anchors vorbereitet sind, werde ich mir das Ding wohl ein wenig modifizieren müssen... -> Download und Ablage unter "ssleay" im Apache-doc-Verzeichnis...
Beim Anlegen der Links in das SSLeay-Dokument hinein sehe ich doch, dass in den FAQs vom Apache ganz unten eben doch die Beispiele aus der Original-Dokumentation aufgearbeitet sind...
-> Hinweise eingebaut, Querverweise angelegt, alles in Butter...

Nebenbei noch die Projekt- und Dokumentationskette mal vollständig in die Bookmarks und hier angelegt:

Was wir brauchen, um die Zertifikate einzurichten, ist also offenbar die OpenSSL - Dokumentation (da ich gern wissen will, was die Vorschläge in den Beispielen von mod_ssl und Apache zu bedeuten haben...)

Einrichtung des Servers

Also: Den Server hatten wir ja schon soweit vorbereitet, dass er am Port 443 lauscht und für dort angenommene Verbindungen das Verzeichnis "/private" serviert. Was jetzt noch fehlt, ist offenbar ein Zertifikat für den Server, weil das SSL-Protokoll offenbar doch nicht ein Modell ganz ohne Authentifizierung, also mit komplett temporär generierten Schlüsseln, unterstützt. Arbeitshypothese abgelehnt. Na ja.

Die Beispiele in Apache-Dokumentation/SSL/FAQ könnten wir ja einfach mal nachvollziehen...

Schlüssel- und Zertifikatsgenerierung für Funktionstests:
$ openssl req -new -x509 -nodes -out server.crt -keyout server.key
new: Erzeugung einer "Zertifikatsanfrage"?? Also: BEI MIR wurde ein Zertifikat (ohne Anfrage) erzeugt... x509: Ahhh ja: Deshalb! Erzeugung eines Zertifikats statt einer Anfrage eines solchen. nodes: No DES (No Data Encryption S? - keine Verschlüsselung des generierten Schlüssels)
Unable to load config info from /usr/local/ssl/openssl.cnf error in req

Ähmmm, ja: ???
Volltextsuche nach "config info" (irgendwo glaube hatte ich doch mal etwas vonwegen configfile oder so überflogen?...):
$ openssl req -config "<Pfad zur Schlüsselablage>\ssl.cfg" -new -x509 -nodes -out server.crt -keyout server.key (mit ssl.cfg zunächst noch leer) Loading 'screen' into random state - done Generating a 512 bit RSA private key ..............++++++++++++ ...............++++++++++++ writing new private key to 'server.key' ----- unable to find 'distinguished_name' in config problems making Certificate Request 4294379319:error:0E06D06C:configuration file routines:NCONF_get_string:no value: .\crypto\conf\conf_lib.c:329:group=req name=distinguished_name error in req

Aha, da soll also sowas wie ein schöngeistiger Bezeichner fest im Konfigurationsfile eingetragen werden, ja? Warum auch immer...
Also, ich entere mal: name="Testname" in die "ssl.cfg"...

$ openssl req -config "<Pfad zur Schlüsselablage>\ssl.cfg" -new -x509 -nodes -out server.crt -keyout server.key Loading 'screen' into random state - done Generating a 512 bit RSA private key ...........++++++++++++ .++++++++++++ writing new private key to 'server.key' ----- unable to find 'distinguished_name' in config problems making Certificate Request 4294379319:error:0E06D06C:configuration file routines:NCONF_get_string:no value: .\crypto\conf\conf_lib.c:329:group=req name=distinguished_name error in req

Aha, "name=" war's also nicht. Na ja...
Volltextsuche nach "distinguished_name" in der Dokumentation von OpenSSL:
Ahhhh, da gibt es ja eine extra Sektion zum Inhalt eines Configfiles nur für das Kommando "req". Ist ja interessant... Da gibt's auch jede Menge Hinweise auf den "distinguished_name"...
Ach ja: Da soll's also eine "Sektion" "req" innerhalb des allgemeinen Configfiles geben. Ich nehme mal an, die soll "[req]" gekennzeichnet werden, so wie wir's von ini-Files gewöhnt sind?
Ja: http://www.openssl.org/docs/apps/req.html#EXAMPLES

Also, folgendes entere ich mal in das Configfile...
[ req ] default_bits = 1024 distinguished_name = Server-Testname default_keyfile = "<Pfad zur Schlüsselablage>/privkey.pem" attributes = req_attributes x509_extensions = v3_ca [ Server-Testname ] countryName = Landeskennung (2 Zeichen - Kode) countryName_default = GE countryName_min = 2 countryName_max = 2 localityName = Ort organizationalUnitName = Organisation commonName = Eigenname commonName_max = 64 emailAddress = Email Adresse emailAddress_max = 40 [ req_attributes ] challengePassword = Kennwort challengePassword_min = 10 challengePassword_max = 40 [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:true

Damit erhalte ich...
$ openssl req -config "<Pfad zur Schlüsselablage>\ssl.cfg" -new -x509 -nodes -out server.crt -keyout server.key Loading 'screen' into random state - done Generating a 1024 bit RSA private key .......++++++ ............................................++++++ writing new private key to 'server.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. ----- Landeskennung (2 Zeichen - Kode) [GE]: Ort []:Neustrelitz Organisation []:private Eigenname []:Harry Boeck Email Adresse []:Harry.Boeck@t-online.de

DAS sieht doch schon mal wesentlich besser aus.
Allerdings kommt mir das alles vollkommen identisch zu dem vor, was ich von der PGP-Schlüsselverwaltung kenne. Warum kann ich nicht einfach einen Schlüssel von dort nehmen?! Muß dazu wohl noch die ganze Dokumentation durchsuchen...
Aber erst mal will ich ja "nur" einen funktionsfähigen Server haben. Also: Verzeicht auf Komfort und Systematik und Augen-zu-und-durch...

So, nun ist dieser dämliche Key natürlich erst mal im Current Directory der Konsole gelandet. Na ja. Rübergeschoben.

Wenn ich da reingucke, sehen die Dinger exakt wie meine PGP-Schlüssel bzw. Zertifikate aus. Schauen wir doch mal, was PGP dazu sagt...
Aha, sehe jetzt erst mal einen Sinn in den ganzen Dateiformaten, die da von PGP immer angeboten wurden: Der kann ja all die Formate, die mir hier in den Apache/OpenSSL-Dokumentationen schon in den Weg gekommen sind, namentlich PEM, PKCS-12 und natürlich seine eigenen Formate (die ich bisher immer benutzte)...
Allerdings ist das, was hier generiert wurde, nach PGP-Auskunft was anderes... Na mal seh'n... Ahhh, ja:
X.509 certificates are not supported in PGP Freeware
Man kann sie höchstens von einem CA-Server anfordern. (Ich nehme mal an, nach irgendeinem Klartext-Server-Protokoll? Dessen Ermittlung/Studium bis zur Anwendungsreife aber mit Sicherheit mindestens einen extra Tag dauert? Alldieweil der Import als Datei ja offensichtlich unmöglich ist?)
Dann, denke ich, ist das Kommandozeilentool OpenSSL doch ganz sinnvoll...

So, wie weiter?
Jetzt soll ich laut Apache-FAQs in der Lage sein, die Direktiven "SSLCertificate" und "SSLCertificateKeyFile" in meine "Apache.cfg" einzusetzen...

Ich entere also...
<VirtualHost 192.168.1.1:443> ... SSLCertificateFile "<Pfad zur Schlüsselablage>/server.crt" SSLCertificateKeyFile "<Pfad zur Schlüsselablage>/server.key" SSLCertificateChainFile "<Pfad zur Schlüsselablage>/server.crt" ...

...und schmeiße mal den Apache neu an...
OK. startet.

Blick ins Apache-"error.log":
Keine irgendwie geänderten Verhaltensweisen. Dort steht immer noch was vonwegen "Generating temporary RSA private keys" und "Generating temporary DH parameters", wobei ich mir nicht zusammenreimen kann, was das zu bedeuten haben soll angesichts dessen, dass ich ja doch die Keys und Zertifikate explizit vorgeben muss. Aber kommt Zeit, kommt Erleuchtung...

Ich nehme mal zusätzlich auf...
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLVerifyDepth 1 <Location /> SSLRequire %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \ and %{REMOTE_ADDR} =~ m/^192\.168\.1\.1$/ </Location>

-> Startet immer noch. Identisch.

Na gut, dann schließlich...
SSLEngine on

Hmmm, startet. Und erst jetzt kommen Meldungen bezüglich Schlüssel/Zertifikat hinzu:
... [info] Loading certificate & private key of SSL-aware server ... [info] Configuring server for SSL protocol [warn] RSA server certificate CommonName (CN) `Harry Boeck' does NOT match server name!? ...

Und das ganze kommt wie üblich 4 mal hintereinander...

Was sagt Google zu "RSA server certificate CommonName (CN)" und "does NOT match server name!?"?
Allen möglichen Schwachsinn von wegen vollkommenkonkreter Problemfälle auf ausschließlich Unix-Rechnern.
Aber nein: http://www.rootforum.de/forum/viewtopic.php?p=230564 enthält einen vernünftig klingenden Hinweis:
"Der ServerName im VirtualHost muss gleich dem CommonName des SSL Zertifikates sein."
Das klingt insofern logisch, dass je das Zertifikat eben ein solches ist und dementsprechend der "CommonName" also im Falle eines Zertifikats für einen Rechner (oder Internet-Knotens) dem Namen des Rechners (oder Internet-Knotens) entsprechen muß.

Warum taucht DAS nicht in den Erklärungen zur Bedeutung des "CommonName" in http://www.openssl.org/docs/apps/req.html#EXAMPLES oder sonstwo in http://www.openssl.org/docs/ auf?

Na, geschenkt!

Test mit https://192.168.1.1:443/index.html: OK
Test mit https://192.168.1.1/index.html: OK

OK, erste Hürde genommen.

Jetzt zur Korrektur des Zertifikats:

Korrekte Einrichtung des Server-Zertifikats

Ich möchte ja nun nicht jeden Tag ein neues Zertifikat einrichten, sondern eben zum Zwecke der sinnvollen Prüfbarkeit und Verteilbarkeit dieses nur dann tun, wenn eine Kompromittierung meiner Daten (entweder des Zertifikats oder des geheimen Schlüssels) aufgetreten sein könnte oder etwas an der Serverkonfiguration geändert wird, so dass zum Beispiel der Servername geändert wird, oder auch wenn ein verwendetes Chiffrierverfahren unsicher wird.

Damit ich nicht jedes mal, wenn sowas seltenes auftritt, wieder die Dokumentation durchwühlen muß, sorge ich mal dafür, dass sämtliche Angaben in der zugehörigen Konfigurationsdatei stehen und der Start des OpenSLL-Programms über eine Batchdatei erfolgt...

Überlegungen zur Schlüsselgenerierung

Schlüsselart
Erstmal habe ich mich in der Dokumentation des OpenSSL ein wenig umgesehen, was denn an Schlüsselarten alles zur Verfügung steht. Und das ist ja offenbar gar nicht so viel. Es gibt exakt 3 asymmetrische Schlüsselarten:
  • DSA
  • DH
  • RSA
wobei DSA (Digital Signature Algorithm) von seinem Verwendungszweck her für die Verschlüsselung der SSL-Verbindungen wegfällt.
Aus der Dokumentation des Kommandozeilentools OpenSSL geht weiterhin hervor, dass eine DH-Schlüsselgenerierung gar nicht implementiert ist, sondern nur die Erzeugung von Parameterdateien. Na toll!
Damit bleibt zwingend RSA zur Verschlüsselung übrig.

Ich brauche also einen RSA-Schlüssel.

Schlüssellänge
Eine Stichprobe im Internet (Raven-Homepage) ergibt halbwegs aktuelle pauschale Anforderung an einen RSA-Schlüssel in Abhängigkeit von dem Aufwand, den Angreifer investieren würden (weil entsprechend teure Rechentechnik notwendig ist):
  • Die effektive Länge eines RSA-Schlüssels von 2048 bit Länge beträgt etwa 112 bit. Damit entspricht die effektive Länge etwa einem Zwanzigstel der tatsächlichen Länge.
  • In den finanziellen Aufwand für das Brechen eines Schlüssels fließen unter Umständen die Anschaffungskosten für Hardware und die Zeit für den Betrieb dieser Hardware und deren Energiehunger ein. Das ganze relativiert sich etwas für die Besitzer von Netzwerken gekaperter Rechner, aber auch da muß sich eine Verwendung der Rechner immer an der einträglichsten Verwendung messen (was, soweit ich informiert bin, Spam ist). Letztlich gibt es da laut Raven Homepage die Einschätzung des "Europäisches Kompetenznetzwerk für Kryptografie", dass das Brechen eines 64 bit-Schlüssels um 2004 herum so etwa 50'000 bis 100'000 Euro kosten sollte.
  • Gehen wir mal größenordnungsmäßig davon aus, dass ein Spam-Bot-Netz für den Betreiber sehr viel billiger rechnet, sagen wir mal so um den Faktor 10:N, wobei N die Menge der insgesamt im Bot-Netz vorhandenen Rechner ist (von denen immer nur ein geringer Teil verfügbar ist, weil die Besitzer ihre Rechner sicherlich auch irgendwann abschalten); das macht in der Praxis bei üblichen Bot-Netzen in der Größenordnung von 10'000 Rechnern etwa 1000 Rechner, die mit üblicherweise fast 100% ihrer Rechenleistung dem Steuernden zur Verfügung stehen und von dieser einen Person mit einem PC eingesetzt werden können. Das bedeutet also, dass ein Spam-Bot-Netzwerk-Betreiber einen 64 bit-Schlüssel im Jahre 2004 schon für höchstens 100 Euro knacken konnte. Angesichts solcher Verhältnisse vermute ich mal, dass solche Gauner eine doch viel größere Gefahr als irgendwelche Geheimdienste darstellen dürften (so habe ich das bisher noch gar nicht gesehen...)!
  • Jetzt muß man hier wohl ein wenig überlegen, wie die persönliche Interessenlage im Gegensatz zu jenen Personen oder Institutionen ist, die ein Interesse an schädigenden Manipulationen oder Offenlegung der mit dem Server per SSL auszutauschenden Daten besitzen könnten und wieviel Investition man gegebenenfalls von jenen erwartet.
    Und an dieser Stelle muß ich deutlich feststellen, dass mir Spam-Bot-Netz-Betreiber sehr viel gefährlicher vorkommen als irgendwelche neugierigen Regierungsstellen oder Geheimdienste...
    Hmmm, also: Ich gehe mal davon aus, dass ich über meinen Server keine finanziell relevanten Transaktionen ausführen werde, wohl aber Meinungsaustausch und dabei durchaus sowohl Regierungen und Geheimdiensten als auch Spammern ordentlich auf die Füße treten könnte. Erstere haben allerdings keinen unmittelbaren finanziellen Vorteil aus der Unterdrückung eines solchen Meinungsaustausches, während das für letztere durchaus zutreffen kann.
  • Weiterhin: In aller Regel sind die Verschlüsselungen von ihrem mathematischen Potential sehr viel stärker als die sie benutzenden Menschen in ihrer Disziplin bei deren Anwendung.
  • Schlußbetrachtung für jetzt: Ein Spam-Bot-Betreiber dürfte zum Knacken eines 2048 bit-RSA-Schlüssels im Jahre 2004 etwa 100 Euro * 2^(112-64) zu investieren haben, also etwa 10^16 Euro. Das ist doch noch so etwa um den Faktor 10^10 außerhalb jeden Sinns. Auch wenn wir jetzt (2006) um 1:4 billiger geworden sein sollten, sind die 2048 bit nach meinem Geschmack ausreichend sicher. Und dass ein Geheimdienst milliarden Euro und mehr in mich oder die Meinung eines Besuchers meines Servers investieren sollte, halte ich für absolut schwachsinnig.
Damit lege ich 2048 als Größe für den zu generierenden RSA-Schlüssel fest.

Zum Schluß gibt's aber nochmal einen Dämpfer: Diese Schlüssellänge wird nur von neueren Browsern akzeptiert (http://httpd.apache.org/docs/2.2/ssl/ssl_faq.html#keysize), namentlich der Netscape Navigator 3.x und ebenso alte Internet Explorer sollen Probleme (gehabt haben). Allerdings: Wer heutzutage mit einem veralteten Browser surft, dürfte auf sowas wie Sicherheit seiner Daten ohnehin keinen Wert legen (da er sich in dem Falle ja noch nicht mal um die Sicherheit seines Rechners im ganzen kümmert).

Ich denke, ich mache das so. Basta!

Message Digest
Der Schlüssel soll eine "Message Digest"-Kennzeichnung bekommen.

Hmmm, nun ja, hier handelt es sich ja um einen Schlüssel, der mir gehört. Viel besser würde ich es finden, wenn ich diesen Schlüssel mit meinem privaten Master-Schlüssel unterzeichnen könnte, weil dann hätte ich selbst eine viel bessere Kontrolle über die Integrität dieses Dingens und andere hätten es viel leichter, weil mein öffentlicher Master-Schlüssel ja schon seit langem überall im Netz verteilt ist. Außerdem wäre er damit auf eine sichere Weise unterzeichnet.
Aber aus einem mir momentan nicht ersichtlichen Grunde soll hier ein "Message Digest" eingesetzt werden. Tja, da kann man wohl nichts machen.

Was für einen nehme ich da bitteschön am besten? Es stehen ja mehrere zur Auswahl:
  • MD2
  • MD5
  • SHA1
  • MDC2
Ein Blick ins Internet eröffnet schnell, dass hier eigentlich gar nichts aktuell und "sicher" ist: Hmmm, also ich bin ja gemeinerweise kein ausgebildeter Mathematiker. Am wenigsten schwach hört sich für mich immer noch die Definition von MD2 an, allerdings ist der ja auch von vornherein nur 64 bit "wert" - wenn ich das so einigermaßen korrekt auf die Reihe gekriegt habe. Demnach würde ich wohl am sinnvollsten noch bei SHA1 liegen.

Na ja: Eigentlich ist das ja nicht weiter problematisch. Ich stelle einfach das Zertifikat samt meiner PGP-Unterschrift auf den Server und damit hat sich's. Dann habe ich den eingangs gewünschten Zustand doch hergestellt. Und dafür, dass SHA1 nicht mehr so sicher ist und was anderes momentan aber nicht zur Verfügung steht, trage ich ja nun keine Verantwortung...

Ich benutze also SHA1 und unabhängig davon meine eigene PGP-Signatur.

Schlüsselgenerierung

Jetzt sieht die Schlüsselgenerierung also folgendermaßen aus:
  • Ich stelle eine Konfigurationsdatei "ssl.cfg" bei der Schlüsselablage bereit mit folgendem Inhalt:
    [ req ] default_bits = 2048 distinguished_name = Servername attributes = req_attributes x509_extensions = v3_ca default_md = sha1 encrypt_key = no prompt = no [ Servername ] countryName = GE stateOrProvinceName = Mecklenburg-Vorpommern localityName = Neustrelitz organizationName = private organizationalUnitName = Server commonName = harryboeck.dyndns.org emailAddress = Harry.Boeck@t-online.de [ req_attributes ] challengePassword = Kennwort challengePassword_min = 15 challengePassword_max = 40 [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:true

  • Ich rufe eine Batchdatei (auch bei der Schlüsselablage) auf mit folgendem Inhalt:
    @echo off set openssl="<Pfad zur Datei openssl.exe>" set outpath="<Pfad zur Schlüsselablage>" :generate_keys %openssl genrsa -out "%outpath\server.key" 2048 :generate_sign %openssl req -config "%outpath\ssl.cfg" -key "%outpath\server.key" -new -x509 -nodes -days 1825 -out "%outpath\server.crt"
    rem Parameter: rem config: Konfigurationsdatei für alles, was nicht hier auf der Kommandozeile definiert wird rem new: Neues Zertifikat oder dessen Anforderung generieren! rem x509: Das mit der Anforderung wieder vergessen! rem nodes: keine Verschlüsselung der Ergebnisse (auf dass ihre Benutzung ohne Passworteingabe möglich ist)! rem sha1: Hashcode-Generator für zusätzliche Sicherung rem (halte ich für Nonsense, besser wäre eine Unterzeichnung mit einem PGP-Key, rem aber offenbar ist die Benutzung eines "Message Digest" im x509-Format vorgeschrieben...) rem days: Das Zertifikat soll für 5 Jahre gültig sein. Danach wird sich die ganze Sache eh weiterentwickelt haben.
    :exit

    Die Zeile mit "genrsa" kann man auch noch weglassen und in den "reg" integrieren, aber ich lasse das jetzt mal so stehen...

abschließende Einstellung der Apache-Konfiguration

Die zugehörige Dokumentation steht in http://httpd.apache.org/docs/2.2/mod/mod_ssl.html.
In der "Apache.cfg" steht jetzt folgendes...
#---------------------------------------- # Dateisystemzugriff | #----------------------------------------
... <Directory "<Pfad zum privaten Bereich>"> Options none AllowOverride all Order Deny,Allow # Während der Einrichtung... Deny from all Allow from 192.168.1.1 </Directory> ...
#---------------------------------------- # Verschlüsselung | #----------------------------------------
LoadModule ssl_module "modules/mod_ssl.so" <IfModule mod_ssl.c> #------------------------------------ # Allgemeine Maschinensteuerung #------------------------------------ AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl # Zufallswertedateien werden bei mir auf jeden Fall verschmäht... SSLRandomSeed startup builtin SSLRandomSeed connect builtin SSLPassPhraseDialog builtin # Anführungszeichen werden nicht gewünscht... # außerdem wird von selbst eine Endung (".pag") angehängt... SSLSessionCache dbm:<Pfad zur Schlüsselablage>/sslcache SSLSessionCacheTimeout 300 # laut Fehlermeldung werden nur "none" und "default" unterstützt... SSLMutex default Listen 192.168.1.1:443 #------------------------------------ # erlaubte Protokolle und Algorithmen #------------------------------------ SSLProtocol all -SSLv2 SSLCipherSuite ALL!ADH!NULL!LOW!EXP!SSLv2+HIGH+MEDIUM #nicht unterstützt... #SSLHonorCipherOrder on #------------------------------------ # Authentifizierung #------------------------------------ # Server Authentication gegenüber einem Client SSLCertificateFile "<Pfad zur Schlüsselablage>/server.crt" SSLCertificateKeyFile "<Pfad zur Schlüsselablage>/server.key" SSLCertificateChainFile "<Pfad zur Schlüsselablage>/server.crt" # Cient Authentication gegenüber dem Server: Die öffentlichen Schlüssel, # von denen einer auf ein Client-Zertifikat (öffentlicher Schlüssel des # Clients, signiert mit einem geheimem Schlüssel) passen muß. # Diese Dateien dürfen nicht leer sein, wenn sie hier notiert werden! #SSLVerifyClient require #SSLCACertificateFile "<Pfad zur Schlüsselablage>/ca-bundle.crt" #SSLCARevocationFile "<Pfad zur Schlüsselablage>/ca-bundle.crl" SSLVerifyDepth 1 <VirtualHost 192.168.1.1:443> DocumentRoot "<Pfad zum privaten Bereich>" ServerName "HTTPS-Server bei Harry Boeck" <Location /> SSLRequireSSL #SSLRequire %{SSL_CIPHER} !~ m/^(EXP|NULL)/ #and %{REMOTE_ADDR} =~ m/^192\.168\.1\.1$/ </Location> SSLEngine on </VirtualHost> </IfModule>

Zur Interpretation der Definitionen:
SSLProtocol
Unter den möglichen "SSLProtocol"s wird "SSLv2" abgeschaltet, weil es veraltet ist und kein aktueller Browser es mehr benötigen sollte.
SSLCipherSuite
Warum wird Anonymous Diffie-Hellmann ausgeschaltet? Ah ja: Wegen fehlender Authentifizierung.
Dazu habe ich allerdings immer noch eine eigene Meinung, die sich aus der Praxis für einfache Durchschnittsbürger, die mathematisch weder begabt noch überhaupt interessiert sind und die weder mit einer Firewall- noch mit einer x-beliebigen anderen Mitteilung, Warnung oder Fehlermeldung, die irgendetwas anderes beinhaltet als was sie im Augenblick gerade vordergründig interessiert, etwas anderes anstellen als sie wegzuklicken. Ähmmm, nein: Solche Leute klicken auch alle Mitteilung, Warnung und Fehlermeldungen weg, die unmittelbar mit dem zu tun haben, was sie im Augenblick gerade vordergründig interessiert. Um anschließend bei Bekannten oder bei zu bemitleidenden Service-Mitarbeitern anzurufen und ihnen Vorwürfe zu machen, wie schlecht das Programm xyz funktioniert...
Zu klären: Eventuell sollte ich also ADH doch wieder zulassen? Weil es in der Praxis DE FAKTO exakt das ist, was "hinten rauskommt"?

Alle geringwertigen Verschlüsselungen werden verboten, weil die eh nur Verschleierungen darstellen.

Die laut Dokumentation notwendig sein sollenden Trennzeichen ":" im Definitionsstring für SSLCipherSuite sind optional, falls gerade kein anderes Trennzeichen verwendet wird. Die Operatoren ("!","+","-") sind Trennzeichen.
SSLVerifyDepth
Wenn Client-Authentifizierung mit Zertifikaten genutzt wird, werde ich der einzige sein, der von mir akzeptierte Zertifikate ausstellt (es sei denn, ich gründe noch mal ein eigenes Unternehmen mit einer ganzen Hierarchie von Zertifizierern (ganz zu schweigen von der Masse der Leute, die von denen dann versorgt zu werden hätten)).