Ich habe heute Abend mit meiner Tochter mal einen Apache Web Server auf einem RaspberryPi aufgesetzt und die default Konfiguration so erweitert, dass wir beim testen mit dem Qualys SSLLabs Onlinetool eine A+ Bewertung bekommen haben. Ich hab mir gedacht ich schreib das mal auf.
Da der Server an einer DSL Leitung mit Dynamischer IP Adresse betrieben wird, verwenden wir einen DynDNS dienst der unserem Hostnamen immer die Aktuelle IP Adresse zuweist, beispielsweise NOIP. Auf die Einrichtung soll hier aber nicht weiter eingegangen werden.
Hier die Schritte:
Apache2 (Webserver) installieren
Installieren der Apache Webservers und aktivieren der erforderlichen Module
sudo apt-get install apache2 sudo a2enmod ssl headers
Erzeugen eines private keys und csr (Certificate Signing Request)
Erzeugen eines privaten Schlüssels und des Certificate Signing Requests
openssl req -out yourname.csr -new -newkey rsa:2048 -nodes -keyout yourname.key
Es wird nun der Private Schlüssel generiert und dann ein zu vergebenes Passwort abgefragt (Das Passwortfeld kann auch leer gelassen werden, da ansonsten jedes mal beim Starten des Apache’s das Passwort benötigt werden würde).
(Dieses wird zur Entschlüsslung des Privaten Schlüssels benötigt und zur Beantragung und Erneuerung der Zertifikate bei einer Certificate Authority. Dieses sollte also auf keinen Fall verloren gehen.)
Generating a 2048 bit RSA private key .................................................................................................+++ ....+++ writing new private key to 'yourname.key' Enter PEM pass phrase:
Es werden nun einige Daten, wie der Country Code u.s.w. abgefragt. Wichtig hier bei ist das „Common Name“ mit dem FQDN des Servers befüllt wird. Aus diesen wird der Certificate Signing Request erzeugt.
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:DE State or Province Name (full name) [Some-State]:Bundesland Locality Name (eg, city) []:Ein Ort Organization Name (eg, company) [Internet Widgits Pty Ltd]:Eine Organisation Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:your.fqdn.tld Email Address []:webmaster@your.fqdn.tld Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Es sind nun zwei Dateien erzeugt worden: yourname.key, dieser enthält den verschlüsselten Privaten Schlüssel und yourname.csr, dies ist der signing Request.
Erzeugen eines private keys und csr (Certificate Signing Request) in einem Rutscht
Wenn ihr den obigen Schritt bereits erledigt habt, könnt Ihr diesen Schritt überspringen!
Man kann den Private-Key, sowie den die CSR-File auch in einem Kommando abfrühstücken und dort auch gleich alle weiteren Angaben unterbringen. (Hierbei wird bei der Erstellung kein Passwort für den private Key abgefragt)
Ein Beispiel dafür würde so aussehen:
openssl genrsa -out yourname.key 2048 && openssl req -new -key yourname.key -sha512 -nodes -subj '/C=DE/ST=Bundesland/L=Stadt/O=Organisation/OU=Webserver/CN=www.example.com/emailAddress=mail@example.com/subjectAltName=DNS.1=example.com' > yourname.csr
Das Resultat ist das selbige, wie oben, nur das hierbei keinerlei Einzelabfragen nötig sind, sondern man den Key inkl. CSR in einem Rutsch erzeugt.
Die entsprechenden Infos müssen hierbei natürlich in dem Befehl angepasst werden bevor man diesen einfach abschickt.
Zusätzlich haben wir in diesem Befehl noch einen zweiten DNS-Namen für die entsprechende CSR hinterlegt, sollte die CA nicht automatisch auch das Cert für www bzw. non-www der Webseite ausliefern.
Bitlänge des Private-Key ändern
Die Bitlänge für den Private-Key lässt sich einfach ändern in dem ihr anstelle von 2048 eine andere Bitlänge in die Befehle einsetzt.
Als Ausgangspunkt ist hier immer gut 1024 * ENTSPRECHENDER WERT (bspw. 4 -> ergo 4094bit) zu nehmen.
Hierdurch verlängert sich zwar der Rechenaufwand sowohl beim Erstellen des Keys (vorallem dann) als auch dann später in der eigentlich Kommunikation, aber die Verschlüsselung ist entsprechend schwerer zu entschlüsseln.
In unserem Fallbeispiel mit einem Raspi 2 genügt allerdings eine Länge von 2048bit.
Auf stärkeren Servern würde sich eine Länge von 4096bit empfehlen, wodurch die Verschlüsselung noch stärker wird, da hierdurch deutlich mehr Primzahlen zu errechnen sind.
.csr-Datei kontrollieren
Die .csr Datei für die Erstellung des Certs kann bevor man Sie bei einer CA einreicht nochmal mittels folgendem Befehl auf der Kommandozeile kontrollieren:
openssl req -text -noout -verify -in yourname.csr
.csr bei einer CA einreichen
Diese .csr Datei wird dann bei einer Certificate Authority eingereicht. Wir haben die kostenlose CA StartSSL verwendet.
Nach der Zuteilung des Zertifikates erhalten wir zwei Dateien. Eine mit dem Root Zertifikat der Certificate Authority „ca.crt“ und eine weitere mit dem Webserver Zertifikat für unsere Domain „yourname.crt“.
Zertifikat von der CA überprüfen
Mit folgendem Befehl könnt ihr das ausgestellt Zertifikat für eure Webseite auch nochmal überprüfen:
openssl x509 -in yourname.crt -text -noout
Hierbei ist vorallem wichtig das der unter Subject CN die richtige Domain bzw. FQDN steht und ebenfalls der Signature Algorithm mindestens SHA2 ist.
SHA1 wird nämlich in den meistens Browsern in zwischen für unzureichend erklärt, was zur Folge hat, das eure Besucher eine Warnmeldung erhalten.
Private-Key wieder entschlüsseln
Dieser Schritt ist nur nötig, sofern ihr dem Private-Key ein Passwort gegeben habt.
Bevor die Zertifikate in die Konfigurationsdateien des Webservers eingebunden werden, muss der Privatekey entschlüsselt werden.
Da ansonsten jedes mal beim starten, es nötig wäre das Passwort des Private-Keys einzugeben.
openssl rsa -in yourname.key.enc -out yourname.key
Es wird das Passwort verlangt, das bei der Erzeugung des privaten Schlüssels vergeben wurde.
Zertifikat, Private-Key und CRT-File in den Apache2 einbinden
Die drei Dateien legen wir nun im Konfigverzeichnis des Apache Webservers ab.
sudo mkdir /etc/apache2/certs sudo mkdir /etc/apache2/private sudo cp yourname.crt /etc/apache2/certs sudo cp yourname.key /etc/apache2/private sudo cp ca.crt /etc/apache2/certs
Jetzt zur Konfiguration des Webservers.
Wir erstellen in /etc/apache2/sites-available/ eine Datei mit folgendem Inhalt.
(bspw. mittels nano /etc/apache2/sites-available/example.com oder vim /etc/apache2/sites-available/example.com)
<IfModule mod_ssl.c> <VirtualHost *:443> Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;" ServerName yourdomain ServerAlias yourdomain ServerAdmin mailaddress DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateChainFile /etc/apache2/certs/ca.crt SSLCertificateFile /etc/apache2/certs/yourname.crt SSLCertificateKeyFile /etc/apache2/private/yourname.key SSLCompression off SSLInsecureRenegotiation off SSLProtocol +TLSv1.2 SSLHonorCipherOrder on SSLCipherSuite AES256+EECDH:AES256+EDH <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # MSIE 7 and newer should be able to use keepalive BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown </VirtualHost> </IfModule>
Apache2 vhost aktivieren
Hiernach ist es noch nötig die entsprechende vhost-Datei zu aktivieren, dies geschieht mit folgendem Befehl:
a2ensite /etc/apache2/sites-available/example.com
Und danach den Apache einmal „neustarten“:
service apache2 reload
Apache2 Details
Die relevanten Zeilen hier noch mal im Einzelnen:
Aktivieren der Http Strict Transport Policy (HSTS) mit langer Lebensdauer
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
XFO (X-Frame-Options) Header auf SAMEORIGIN oder DENY Setzen
Header always set X-Frame-Options SAMEORIGIN oder Header always set X-Frame-Options DENY
X-Content-Type-Options Header set auf „nosniff“
Header always set X-Content-Type-Options nosniff
Cross Site Scripting Protection aktivieren
Header always set X-XSS-Protection: "1; mode=block"
Content Security Policy Header auf „default-src ’self'“ setzen
Header set Content-Security-Policy "default-src 'self'"
Header set X-Webkit-CSP "default-src 'self'"
Aktiviern der SSL Engine
SSLEngine on
Einbinden der erstellten SSL Zertifikate
SSLCertificateChainFile /etc/apache2/certs/ca.crt SSLCertificateFile /etc/apache2/certs/yourname.crt SSLCertificateKeyFile /etc/apache2/private/yourname.key
Deaktivieren der SSL Kompression und unsicherer SSL Aushandlungsverfahren
SSLCompression off SSLInsecureRenegotiation off
Deaktivieren aller veralteten SSL und TLS Versionen, wir wollen nur TLSv1.2 unterstützen.
SSLProtocol +TLSv1.2
Deaktivieren aller Cipher Suites außer Elliptic Curve Diffie Hellman Keyexchange mit AES256 Verschlüsselung. Damit wird Perfect Forward Secrecy (PFS) unterstützt und erzwungen.
SSLHonorCipherOrder on SSLCipherSuite AES256+EECDH
SSLCheck
Das war`s auch schon. Ein Testlauf mit den SSLCheck Tools von SSLLabs.com sieht dann wie folgt aus:
Juhuuuu