Absicherung von Webdiensten mit 2FA: Zertifikat + Passwort
Einführung
- Zwei Faktoren: Besitz (Client-Zertifikat) und Wissen (Passwort).
- Der Server prüft das Client-Zertifikat gegen unsere CA (mTLS), danach folgt HTTP-Basic-Auth.
Ausgangspunkt
- Bestehender Apache-vHost gelb.it2XX.int (Debian) mit fertigem Server-Zertifikat
- Wenn vorhanden
- rm -v /var/www/gelb/.htaccess
- cat /etc/apache2/sites-available/server.conf
<VirtualHost *:443>
ServerName gelb.it2XX.int
DocumentRoot /var/www/gelb
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/gelb.it2XX.int-fullchain.pem
SSLCertificateKeyFile /etc/apache2/ssl/gelb.it2XX.int.key
<Directory /var/www/server>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/gelb_error.log
CustomLog ${APACHE_LOG_DIR}/gelb_access.log combined
</VirtualHost>
Client-Zertifikat erstellen
- Auf dem CA-Host
#Variablen setzen
CA=it2XX-ca
USER=xinux
#CSR erzeugen
openssl req -new -newkey rsa:2048 -nodes -keyout $USER.key -out $USER.csr -subj "/CN=$USER"
#Signieren
openssl x509 -req -in $USER.csr -CA $CA.crt -CAkey $CA.key -CAcreateserial -out $USER.crt -days 365 -extfile <(printf "extendedKeyUsage=clientAuth")
#PKCS12 für den Browser-Import bauen (Export-Passwort setzen)
openssl pkcs12 -export -in $USER.crt -inkey $USER.key -certfile $CA.crt -out $USER.p12
Benutzer für Basic-Auth anlegen
- htpasswd -c /etc/apache2/.htpasswd xinux
Apache-Konfiguration erweitern
- Die CA liegt bereits im System-Store, wir referenzieren die Datei direkt
- ls /usr/local/share/ca-certificates/
- cat /etc/apache2/sites-available/server.conf
<VirtualHost *:443>
ServerName server.it2XX.int
DocumentRoot /var/www/server
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.it2XX.int-fullchain.pem
SSLCertificateKeyFile /etc/apache2/ssl/server.it2XX.int.key
SSLCACertificateFile /usr/local/share/ca-certificates/ca.crt
SSLVerifyClient require
<Directory /var/www/server>
Options Indexes FollowSymLinks
AllowOverride All
AuthType Basic
AuthName "Login mit Benutzername und Passwort"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/server_error.log
CustomLog ${APACHE_LOG_DIR}/server_access.log combined
</VirtualHost>
- Config testen und neu laden
- apachectl configtest
- systemctl reload apache2
Zertifikat im Firefox einbinden
- Import
- Firefox → Einstellungen → Datenschutz & Sicherheit → Zertifikate anzeigen
- Reiter "Ihre Zertifikate" → Importieren → xinux.p12 (Export-Passwort eingeben)
- Verwendung
Test
- Kein Zertifikat
- TLS-Handshake-Fehler (curl: alert certificate required, kein HTTP-Fehlercode)
- Falsches Passwort
- Zertifikat + Passwort korrekt
- Test mit curl
Optional: Nur bestimmten CN zulassen
- SSLVerifyClient prüft nur die Signatur der CA – jedes von ihr ausgestellte Zertifikat wird akzeptiert.
- Im Directory-Block ergänzen
Require expr "%{SSL_CLIENT_S_DN_CN} == 'xinux'"
- Testfall
- gültiges Zertifikat, falscher CN
Fazit
- mTLS plus Basic-Auth ergibt eine echte 2-Faktor-Absicherung: Besitz und Wissen.
- SSLCACertificateFile bestimmt, wessen Client-Zertifikate akzeptiert werden – einen Default auf den System-Store gibt es bewusst nicht.