Lokales SSL-Zertifikat einrichten

Ich habe gerade die erste meiner Webseiten auf HTTPS umgestellt. Da ich meine Webseiten lokal entwickele, macht es Sinn, auch diese lokale Entwicklungsversion auf HTTPS umzustellen, damit eventuelle Probleme frühzeitig auffallen. Hier beschreibe ich kurz mein Vorgehen dazu.

Die Arbeitsumgebung

Ich arbeite unter Windows 10 mittlerweile mit dem WAMP-Stack von Bitnami, der mir mit einer Installation Apache und MySQL mitbringt. Die Entwicklungsversion meiner Webseiten rufe ich unter einer lokalen Domain auf, z.B. ammaletu.loc statt ammaletu.de. Dazu habe ich einfach folgendes in die HOSTS-Datei eingetragen:

127.0.0.1	ammaletu.loc

Windows fragt zu dieser nicht-existenten Top-Level-Domain dann keinen Nameserver, sondern wendet sich direct an die IP 127.0.0.1 alias localhost. Im Apache braucht man dann noch einen Virtual Host, der die Anfrage unter der IP 127.0.0.1 bearbeitet. Dazu habe ich in der vhosts_extra.conf-Datei eingetragen:

<VirtualHost 127.0.0.1:80>
	ServerName ammaletu.loc
	DocumentRoot "D:/[Pfad zur Webseite]"
	<Directory "D:/[Pfad zur Webseite]">
		Options FollowSymLinks
		AllowOverride All
		Require all granted
	</Directory>
</VirtualHost>

Diese Datei wird in meinem Setup aus der http.conf heraus eingebunden und enthält alle meine VirtualHost-Definitionen. Ich habe mir die Datei in einen Ordner gelegt, wo ich meine eigenen Änderungen gut sichern kann, damit beim WAMP-Stack-Update nichts verloren geht.

Zertifikat erstellen Teil 1: Root-CA

Ein lokales Zertifikat kann man sich einfach mit dem Tool OpenSSL selbst erstellen. Da ich auf Anhieb keine Windows-Installation gefunden habe, habe ich das auf einem älteren Ubuntu-Laptop gemacht. Es sollte unter Linux eigentlich nie in Problem sein, dieses Tool zu benutzen, denke ich. Für das genaue Vorgehen (auch für den nächsten Schritt) habe ich diese Anleitung benutzt.

Als erstes erstellt man eine eigene Root-CA (CA = Certificate Authority). Die Root-CA ist quasi die Stelle, welche das konkrete Zertifikat dann herausgibt. Da ich mehrere lokale Webseiten auf SSL umstellen muss, habe ich mir die Root-CA an eine zentrale Stelle gespeichert und sie allgemein gehalten. So kann ich sie dann für die weiteren Webseiten wiederverwenden und spare mir dabei Arbeit.

Folgt dafür der verlinkten Anleitung unter dem Punkt „Create the root.cnf“, mit einer Ergänzung: Standardmäßig ist die generierte CA nur 30 Tage gültig. Das ist natürlich Quatsch, mit dem Parameter „-days 3650″ gilt sie dann 10 Jahre. Zusammen also so:

openssl req -x509 -new -days 3650 -keyout root.key -out root.cer -config root.cnf

Ihr habt nun die drei Dateien „root.cnf“, „root.cer“ und „root.key“. Diese solltet ihr gut aufheben, genau wie das für die Root-CA vergebene Passwort.

An dieser Stelle kann man die neue CA auch gleich im Browser bekannt machen. Versuche, meinen Firefox sie aus dem Windows-Zertifikatsstore laden zu lassen, haben bei mir leider nicht funktioniert. Windows kennt nun meine Root-CA zwar, aber Firefox hat von dort irgendwie nichts übernommen, trotz Änderung in der about:config und Neustarts. Egal, importiert man sie eben einmalig in den Browser. Ruft dazu Extras -> Einstellungen -> Datenschutz & Sicherheit -> Zertifikate -> Zertifikate anzeigen auf. Auf dem Tab „Zertifizierungsstellen“ dann einfach die gerade erstellte Datei „root.cer“ importieren. Die Checkbox für „Dieses Zertifikat kann Webseiten identifizieren“ muss dabei gesetzt sein.

Zertifikat erstellen Teil 2: Das Zertifikat

Die neue Root-CA kann nun Zertifikate für die lokalen Webseiten erstellen. Folgt dabei wieder der verlinkten Anleitung, unter dem Punkt „Create the server.cnf“. Ihr erhaltet dann die Dateien „server.csr“, „server.key“ und „server.cer“. Letzteres ist das eigentliche Zertifikat. Die drei Dateien speichere ich mir in einem „cert“-Ordner zu meiner lokalen Seite, aber natürlich so, dass sie außerhalb des git-Projektes liegen und auch nicht mit auf die produktive Seite ausgeliefert werden.

