Seit August 2014 werkeln die Mitglieder von IETF und andere Beteiligte an der kommenden TLS Version 1.3. Nach einiger Verzögerung durch die überaschend negativen Feldtestergebnisse, welche durch Middleboxen verursacht wurden, ist nun der aktuelle Draft eingereicht.

Es wird wohl noch einige Tage dauern bis der Draft (aktuell 23) akzeptiert wird, sich aber technisch nicht mehr ändern.
Diverse Browser und Opensource Projekte warten nicht auf die IEFT und haben bisher den Draft 18 des kommenden Standards schon implementiert, unter anderem um die Feldtests zu ermöglichen. Ich möchte nun mein Webserver aktualisieren, um TLSv1.3 jetzt schon anzubieten.

Update:
NSS 3.35 enthält die TLSv1.3 Draft 23, welche Firefox mit Version 59 nutzen wird (siehe NSS 3.35 Release Notes, Mozilla Bug #1420060 - Upgrade Firefox 59 to NSS 3.35). Firefox 59 wird am 13.03.2018 released.

Da der Standard noch nicht verabschiedet wurde und dies ein grösseres Update des TLS Protokoll ist, kann ich annehmen, dass dieses Update nicht so schnell für meinen Server, welcher mit Centos 7 läuft, zur Verfügung stehen wird. Trotzdem möchte ich das Protokoll gerne in meinem Nginx Webserver einsetzen. Am besten auch so, dass einfach neue Versionen eingespielt werden können.

Dazu nutze ich die Fedora COPR Infrastruktur, wo man eigene Paketrepositories hosten kann. So kann ich meine Nginx Updates selbständig paketieren und diese Paket-Quellen für meine Server nutzen.

Voraussetzungen

Die Voraussetzungen um TLSv1.3 im nginx anzubieten sind folgende:

  • nginx 1.13
  • openssl 1.1.1

Centos 7.4 verwendet die OpenSSL Version 1.0.2k, daher kann der Nginx nicht OpenSSL des OS verwenden.

Die kommende OpenSSL Version, welche zu diesem Zeitpunkt noch nicht released ist, wird TLSv1.3 unterstützen (siehe den Blogpost von OpenSSL). Um sie jetzt schon nutzen zu können, verwende ich den tls1.3-draft18 Branch von Github. Diesen Draft 18 ist bei Firefox und Chrome schon implementiert. Sobald die grösseren Browserhersteller den finalen Standard implementiert und ausgerollt haben, kann ich die 1.1.1-pre Versionen von OpenSSL oder später die finale Version 1.1.1 für nginx verwenden.

Nginx kompilieren

Da nun eine neuere Version von OpenSSL benötigt wird, muss der Nginx und OpenSSL selbst kompiliert und statisch mit der SSL-Library gelinkt werden. Ich nutze die Standardoptionen, wie sie für die offiziellen Nginx RPM's verwendet wurde. Da ich schlussendlich selbst Pakete baue, verwende ich das neuste bestehende SRPM von Nginx und passe es an.

# yum -y groupinstall 'Development Tools'
# wget https://nginx.org/download/nginx-1.13.8.tar.gz
# tar xvfz nginx-1.13.8.tar.gz
# cd nginx-1.13.8
# git clone https://github.com/openssl/openssl.git
# cd openssl
# git checkout tls1.3-draft-18
# cd ..

Wichtige 2 Optionen um TLSv1.3 zu aktivieren: --with-openssl=openssl --with-openssl-opt=enable-tls1_3

  • --with-openssl=openssl bestimmt das Verzeichnis, indem sich die OpenSSL Sourcen befinden.
  • --with-openssl-opt=enable-tls1_3 aktiviert tls 1.3
# ./configure --prefix=/etc/nginx
--sbin-path=/usr/sbin/nginx
--modules-path=/usr/lib64/nginx/modules
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock
--http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user=nginx
--group=nginx
--with-compat 
--with-file-aio
--with-threads
--with-http_addition_module
--with-http_auth_request_module
--with-http_dav_module
--with-http_flv_module
--with-http_gunzip_module
--with-http_gzip_static_module
--with-http_mp4_module
--with-http_random_index_module
--with-http_realip_module
--with-http_secure_link_module
--with-http_slice_module
--with-http_ssl_module
--with-http_stub_status_module
--with-http_sub_module
--with-http_v2_module
--with-mail
--with-mail_ssl_module
--with-stream 
--with-stream_realip_module
--with-stream_ssl_module
--with-stream_ssl_preread_module
--with-openssl=openssl
--with-openssl-opt=enable-tls1_3 
# make -j2
# ./objs/nginx -V
nginx version: nginx/1.13.8
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) 
built with OpenSSL 1.1.1-dev  xx XXX xxxx
TLS SNI support enabled

