Kategorien
Tutorials

HTTPS mit SAN-Zertifikat für Apache unter Ubuntu konfigurieren

Mittlerweile gehört ein TLS-Zertifikat für einen Webserver zum guten Ton und kann als Standard angesehen werden. Wie mit einem solchen Zertifikat HTTPS unter Apache und Ubuntu konfiguriert werden kann, zeige ich in diesem Artikel. Wir erstellen dafür ein SAN-Zertifikat und nutzen das Kommandozeilentool OpenSSL.

Technisch gesehen ist TLS der Nachfolger von SSL. In der Praxis werden beide Begriffe jedoch oft synonym verwendet, was zu Missverständnissen führen kann. Wenn in diesem Artikel SSL thematisiert wird, ist daher auch immer TSL gemeint.

SAN-Zertifikate

Anders als herkömmliche Zertifikate ist ein SAN-Zertifikat nicht nur für eine Domain gültig, sondern für mehrere alternative Domains oder IP-Adressen. Daher auch der Name SAN (Subject Alternative Name).

SAN-Zertifikat subjectAltName
Ein SAN-Zertifikat ist für mehrere Domains oder IP-Adressen gültig.

Wer mehr über die Hintergründe von SAN-Zertifikaten lesen möchte, sollte sich einmal den Abschnitt Hintergründe von SAN-Zertifikaten von meinem Kollegen Oguz Cankurt durchlesen.

Arbeitsordner erstellen

Alle relevanten Dateien für das SAN-Zertifikat möchte ich an einem zentralen Ort im Webserververzeichnis ablegen. Dafür erstelle ich einen Arbeitsordner, in dem ich alle SSL-relevanten Dateien ablege:

sudo mkdir /etc/apache2/ssl
cd /etc/apache2/ssl/

Erstellung der req.conf

Zunächst ist eine Konfigurationsdatei zu erstellen, in der die gewünschten DNS- und IP-Einträge zu hinterlegen sind. Die eigentliche Konfigurationsdatei ist mit folgendem Befehl erstellt:

sudo touch ubusrvreq.conf
sudo nano ubusrvreq.conf

In der Konfigurationsdatei ist folgender Inhalt anzugeben:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = DE
ST = NRW
L = ESSEN
O = NOCKSOFT
OU = IT
CN = ubusrv.lab.local
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.52.154
DNS.1 = ubusrv
DNS.2 = ubusrv.lab.local
DNS.3 = ubusrvalias
DNS.4 = ubusrvalias.lab.local

Die Werte unter "[req_distinguished_name]" und "[alt_names]" sind entsprechend anzupassen. Unter "[alt_names]" können auch beliebige Einträge hinzugefügt oder entfernt werden. Wichtig ist nur die Nummerierung der Parameter.

OpenSSL req.conf für SAN-Zertifikat
Die req.conf beinhaltet die wesentlichen Informationen für das spätere Zertifikat.
Wer nicht möchte, dass das Zertifikat auch für die IP-Adresse gültig ist, kann den Eintrag einfach entfernen.

Private Key erstellen

Der Private Key ist wie folgt erstellt:

sudo openssl genrsa -out ubusrv.key 2048

Im oberen Beispiel wird der Private Key mit einem 2048 Bit Schlüssel erstellt. Das ist Stand 2021 ausreichend sicher. Wer mehr Sicherheit möchte, kann auf Lasten der Rechenkapazität auch einen stärkeren Schlüssel wie 4096 Bit angeben.

Der Private Key ist geheim zu halten und sollte niemandem mitgeteilt werden. Ansonsten könnte die entsprechende Person die Verschlüsselung aufbrechen.

CSR erstellen

Mit dem Private Key und der Konfigurationsdatei kann jetzt ein CSR erstellt werden, der später für das Zertifikat benötigt wird. Das geht wie folgt:

sudo openssl req -new -out ubusrv.csr -key ubusrv.key -config ubusrvreq.conf

Zertifikat erstellen

Es gibt jetzt mehrere Möglichkeiten das Zertifikat zu erstellen. Ich stelle zwei Möglichkeiten genauer vor: Active Directory Zertifikatsdienste und Self Signed Zertifikat. Der Weg über die Active Directory Zertifikatsdienste oder einer anderen Lösung zur Erzeugung von gültigen Zertifikaten, ist wenn möglich, dem Self Signed Zertifikat immer vorzuziehen.