Wichtig wenn ihr das mehrmals macht: Der zweite Befehl, der das eigentliche Zertifikat erstellt, enthält diesen Teil hier: „-set_serial 123″. Wenn man hier jedes Mal die „123″ als Seriennummer nimmt, akzeptiert Apache diese Zertifkate nicht, da die Seriennummer zum ersten auf diese Weise erstellten Zertifkat gehört. Einfach weglassen geht auch nicht. Ich habe dann als Seriennummer einfach das Datum genommen, also z.B. „-set_serial 201903260054″. Man muss halt dran denken, das zu variieren. Den Fehler bemerkt man sonst erst beim Testen und kann das dann alles noch mal machen.

Apache konfigurieren

Damit die lokale Seite per HTTPS aufgerufen werden kann, brauchen wir einen neuen Virtual Host. HTTPS läuft üblicherweise über Post 443, also ergänzen wir in der vhosts_extra.conf:

<VirtualHost 127.0.0.1:443>
	ServerName ammaletu.loc
	DocumentRoot "D:/[Pfad zur Webseite]"
	SSLEngine On
	SSLCertificateFile "D:/[Pfad zum Zertifikatsordner]/server.cer"
	SSLCertificateKeyFile "D:/[Pfad zum Zertifikatsordner]/server.key"
	<Directory "D:/[Pfad zur Webseite]">
		Options FollowSymLinks
		AllowOverride All
		Require all granted
	</Directory>
</VirtualHost>

So, jetzt noch den Apache neustarten, dann klappt der Aufruf der Seite per HTTPS.

Aufruf üer HTTPS

Nun kann man in der .htaccess-Datei der Seite noch sicherstellen, dass die Seite ausschließlich per HTTPS aufgerufen werden kann:

# force HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Ruft man nun „http://ammaletu.loc“ auf, so wird man zu „https://ammaletu.loc“ umgeleitet.

Im Apache-Errorlog fand sich übrigens beharrlich diese Warnung:

AH01909: localhost:443:0 server certificate does NOT include an ID which matches the server name

Normalerweise weist einen das daraufhin, dass man z.B. das Zertifikat auf „www.example.org“ ausgestellt, aber im VirtualHost als ServerName „example.org“ eingetragen hat, mit dem Alias „www.example.org“. Das funktioniert dann trotzdem alles, und die Meldung geht weg, wenn man ServerName und ServerAlias vertauscht. In meinem Fall gab es aber keinen Alias, an beiden Stellen stand „ammaletu.loc“.

Nach sehr viel Suchen und Probieren habe ich herausgefunden, dass Bitnami einen Default-Virtual-Host definiert, der hier irgendwie stört. Da ich diesen Default-VirtualHost nicht brauche, habe ich ihn einfach aus der Konfigurationsdatei entfernt. Die betreffende Datei wird von der httpd.conf aus eingebunden und liegt hier: wampstack-7.2.13-1\apache2\conf\bitnami\bitnami.conf. Darin findet sich dieser längere Block:

<VirtualHost _default_:443>
  DocumentRoot "D:/[Pfad zum WAMP-Stack]/apache2/htdocs"
  SSLEngine on
  SSLCertificateFile "D:/[Pfad zum WAMP-Stack]/apache2/conf/server.crt"
  SSLCertificateKeyFile "D:/[Pfad zum WAMP-Stack]/apache2/conf/server.key"
  
  # ...
  
  # Bitnami applications installed with a prefix URL (default)
  Include "D:/[Pfad zum WAMP-Stack]/apache2/conf/bitnami/bitnami-apps-prefix.conf"
</VirtualHost>

Mag sein, dass das für einige Teile des WAMP-Stacks nötig ist. Da ich nur Apache, MySQL und phpMyAdmin davon nutze, kann ich darauf verzichten. Nach einem erneuten Neustart des Apache war die nervige Warnung dann aus dem Log verschwunden.