Nginx paketieren

Für die automatische paketierung mit COPR von Fedora nutze ich Pagure.io ein Gitrepo von Fedora, welches sich mit dem COPR verknüpfen lässt. So löst jeder Git-Push einen COPR Build aus.
Die oben genannten Änderungen, plus ein paar Anpassungen, wie z.B. das Brotli-Kompressionsmodul von Google habe ich ins SPEC-File übernommen und das Nginx RPM damit erstellt.

Diese Paketversionen sind experimentell
Das Paket ist momentan mit OpenSSL 1.1.1pre6 gebaut.
https://copr.fedorainfracloud.org/coprs/bpereto/nginx-latest

Hier ist das SPEC-File: https://pagure.io/nginx-latest/blob/master/f/nginx.spec

Nginx update

Nun aktualisiere ich meinen Webserver. Dazu binde ich das COPR Repository in YUM ein und installiere meine Version von Nginx.

# yum install yum-plugin-copr
# yum copr enable bpereto/nginx-latest 
# yum update nginx
# systemctl restart nginx

Nginx Konfiguration

Mit TLS 1.3 sind nur noch AEAD Cipher zugelassen, die bestehenden werden nicht für diese Protokollversion genutzt. Daher müssen die neuen Cipher in der Nginx-Konfiguration spezifiziert werden, falls nginx (wie ich das konfiguriert habe) nicht die Default Cipher verwendet.

Da sind nur 2 kleine Änderungen in der Nginx Konfiguration um TLS1.3 zu aktivieren:

  • Das neue Protokoll TLSv1.3
  • Die neuen Ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256 müssen bei den Nginx SSL Optionen ergänzt werden.
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

Brotli

Brotli ist kein neues, hippes Gebäck mit fehlendem Umlaut, sondern ein Kompressionsalgorithmus. Der in den Zürcher Büros von Google entwickelte Algorithmus produziert bei vergleichbaren Komprimierungsgeschwindigkeiten kleinere Dateien, als das für Websites gern genutzte Format gzip. von Cyon-Blog

Das Brotli Modul für nginx ist nicht per default dabei, daher füge ich das meinem Paket noch hinzu.

Ich lade die Source herunter und aktiviere das Modul mit dem Konfigparameter --add-module=ngx_brotli.

git clone https://github.com/google/ngx_brotli                                  
cd ngx_brotli && git submodule update --init 

./configure {options} --add-module=ngx_brotli

Dies ist auch in meinem RPM vorhanden.

Nun kann ich Brotli in meiner Nginx Konfiguration aktivieren: /etc/nginx/nginx.conf

brotli on;
brotli_static on;
brotli_buffers 16 8k;
brotli_comp_level 6;
brotli_types *;
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# systemctl restart nginx

TLSv1.3 Test

Du kannst deine Seite mit SSL Labs testen. Sie sollte nun TLS 1.3 draft 18 supporten:

ssllabs_sandchaschte_tls13

Um dies in Firefox auszutesten, muss die Option security.tls.version.max in about:config auf 4 gesetzt werden.
Danach sollte sich Firefox mit TLS v1.3 verbinden:

Firefox Verbindungsoptionen

Brotli Test

br in den Firefox Developer Logs zeigt uns an, dass der Brotli Algorithmus für die Kompression verwendet wurde.

Firefox Developer Logs

Next Post Previous Post

Kommentar hinzufügen