Dokumentation: Apache2 SSL-Konfiguration & Server-Härtung
1. Problem: ERR_SSL_PROTOCOL_ERROR / SSL_ERROR_RX_RECORD_TOO_LONG
Symptom: Beim Aufruf des Servers über HTTPS brach die Verbindung mit einem Protokollfehler ab. Ursache:
- Das selbstsignierte Zertifikat wurde ohne Subject Alternative Name (SAN) generiert. Moderne Browser erzwingen diesen Eintrag für IP-Adressen und ignorieren den alten Common Name (CN).
- Die Konfigurationsdatei
default-ssl.confwar in Apache zwar bearbeitet, aber nicht aktiv geschaltet (sites-enabled). Dadurch lieferte Apache auf Port 443 unverschlüsselten HTTP-Klartext statt eines SSL-Handshakes aus.
2. Diagnose-Werkzeuge
Für die Fehlersuche bei VirtualHosts und Ports ist dieser Befehl der wichtigste Indikator:
sudo apache2ctl -S
Er zeigt die exakte Ladereihenfolge und Port-Zuweisung aller aktiven VirtualHosts an.
3. Lösung: Zertifikat mit SAN neu erstellen
Erstellung des selbstsignierten Zertifikats inklusive der zwingend erforderlichen IP-Deklaration im SAN-Block:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/apache-selfsigned.key \
-out /etc/ssl/certs/apache-selfsigned.crt \
-subj "/CN=5.45.104.139" \
-addext "subjectAltName = IP:5.45.104.139"
4. Einrichtung des "Lumpensammlers" (Fallback VirtualHost)
Um unbefugte IP-Aufrufe oder unbekannte Domains ressourcenschonend abzufangen, wird die default-ssl.conf als erster VHost (alphabetisch priorisiert via 000-default-ssl.conf) geladen. Statt Daten auszuliefern, bricht sie die Verbindung sofort mit einem nackten 403 Forbidden ab.
Datei: /etc/apache2/sites-available/default-ssl.conf
<VirtualHost *:443>
# Kein ServerName -> Greift als globaler Fallback
DocumentRoot /var/www/html/nix
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
# TLS-Protokolle: Nur moderne Standards erlauben
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
# Sichere Cipher-Suite (inklusive AES128)
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
SSLCompression off
# Sofortiger Abbruch mit HTTP 403 (Ressourcenschonend gegen Bot-Grundrauschen)
Redirect 403 /
ErrorDocument 403 "Forbidden"
<Directory /var/www/html/nix>
AllowOverride None
Require all denied
</Directory>
ErrorLog ${APACHE_LOG_DIR}/ssl_fallback_error.log
CustomLog ${APACHE_LOG_DIR}/ssl_fallback_access.log combined
</VirtualHost>
Konfiguration aktivieren:
sudo a2ensite default-ssl.conf
# Optional: Verknüpfung als 000-default-ssl erzwingen für Ladepriorität
sudo ln -sf /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/000-default-ssl.conf
sudo apache2ctl -t
sudo systemctl restart apache2
5. Globale Server-Härtung (Sicherheit)
Um potenziellen Angreifern keine Details über das Betriebssystem oder die Apache-Version zu verraten, werden die Header global minimiert.
Datei: /etc/apache2/conf-available/security.conf
# Nur noch "Server: Apache" im Header senden (keine Versionsnummern)
ServerTokens Prod
# Fußzeilen auf generierten Fehlerseiten ausblenden
ServerSignature Off
Aktivierung:
sudo a2enconf security
sudo systemctl reload apache2
6. Überprüfung des Setups
Ein Test via curl gegen die IP-Adresse muss aufgrund des selbstsignierten Zertifikats fehlschlagen (Sicherheitsfeature). Mit dem Parameter -k (insecure) lässt sich das Ergebnis verifizieren:
curl -Ik https://5.45.104.139
Erwartete Ausgabe:
HTTP/1.1 403 Forbidden
Server: Apache
Content-Type: text/html; charset=iso-8859-1
...
(Das Ergebnis zeigt: Der Server maskiert sich als reines "Apache" und blockiert den IP-Aufruf sofort mit einem minimalen 403-Header, ohne Festplatten- oder CPU-Last zu erzeugen).