4 Gedanken zu „Lokales SSL-Zertifikat einrichten

  1. Ich bin nach den Anleitungen vorgegangen, bei mir funktionieren die Zertifikate nicht. Sorry mich macht das wütend 3 Stunden an dem Müll zu sitzen und keinen Erfolg zu haben.
    In meinen Zertifikat steht:
    Die Integrität dieses Zertifikats kann nicht garantiert werden. das Zertifikat ist eventuell beschädigt oder wurde geändert.
    Ist mit Root CA die root.cnf gemeint?

  2. Kann ich verstehen, sowas ist frustrierend. Ohne genauere Infos kann ich hier aber auch nur raten. Wenn ich nach der Fehlermeldung google, dann kommen u.a. Hinweis darauf, dass eine zu geringe Schlüssellänge benutzt wurde. In den cnf-Dateien steht die unter „default_bits“. Sie muss wohl über 1024 liegen, in der Anleitung war 2048 eingetragen.

    Möglich wäre natürlich auch, dass die generierten Dateien tatsächlich verändert wurden, z.B. die Zeilenumbruch-Zeichen, falls sie per SFTP übertragen wurden von einem Client, der sowas automatisch macht. Die müssen alle exakt so bleiben, wie sie angelegt wurden.

    Ansonsten: Wurde die Root-CA korrekt im Browser bekannt gemacht? Welcher Browser ist es überhaupt? Wurde er nach dem Eintrag neugestartet?

    Die CNF-Dateien sind die Konfigurationen, aus denen dann der Kommandozeilen-Aufruf das Zertifikat (die CER-Datei) und einen Private Key (die KEY-Datei) generiert. Das gehört alles zusammen und sollte aufgehoben werden, falls man die Zertifikate mal neu ausstellen möchte.

  3. Problem gelöst. xD jetzt funzt es…
    Meine 2 Fehler waren:
    1.) Die root.cer hatte ich nicht als Vertrauenswürdige Zertifizierungsstelle in Windows eingefügt.
    2.) Ein Fehler in der server.cnf aufgrund der Anleitung. Wenn man da mehrere DNS (DNS.1 = http://www.beispiel.server, DNS.2 = usw.) einträgt dann darf bei commonName = nur * stehen und nicht http://www.beispiel.server sonst ist das Zertifikat fehlerhaft.

    Herausgefunden habe ich es dadurch:
    https://secure.comodo.net/utilities/decodeCSR.html

    Dort kann man per C&P den Code der server.csr einfügen und auch das wildcart Format prüfen.

    Mit dem Befehl kann man die root.cer prüfen
    openssl x509 -in root.cer -text -noout
    In der Mitte der Textausgabe muss CA:TRUE erscheinen, dann ist die root.cer OK.

    Wer unter Windows mit OpenSSL arbeitet kann die Zertifikate auch auf einer anderen Partition erstellen und anschließend auf C:\…..\Apache\ server.crt unsw. einfügen. Dazu Eingabeaufforderung als Admin:

    D:
    cd D:\Pfad\Zu\Den\Zertifikaten
    „C:\Pfad\Zu\OpenSSL-Win64\openssl.exe“ req -x509 -days 365 -new -keyout root.key -out root.cer -config root.cnf

    Was den letzten Befehl betrifft:
    openssl x509 -days 3650 -req -in server.csr -CA root.cer -CAkey root.key -set_serial 123 -out server.cer -extfile server.cnf -extensions x509_ext

    habe ich ihn so verändert:

    openssl x509 -days 3650 -req -in server.csr -CA root.cer -CAkey root.key -set_serial 123 -out server.crt -extfile server.cnf -extensions x509_ext

    Damit ein server.crt anstatt eines server.cer erstellt wird, da mein xampp Apache mit einer server.crt arbeitet.

    Wenn man in der Eingabeaufforderung als Admin:
    mmc
    eingibt kann man in der Konsole die öffnet über snap in in den Zertifakt Ordner von Windows und dort veraltete Zertifikate Problemlos löschen.

    Ansonsten danke für deine Arbeit hat mir sehr geholfen da mein Opera Browser das veraltete Standart Zertifikat mit festen commonName was man mit dem Befehl makecert im Apache erstellen kann nicht akzeptiert. Er will ein Wildcart Zertifikat um eine separate Überprüfung der Server Adresse (DNS) vornehmen zu können. Das Standart Zertifikat hat nur im Internet Explodierer funktioniert.
    Außerdem sind selbst erstellte Zertifikate auch besser wenn es um die länge der Gültigkeit geht.

  4. Vielen Dank für den ausführlichen Kommentar! Das hilft hoffentlich dem ein oder anderen weiter, der ähnliche Probleme hat. Das mit dem Hinzufügen als vertrauenswürdiges Zertifikat in Windows ist spannend. Das habe ich vermutlich gemacht, weil ich anfangs dachte, dass der Browser es komplett von Windows beziehen kann. Das hatte nicht geklappt, war dann aber als Arbeitsschritt vielleicht trotzdem nötig.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Bitte beachte die Kommentarregeln: 1) Kein Spam, und bitte höflich bleiben. 2) Ins Namensfeld gehört ein Name. Gerne ein Pseudonym, aber bitte keine Keywords. 3) Keine kommerziellen Links, außer es hat Bezug zum Beitrag. mehr Details...

So, noch mal kurz drüber schauen und dann nichts wie ab damit. Vielen Dank fürs Kommentieren! :-)