ScusiBlog

background emmission of scusi

Apr 9, 2014 - 4 minute read - SSL TLS nginx config

nginx tls config

Wegen des Heartbleed Fehler ist gerade ein guter Zeitpunkt mal die eigene SSL config zu überarbeiten und auf den aktuellen Stand zu bringen. Daher werde ich in diesem Blogposting mal erklären wie - und was - ich da für scusiblog.org gemacht habe.

Die folgenden Anweisungen beziehen sich alle auf den webserver nginx.

HTTP Client-Anfragen auf HTTPS umleiten

## scusiblog.org http redirect server config ########################
#  if someone contacts us on port 80 we redirect to https
server  {
    listen scusiblog.org:80;
    #listen [::]:80;
    server_name         www.scusiblog.org scusiblog.org;
    return 301 https://$server_name$request_uri;
}
###############################################################################

Die obigen 10 Zeilen definieren einen Server auf Port 80 der alle eingehenden Anfragen dauerhaft (Return Code 301 - Moved Permanently) auf die gleichnamige HTTPS URL verweist.

Will man auch auf IPv6 Anfragen antworten muss man Zeile 5 einkommentieren (das #-Zeichen am anfang der Zeile löschen.

HTTPS Server konfigurieren

Der folgende Abschnitt konfiguriert einen HTTPS server. Will man IPv6 Anfragen beantworten muss man Zeile 3 einkommentiren. Die Zeile mit root legt das root-Verzeichnis fest, index legt die zu verwendenden Standard-Seiten fest. Der Abschnitt location sorgt dafür dass auch syntaktisch nicht korrekte - aber dennoch gern genutzte - URLs zu ihrem Ziel finden.

server {
    listen              scusiblog.org:443 ssl;
    #listen              [::]:443 ssl;
    server_name         www.scusiblog.org scusiblog.org;
    root /usr/share/nginx/www/scusiblog.org;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ /index.html;
    }

Schlüsselmaterial konfigurieren

Die nächsten zwei Zeilen sagen nginx wo SSL Zertifikat und dazugehöriger Key zu finden ist.

    ssl_certificate     /etc/ssl/private/scusiblog/scusiblog_chained.crt;
    ssl_certificate_key /etc/ssl/private/scusiblog/scusiblog.org.key;

Die Datei scusiblog_chained.crt ist das scusiblog Zertifikat (PEM encoded) mit daran anschließendem indermediate Zertifikat meiner CA. Diese Datei erstellt man so:

cat scusiblog.crt sub.intermediate.cert > scusiblog_chained.crt

Das ist oft nötig weil einige CAs zwar in den Stammzertifikaten der Browser enthalten sind aber aus verschiedenen Gründen nicht mit ihrem Stammzertifikat andere Zertifikate signieren. Es gibt noch eine Zwischenstelle, die sogenannte intermediate CA, deren Zertifikat ist vom Stammzertifikat unterschrieben, und signiert seinerseits Zertifikate von Kunden. Wenn man Kunde einer solchen CA ist, dann muss man dafür sorgen dass das Zertifikat der zwischen CA auch zum Browser des Besuchers geliefert wird. Andernfalls sucht der Browser das Zertifikat was viel Zeit (und unnötige Resourcen) beim Verbindungsaufbau kostet. Die einfache Lösung ist daher das Zertifikat der intermediate CA mit dem des eigenen Servers zusammen zu kleistern und gemeinsam dem Client zu schicken.

Protokolle und Verschlüsselungsverfahren

Als nächstes müssen noch die gewünschten Protokollversionen und die Verfahren zur Verschlüsselung konfiguriert werden. Das ist einer der eigentlich kritischen Teile.

    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-CBC-SHA;
    ssl_prefer_server_ciphers on;

Wir machen das in den obigen drei Zeilen. Zeile 1 legt fest welche Protokolle unser Server unterstützt. Die Reihenfolge ist auch Wichtig, sie gibt unsere Präferenz an. Je weiter links in der Zeile ein Protokoll steht desto lieber würden wir dieses nutzen. Wir wollen TLS1.2 nutzen, wenn es nicht anders geht nehmen akzeptieren wir auch TLS1.1 oder gar TLS1(.0). SSL sprechen wir gar nicht weil das signifikant kaputt ist.

Zeile 2 legt die sogenannten ciphers - also die Verschlüsselungsverfahren fest. Wie schon bei den Protokollen ist die Reihenfolge wichtig. Wir wollen ECDHE-RSA-AES256-GCM-SHA384sprechen wenn möglich. Bei diesem Verfahren sind die Schlüssel der Teilnehmer RSA Schlüssel, die Sitzungsschlüssel werden über das Deffie-Hellman Schlüsselaustauschverfahren (DHE) auf eliptischen Kurven (EC) basierend ausgetauscht. Der Transportstrom wird mit AES-128 geschützt und als absicherung gegen Manipulation wird der Galois/Counter Mode mit SHA384 verwendet. Das ist gerade State of the Art.

DH Parameter erzeugen und einstellen

Die DH Parameter werden für Verfahren die elliptische Kurven nutzen gebraucht und müssen erstmal - auf jedem System - neu generiert werden. Das macht man am besten mit dem folgenden openSSL Befehl. Das folgende Beispiel geht davon aus das ein 4096 bit Key für das System vorliegt.

$> openssl dhparam -outform PEM -out dhparam4096.pem 4096

Gegebenfalls muss die Datei jetzt an den richtigen Ort verschoben werden, z.B. nach /etc/ssl/private/scusiblog/.

In der nginx Konfiguration muss die erzeugte Datei dann noch eingetragen werden. Die folgende Zeile macht den Job:

    ssl_dhparam /etc/ssl/private/scusiblog/dhparam4096.pem;

Saubere Elliptische Kurven

Die folgende Zeile definiert die zu verwendenden Kurven.

    ssl_ecdh_curve secp384r1;

Strict-Transport-Security

Strict Transport Security ist ein HTTP-Header Flag welches dem Browser signalisiert dass diese Seite nur über HTTPS geladen werden soll. Der Parameter max-age gibt an wie lange in die Zukunft die Ansage - diese Seite nur über HTTPS zu laden - gelten soll. 31536000 Sekunden entspricht einem Jahr. Damit sorgen wir also dafür dass ein Browser ein Jahr lang nach seinem letzten Besuch scusiblog.org nur noch per HTTPS kontaktiert.

    add_header Strict-Transport-Security max-age=31536000;

Sinnvolle Zeitspannen sind etwa 12 oder 24 Monate, respektive 31536000 oder 63072000 Sekunden. Kürzere Zeitspannen, vor allem unter einem halben Jahr sind inakzeptabel.

Sitzungseinstellungen

Jetzt legen wir noch fest dass unser Session Cache zwischen den einzelnen Instanzen geteilt werden soll. Die Sitzungszeit - bis ein neuer Sitzungsschlüssel ausgetauscht werden muss - stellen wir auf 10 Minuten ein.

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

Klammern schließen nicht vergessen!

}

Zusammenfassung

Mit einer solchen Konfiguration hat man nach dem Stand heute eine gute und sichere SSL/TLS Konfiguration. Vom Qualys SSL Test gibt es dann - bis zur nächsten Schwachstelle - auch die Bestnote A+.

Die Bewertung von scusiblog.org steht unter https://www.ssllabs.com/ssltest/analyze.html?d=scusiblog.org