Problem:
Auf einem Server (Apache) liegen mehrere Domains, die von Tomcat ausgeliefert werden. Die Verschlüsselung kann nicht mit einem normalen Zertifikat für jeweils eine Domain durch Tomcat erfolgen, weil dieser keine unterschiedlichen Zertifikate verwalten kann. Und Apache weiß überhaupt nichts von den unterschiedlichen Domains, die Trennung erfolgt bei mir erst eine Ebene weiter unten, beim Tomcat.
Man benötigt also ein SAN (Subject Alternative Name)-Zertifikat, das mehrere Domainnamen in einem Zertifikat unterbringt. Dieses kann dann dem Apache übergeben werden, dem dann egal sein kann, welche Domain gerade aufgerufen wurde, er hat immer das richtige Zertifikat parat.
Kostenlose SAN-Zertifikate habe ich leider keine gefunden, aber es gibt recht günstige Anbieter auf dem Markt. Bei meinem Versuch, dort ein Zertifikat zu beantragen und auf dem Server korrekt zum Laufen zu bringen, ergaben sich einige Stolperstellen, deshalb hier die Beschreibung des Lösungswegs.
Lösung:
Zertifikatsantrag erstellen
Bevor man bei einem Anbieter ein Zertifikat kaufen kann, muss man auf dem eigenen Server erst einen passenden Antrag zusammenstellen. Dabei erstellt man das Schlüsselpaar (öffentlicher und privater Schlüssel) sowie eine Antragsdatei, die einige Angaben über den eigenen Server enthält. Wie man diese Dateien erstellt, dafür gibt es im Netz viele Anleitungen. Allerdings unterscheidet sich das Erstellen von SAN-Zertifikatsanträgen an ein paar entscheidenden Stellen vom üblichen Vorgehen, schließlich braucht man nicht nur einen, sondern noch eine oder mehrere weitere (Alternative Name...) Domainadressen.
Zunächst erstellt man ein Schlüsselpaar (privat und öffentlich) mit dem Befehl
openssl genrsa -out example.com.key 2048
wobei der Dateiname example.com beliebig ist.
Aus diesem Schlüssel (dem öffentlichen Teil natürlich, der private wird nicht "aus der Hand" gegeben!) kann man jetzt einen Zertifikatsantrag erstellen. Allerdings muss man dazu zunächst die Konfiguration des betreffenden Programms anpassen. Hierzu erstellt man ein File csr.conf mit folgendem Inhalt:
prompt = yes
distinguished_name = req_distinguished_name
req_extensions = req_ext
[req_distinguished_name]
commonName = Common Name
commonName_default = www.adresse1.de
countryName = Country Name
countryName_default = DE
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State
stateOrProvinceName_default = BW
localityName = City
localityName_default = Reutlingen
organizationName = Organization
organizationName_default = Meine Organisation
organizationalUnitName = Unit
organizationalUnitName_default = Meine Einrichtung
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.adresse2.de
DNS.2 = www.adresse3.de
Bei meinem Zertifikateanbieter mussten die Angaben zur Organisation usw. im Zertifikatsantrag stehen, blieben die Felder leer, konnte man den Antrag nicht abschließen, die Felder aber auch nicht nachträglich ausfüllen.
Jetzt kann man das Zertifikat erstellen mit dem Befehl:
openssl req -new -key example.com.key -config csr.conf -out example.com.csr
openssl fragt in der Folge ein paar weitere Parameter ab, bis schließlich das csr-File erstellt ist.
Jetzt kann man mit der csr-Datei den das Zertifikat beim Anbieter beantragen. Am Ende des Prozesses sollte man eine crt-Datei (oder pem-Datei) erhalten (oder nur den Inhalt, den man in eine neue Datei hineinkopiert).
SSL auf dem Server einrichten und aktivieren
Jetzt muss man die Dateien an den richtigen Ort verschieben. Bei Linux mit Apache sind das folgende Pfade:
Die crt/pem-Datei nach /etc/ssl/certs/
Die key-Datei nach /etc/ssl/private/
Jetzt muss man nur noch dem Apache beibringen, zukünftig mit SSL zu verschlüsseln. Dazu sind folgende Änderungen/Ergänzungen in /etc/apache2/sites-available/000-default.conf notwendig:
Sofern alle Anfragen, auch an http.//... auf https://... umgeleitet werden sollen, kommen in den Abschnitt <VirtualHost *:80> folgende Zeilen hinein:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
In den Abschnitt <VirtualHost *:443> (wenn nicht vorhanden, dann von oben kopieren und abändern, DocumentRoot sollte vorhanden sein) kommen folgende Zeilen:
SSLEngine On
SSLCertificateFile /etc/ssl/certs/example.com.pem
SSLCertificateKeyFile /etc/ssl/private/example.com.key
Bei meinem Zertifikatsanbieter war noch ein ChainFile notwendig, weil kein Root-Zertifikat des Anbieters in Firefox & Co installiert war. Sofern notwendig, wird dies mit der Zeile
SSLCertificateChainFile /etc/ssl/certs/XYZChain.pem
eingebunden. (Vorher muss das File natürlich vom Anbieter heruntergeladen und hierher kopiert werden...)
Jetzt kann man noch seine SSL-Konfiguration anpassen, indem man unsichere Protokolle ausschließt, hier nutzt man am besten den Mozilla-SSL-Configuration-Generator und fügt dann die Zeilen
SSLProtocol ...
SSLCipherSuite ...
SSLHonorCipherOrder on
ein.
Nach einem Apache reload sollte jetzt die SSL-Verschlüsselung der beantragten URLs funktionieren, zu überprüfen mit
http://sslzilla.de/zertifikatstest.php.