Zertifikat über die Active Directory Zertifikatsdienste erstellen

Der Inhalt des CSR kann einfach kopiert und in den Active Directory Zertifikatsdiensten eingefügt werden. In den Active Directory Zertifikatsdiensten ist eine erweiterte Zertifikatsanforderung zu erstellen:

Active Directory Zertifikatsdienste SAN-Zertifikat
Über die Active Directory Zertifikatsdienste kann ein neues Webserverzertifikat angefordert werden.

Das Zertifikat (*.cer) kann nun in Base-64-codiert heruntergeladen werden:

Active Directory Zertifikatsdienste SAN-Zertifikat
Für Linux-Systeme kann das Zertifikat als Base-64-codiert heruntergeladen werden.

Anschließend ist das Zertifikat wieder auf dem Server unter /etc/apache2/ssl/ abzulegen. Dazu gibt es zwei Wege: Entweder man überträgt die Zertifikatsdatei per WinSCP auf den Ubuntu-Server oder man erstellt auf dem Ubuntu-Server eine neue Datei und fügt den Inhalt der heruntergeladenen Zertifikatsdatei dort ein:

cd /etc/apache2/ssl/
sudo touch ubusrv.cer
sudo nano ubusrv.cer
Die heruntergeladene Zertifikatsdatei kann einfach mit einem beliebigen Texteditor geöffnet werden. Der Inhalt sieht wie folgt aus:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Self Signed Zertifikat mit OpenSSL erstellen

Wer über keine Active Directory Zertifikatsdienste verfügt oder aus einem anderen Grund lieber ein selbst signiertes Zertifikat erstellen möchte, kann dies wie folgt tun:

sudo openssl x509 -req -days 365 -in ubusrv.csr -signkey ubusrv.key -sha256 -out ubusrv.cer
Ein selbst signiertes Zertifikat wird die Verbindung zwischen Client und Server zwar verschlüsseln, aber dennoch eine Sicherheitswarnung im Browser hervorrufen.
Beim Erstellen eines Self Signed Zertifikates mit dem oberen Befehl gehen die Informationen der subjectAltNames verloren. Das ist allerdings nicht weiter tragisch, weil bei einem Self Signed Zertifikat sowieso eine Zertifikatswarnung angezeigt wird. Grundsätzlich sollte in produktiven Umgebungen aber nicht mit selbst signierten Zertifikaten gearbeitet werden. Andernfalls besteht die Gefahr, dass Benutzer sich an Zertifikatswarnungen gewöhnen.

Zertifikat von einer offiziellen CA ausstellen lassen

Soll das Zertifikat im Internet verwendet werden, ist der CSR einem entsprechenden Dienstleister wie z.B. GlobalSign o.ä. einzureichen, der ein gültiges Zertifikat für den CSR ausstellt.

Zertifikat in Apache einbinden

In dieser Anleitung werden wir die Apache-Konfiguration im VirtualHost anpassen. Wenn noch keine vorhanden ist, muss zunächst eine erstellt werden:

cd /etc/apache2/sites-available/
sudo touch vhost.conf
sudo nano vhost.conf

Eine gültige Konfiguration kann sich von Anwendung zu Anwendung unterscheiden. Hier daher ein Beispiel für eine einfache Webseite mit HTTPS und automatischer Weiterleitung von HTTP auf HTTPS:

<VirtualHost *:80>
  ServerName 192.168.52.154
  ServerAlias ubusrv ubusrv.lab.local ubusrvalias ubusrvalias.lab.local

  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule (.*) https://%{SERVER_NAME}$1 [R,L]
</VirtualHost>


<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/ubusrv.cer
  SSLCertificateKeyFile /etc/apache2/ssl/ubusrv.key
  SSLProtocol -ALL +TLSv1.2 +TLSv1.3

  ServerName 192.168.52.154
  ServerAlias ubusrv ubusrv.lab.local ubusrvalias ubusrvalias.lab.local
  DocumentRoot /var/www/html
</VirtualHost>
Apache VirtualHost HTTPS/SSL
Alle relevanten Konfigurationen für die Webseite samt HTTPS sind in dieser einen Konfigurationsdatei zusammengefasst.
ServerName und ServerAlias legen fest, unter welchen DNS-Namen bzw. IP-Adressen die Webseite aufrufbar sein soll und muss in beiden VirtualHosts angegeben werden. Die Zeile SSLProtocol -ALL +TLSv1.2 +TLSv1.3 schaltet veraltete Sicherheitsprotokolle ab und lässt nur noch die aktuellen Protokolle TLS 1.2 und TLS 1.3 zu.
Die obere Konfiguration leitet alle Anfragen von Port 80 (oberer VirtualHost) auf Port 443 (unterer VirtualHost) weiter. Daher sind alle relevanten weiteren Konfigurationen für die Webseite wie eventuell ein <Directory /dir/subdir>...</Directory> usw. im unteren VirtualHost vorzunehmen. Der obere VirtualHost kümmert sich nur um die Weiterleitung auf HTTPS und hat sonst keine Bedeutung mehr.

Außerdem muss der VirtualHost sowie das SSL- und Rewrite-Modul im Apache noch aktiviert werden:

sudo a2ensite vhost.conf
sudo a2enmod ssl
sudo a2enmod rewrite
sudo service apache2 restart

Jetzt ist die Seite per HTTPS aufrufbar:

Apache unter Ubuntu mit HTTPS absichern
Apache ist damit entsprechend konfiguriert und die Webseite über HTTPS erreichbar.

HSTS aktivieren

Apache und HTTPS ist auf dem Ubuntu-Server jetzt erfolgreich konfiguriert. Wer jedoch optional die Sicherheit durch HSTS weiter erhöhen möchte, kann HSTS wie folgt in der VirtualHost-Konfiguration aktivieren:

<VirtualHost *:80>
  ServerName 192.168.52.154
  ServerAlias ubusrv ubusrv.lab.local ubusrvalias ubusrvalias.lab.local

  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule (.*) https://%{SERVER_NAME}$1 [R,L]
</VirtualHost>


<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/ubusrv.cer
  SSLCertificateKeyFile /etc/apache2/ssl/ubusrv.key
  SSLProtocol -ALL +TLSv1.2 +TLSv1.3
  Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"

  ServerName 192.168.52.154
  ServerAlias ubusrv ubusrv.lab.local ubusrvalias ubusrvalias.lab.local
  DocumentRoot /var/www/html
</VirtualHost>
Es ist im VirtualHost lediglich die Zeile Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;" ergänz worden (siehe unterer VirtualHost unter der Zeile SSLProtocol...).

Der Parameter max-age wird in Sekunden angegeben und sagt aus, für die lange zu dem Server nur noch eine gesicherte Verbindung über HTTPS aufgebaut werden darf.

Anschließend muss das Headers-Modul noch im Apache aktiviert werden:

sudo a2enmod headers
sudo service apache2 restart

Quellen
https://www.thomas-krenn.com/de/wiki/Openssl_Multi-Domain_CSR_erstellen
https://www.bjoerns-techblog.de/2017/07/hsts-im-apache-aktivieren/

Seit mehreren Jahren begeistere ich mich privat und beruflich für die IT. Das habe ich dann auch zum Anlass genommen, diesen Blog ins Leben zu rufen, um dort praxisnahe Tutorials über verschiedene IT-Themen zu schreiben und meine selbst geschriebene Software zu veröffentlichen.

2 Antworten auf „HTTPS mit SAN-Zertifikat für Apache unter Ubuntu konfigurieren“

Hallo, danke erstmal für diese tolle Anleitung! Ich habe diese Anleitung für eine lokale Instanz umgesetzt (allerdings unter Windows 10 in Verbindung mit XAMPP). Unter Chromium Browsern wird das Zertifikat auch als Sicher angezeigt. Unter Firefox allerdings bekomme ich folgende Fehlermeldung:
Fehlercode: SEC_ERROR_UNKNOWN_ISSUER

Der Zertifikat-Aussteller der Gegenstelle wurde nicht erkannt.

HTTP Strict Transport Security: false
HTTP Public Key Pinning: false

Hättest du eventuell eine Idee was ich falsch gemacht haben könnte?

Gruß
Adrian

Hallo Adrian,
Firefox hat seinen eigenen Zertifikatsspeicher und greift nicht auf den von Windows zu. Eventuell müsstest du das Zertifikat also erst im Firefox installieren oder als Ausnahme definieren. Die Fehlermeldung "SEC_ERROR_UNKNOWN_ISSUER" deutet darauf hin, dass das Zertifikat selbstsigniert ist und dem Browser erst als "sicher" erklärt werden muss.
LG Rafael

Schreibe einen Kommentar

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