BLOG | NGINX

Verbessern der NGINX-Leistung mit Kernel-TLS und SSL_sendfile( )

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Mikhail Isachenkov Miniaturbild
Michail Isachenkow
Veröffentlicht am 11. November 2021

Transport Layer Security (TLS) ist ein äußerst beliebtes Kryptografieprotokoll. Durch die Implementierung von TLS im Kernel (kTLS) wird die Leistung verbessert, da weniger Kopiervorgänge zwischen Benutzerbereich und Kernel erforderlich sind.

Durch die Kombination von kTLS und sendfile() werden Daten direkt im Kernelspeicher verschlüsselt, bevor sie zur Übertragung an den Netzwerkstapel übergeben werden. Dadurch entfällt die Notwendigkeit, Daten in den Benutzerbereich zu kopieren, um sie mit TLS-Bibliotheken zu verschlüsseln, und sie dann zur Übertragung wieder in den Kernelbereich zurückzukopieren. kTLS ermöglicht außerdem die Auslagerung der TLS-Verarbeitung auf die Hardware, einschließlich der Auslagerung der symmetrischen TLS-Kryptoverarbeitung auf Netzwerkgeräte .

Moderne Linux- und FreeBSD-Kernel unterstützen das Auslagern von TLS auf den Kernel, und jetzt tut dies auch NGINX Open Source! NGINX 1.21.4 führt Unterstützung für kTLS beim Bereitstellen statischer Dateien und zwischengespeicherter Antworten mit SSL_sendfile() ein, was die Leistung enorm verbessern kann. Wie unten beschrieben, müssen sowohl der Kernel als auch OpenSSL mit kTLS erstellt werden, damit NGINX SSL_sendfile() verwenden kann.

In diesem Blog erläutern wir im Detail, welche Betriebssystem- und OpenSSL-Versionen kTLS unterstützen, und zeigen, wie der Kernel und NGINX für kTLS erstellt und konfiguriert werden. Um Ihnen eine Vorstellung von der Leistungsverbesserung zu geben, die Sie von kTLS erwarten können, teilen wir auch die Spezifikationen und Ergebnisse unserer Tests unter FreeBSD und Ubuntu.

Hinweis: kTLS-Implementierungen sind recht neu und entwickeln sich schnell. In diesem Blog wird die Unterstützung für kTLS ab November 2021 beschrieben. Achten Sie jedoch auf Ankündigungen auf nginx.org und im NGINX-Blog<.htmla> zu Änderungen der hier bereitgestellten Informationen und Anweisungen.

Allgemeine Anforderungen

  • Betriebssystem – Eines von:

    • FreeBSD 13.0+. Seit November 2021 ist FreeBSD 13.0+ das einzige Betriebssystem, das kTLS in NGINX unterstützt, ohne dass ein manueller Build von NGINX zur Integration von OpenSSL 3.0.0+ erforderlich ist. Siehe Aktivieren von NGINX mit kTLS unter FreeBSD .

    • Eine Linux-Distribution, die auf der Linux-Kernel-Version 4.17 oder höher basiert. Wir empfehlen jedoch, wenn möglich solche zu verwenden, die auf der Version 5.2 oder höher basieren. (kTLS-Unterstützung ist tatsächlich in Version 4.13 verfügbar, aber OpenSSL 3.0.0 erfordert die Kernel-Header-Version 4.17 oder höher.)

  • OpenSSL – Version 3.0.0 oder höher

  • NGINX – Version 1.21.4 oder höher (Hauptversion)

    [ HerausgeberNGINX Plus R27 und höher unterstützt kTLS auf berechtigten Linux-basierten Betriebssystemversionen; NGINX Plus R26 und höher unterstützt es auf berechtigten FreeBSD-Versionen. Einzelheiten zu den unterstützten Betriebssystemen finden Sie auf der Seite „NGINX Plus Releases “.]

Betriebssystemunterstützung

Betriebssysteme, die kTLS unterstützen

Ab November 2021 unterstützen die folgenden von NGINX Open Source unterstützten Betriebssysteme kTLS und die angegebenen Chiffren. Einzelheiten zur Verschlüsselungsunterstützung finden Sie unter TLS-Protokoll und Verschlüsselungsunterstützung .

  TLSv1.2-Chiffren TLSv1.3
Verschlüsselungssammlungen
TLS_CHACHA20_POLY1305_SHA256 -Verschlüsselung Linux-Kernel-Version
Amazon Linux 2 * 5.10
CentOS 8 ** 4.18
FreeBSD 13.x *** N / A
RHEL 8 4.18
SLES 15 SP2 5.3
Ubuntu 20.04 LTS ❌​​ 5.4
Ubuntu 21.04 5.11
Ubuntu 21.10 5.13

  * Die Kernel-Version muss 5.10 sein, nicht 4.14; siehe Betriebssysteme, die kTLS nicht unterstützen und die Amazon Linux 2-FAQ
** Erbt seinen kTLS-Supportstatus von RHEL 8 als Upstream-Quelle
*** Siehe das FreeBSD-Commit-Protokoll

Betriebssysteme, die kTLS nicht unterstützen

Die folgenden Betriebssysteme unterstützen kTLS aus dem angegebenen Grund nicht:

  • Alpine Linux 3.11–3.14 – Der Kernel wird mit der Option CONFIG_TLS=n erstellt, die den Aufbau von kTLS als Modul oder als Teil des Kernels deaktiviert.
  • Amazon Linux 2 – Die Linux-Kernelversion für das standardmäßige Amazon Linux 2-AMI ist 4.14 (siehe die FAQ zu Amazon Linux 2 ).
  • CentOS 7.4+ – Die Linux-Kernelversion ist 3.10. Erbt seinen kTLS-Supportstatus von RHEL 7.4+ als Upstreamquelle.
  • Debian 10 und 11 – Der Kernel wird mit der Option CONFIG_TLS=n erstellt (siehe die Protokolle der Debian-Fehlerberichte ).
  • RHEL 7.4+ – Linux-Kernel-Version ist3.10 .
  • SLES 12 SP5+ – Linux Kernel Version ist4.12 .
  • Ubuntu 18.04 LTS – Linux-Kernel-Version ist4.15 .

TLS-Protokoll und Verschlüsselungsunterstützung

Wie oben beschrieben, unterscheiden sich die Betriebssysteme, die kTLS unterstützen, in ihrer Unterstützung für TLS-Protokolle und -Chiffren.

Mit TLSv1.2 unterstützt das kTLS-Modul diese Chiffren:

  • AES128-GCM-SHA256
  • AES256-GCM-SHA384
  • ECDHE-RSA-AES128-GCM-SHA256
  • ECDHE-RSA-AES256-GCM-SHA384

Mit TLSv1.3 unterstützt das kTLS-Modul diese Verschlüsselungssammlungen:

Um zu überprüfen, welche von OpenSSL unterstützten TLS-Chiffren in Ihrer NGINX-Binärdatei aktiviert sind, führen Sie den Befehl openssl-3.0.0/.openssl/bin/openssl ciphers in dem Verzeichnis aus, in dem Sie NGINX erstellt haben (z. B. Ihrem Home-Verzeichnis).

Aktivieren von kTLS in NGINX

Wie in der Einleitung erwähnt, verbessert kTLS die Leistung von NGINX, da die gesamte Ver- und Entschlüsselung im Kernel stattfindet. Die Daten werden direkt im Kernelspeicher verschlüsselt – bevor sie zur Übertragung an den Netzwerkstapel übergeben werden. Dadurch ist es nicht mehr erforderlich, die Daten in den Benutzerspeicher zu kopieren, um sie mit TLS-Bibliotheken zu verschlüsseln, und sie dann zur Übertragung wieder in den Kernelspeicher zurückzukopieren.

Diagramm des Kernel-TLS (kTLS) mit NGINX

Laden von kTLS im Kernel

In modernen FreeBSD- und Linux-Distributionen wird kTLS normalerweise als Modul erstellt (mit der Option CONFIG_TLS=m ). Sie müssen das kTLS-Modul explizit in den Kernel laden, bevor Sie NGINX starten.

  • Führen Sie unter FreeBSD diese Befehle als Root -Benutzer aus:

    # kldload ktls_ocf.ko # sysctl kern.ipc.tls.enable=1
    

    Einzelheiten zu den FreeBSD-Befehlsoptionen finden Sie auf der Manpage für ktls(4) .

  • Führen Sie bei Linux-Distributionen diesen Befehl als Root -Benutzer aus:

    # modprobe tls
    

Aktivieren von NGINX mit kTLS unter FreeBSD

Um die kTLS-Unterstützung in NGINX unter FreeBSD zu aktivieren, können Sie dieselben Anweisungen wie für Linux-Distributionen verwenden. Wir empfehlen Ihnen jedoch, die folgenden Schritte auszuführen, um den Build von NGINX mit kTLS im Port „security/openssl-devel“ in der FreeBSD-Ports-Sammlung zu nutzen. Weitere Informationen, einschließlich einer Übersicht über kTLS, finden Sie unter TLS Offload im Kernel auf der FreeBSD-Website.

  1. Erstellen Sie OpenSSL 3.0 mit kTLS-Unterstützung und wählen Sie die entsprechenden Optionen im Konfigurationsmenü aus:

    # cd /usr/ports/security/openssl-devel und make config und make install
    
  2. Ändern Sie /etc/make.conf , um openssl-devel als Standard-SSL-Bibliothek zu verwenden:

    # echo "DEFAULT_VERSIONS+=ssl=openssl-devel" >> /etc/make.conf
    
  3. Erstellen Sie NGINX:

    # cd /usr/ports/www/nginx-devel und make install
    

Erstellen von NGINX mit kTLS auf Linux-Distributionen

Die meisten aktuellen Linux-Distributionen enthalten eine OpenSSL-Version vor 3.0.0 (normalerweise Version 1.1). Sie müssen NGINX also aus dem Quellcode mit OpenSSL 3.0.0 erstellen.

Die beiden entscheidenden Optionen im Konfigurationsbefehl , die die kTLS-Unterstützung aktivieren, sind:

  • --with-openssl=../openssl-3.0.0
  • --with-openssl-opt=enable-ktls

Die anderen Konfigurationsoptionen gelten für die Module, die in den offiziellen NGINX-Binärpaketen enthalten sind, die unter nginx.org verfügbar sind. Sie können stattdessen einen benutzerdefinierten Modulsatz angeben. Um die für Ihre aktuelle NGINX-Binärdatei verwendeten Build-Optionen anzuzeigen, führen Sie nginx -V aus.

Führen Sie die folgenden Befehle aus, um NGINX mit OpenSSL 3.0.0 zu erstellen:

$ wget https://nginx.org/download/nginx-1.21.4.tar.gz $ wget https://www.openssl.org/source/openssl-3.0.0.tar.gz $ tar xzf openssl-3.0.0.tar.gz $ cd nginx-1.21.4 $ ./configure \ --with-debug \ --prefix=/usr/local \ --conf-path=/usr/local/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 \ --mit-http_gunzip_modul \ --mit-http_gzip_static_modul \ --mit-http_mp4_modul \ --mit-http_random_index_modul \ --mit-http_realip_modul \ --mit-http_secure_link_modul \ --mit-http_slice_modul \ --mit-http_ssl_modul \ --mit-http_stub_status_modul \ --mit-http_sub_modul \ --mit-http_v2_modul \ --mit-mail \ --mit-mail_ssl_modul \ --mit-stream \ --mit-stream_realip_modul \ --mit-stream_ssl_modul \ --mit-stream_ssl_preread_modul \ --mit-openssl=../openssl-3.0.0 \ --with-openssl-opt=ktls aktivieren \ --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=Formatsicherheit -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \ -with-ld-opt='-Wl,-Bsymbolische Funktionen -Wl,-z,relro -Wl,-z,jetzt -Wl,--nach Bedarf -pie' $ make –j4 $ make install

Notiz: Die resultierende NGINX-Binärdatei ist statisch mit OpenSSL 3.0.0-Bibliotheken verknüpft. Wenn Sie OpenSSL später patchen müssen, müssen Sie das neue OpenSSL-Quellarchiv herunterladen und entpacken und dann die obigen Befehle ausführen, um die NGINX-Binärdatei neu zu erstellen.

Konfigurieren von NGINX

Um kTLS zu aktivieren, schließen Sie die Direktive ssl_conf_command mit dem Parameter Options KTLS in den Kontext server{} ein, wie in dieser Beispielkonfiguration, die für unsere Tests verwendet wurde:

worker_processes auto;error_log /var/log/nginx/error.log debug;

events {}

http {
sendfile on;

server {
listen 443 ssl;
ssl_certificate ssl/example.crt;
ssl_certificate_key ssl/example.key;
ssl_conf_command Optionen KTLS;
ssl_protocols TLSv1.3;

location / {
root /data;
}
}
}

Überprüfen, ob kTLS aktiviert ist

Um zu überprüfen, ob NGINX kTLS verwendet, aktivieren Sie den Debugmodus und suchen Sie im Fehlerprotokoll nach BIO_get_ktls_send() und SSL_sendfile() .

$ grep BIO /var/log/nginx/error.log 2021/11/10 16:02:46 [debug] 274550#274550: *2 BIO_get_ktls_send(): 1 10.11.2021 16:02:49 [debug] 274550#274550: *3 BIO_get_ktls_send(): 1 $ grep SSL_sendfile /var/log/nginx/error.log 2021/11/10 16:02:46 [debug] 274550#274550: *2 SSL_sendfile: 1048576 10.11.2021 16:02:49 [debug] 274550#274550: *3 SSL_sendfile: 1048576

Notiz: Wir empfehlen, den Debugmodus nach diesen Prüfungen zu deaktivieren, insbesondere in Produktionsumgebungen. Die Debug-Protokollierung führt aufgrund der großen Anzahl an Schreibvorgängen zu Leistungseinbußen. Außerdem können Debug-Protokolle sehr groß sein und den verfügbaren Speicherplatz auf der Festplattenpartition schnell erschöpfen.

Leistungsverbesserung mit kTLS

Beim Bereitstellen statischer Dateien und zwischengespeicherter Antworten unter hoher Last kann SSL_sendfile() den Durchsatz im Vergleich zu TLS im Benutzerbereich um bis zu das Zweifache steigern . Das Ausmaß der Leistungssteigerung hängt jedoch stark von verschiedenen Faktoren ab (Festplattenleistung, Systemlast usw.). Es ist auch möglich, die CPU-Auslastung zu reduzieren, wenn Ihre Netzwerkkarte TLS-Offload unterstützt.

Testen der Leistung

Um die Leistungssteigerung Ihres Setups zu messen, führen Sie anhand der folgenden Anweisungen einen einfachen Ein-Thread-Test durch. Wie unten ausführlich beschrieben, deuten unsere Testergebnisse auf eine Leistungssteigerung von bis zu fast 30 % ohne spezielle Feinabstimmung hin.

Verwendete Hard- und Software:

  • AWS t3.medium-Instanz mit:
    • 4 GB RAM
    • 20 GB Allzweck-SSD
    • Intel® Xeon® Platinum 8259CL CPU @ 2,50 GHz mit 2 Kernen
  • FreeBSD 13.0 und Ubuntu 21.10
  • TLSv1.3 mit der Verschlüsselungssammlung TLS_AES_256_GCM_SHA384
  • NGINX 1.21.4, erstellt und konfiguriert wie unter „Aktivieren von kTLS in NGINX“ angegeben.

So führen Sie den Test durch:

  1. Erstellen Sie eine große Datei, die vollständig in den Festplattencache passt:

    # abschneiden -s 1g /data/1G
    
  2. Führen Sie diesen Befehl aus, um den Durchsatz zu prüfen. Der Basisbefehl wird für genauere Ergebnisse mehrmals wiederholt. Leiten Sie die Ausgabe an das Dienstprogramm Ministat [ FreeBSD ] [ Ubuntu ] weiter, um eine grundlegende statistische Analyse durchzuführen.

     

    # für i in „seq 1 100“; führe curl -k -s -o /dev/null -w „%{speed_download}\n“ https://localhost/1G aus | ministat
    

Ergebnisse der Leistungstests

In den folgenden Ergebnissen unserer Tests, die als Ausgabe von ministat dargestellt werden, ist jeder Wert die Download-Geschwindigkeit in kByte/Sekunde. Die Ausgabe ist zur besseren Lesbarkeit auf zwei Zeilen aufgeteilt.

Durchsatz für FreeBSD 13.0 ohne kTLS:

    N Min Max Median ...x 10 532225 573348 555616 ... 

...      Durchschnittliche Standardabweichung 
... 555155.6 10239.137

Durchsatz für FreeBSD 13.0 mit kTLS:

    N Min Max Median ...x 10 629379 723164 717349 ... 

...      Durchschnittliche Standardabweichung
... 708600.4 28304.766

Durchsatz für Ubuntu 21.10 ohne kTLS:

    N Min Max Median ...x 10 529199 705720 662354 ... 

...      Durchschnittliche Standardabweichung
... 654321.6 48025.103

Durchsatz für Ubuntu 21.10 mit kTLS:

    N Min Max Median ...x 10 619105 760208 756278 ... 

...      Durchschnittliche Standardabweichung
... 741848.3 43255.246

Bei unseren Tests steigerte kTLS die Leistung unter FreeBSD stärker als unter Ubuntu. Die prozentuale Verbesserung war wie folgt:

  Mindest Max Mittlere Durchschnitt
FreeBSD 13.0 18 % 26 % 29 % 28 %
Ubuntu 21.10 16 % 8 % 14 % 13 %

Zusammenfassung

NGINX 1.21.4 führt Unterstützung für kTLS beim Bereitstellen statischer Dateien und zwischengespeicherter Antworten mit SSL_sendfile() ein. Unsere Tests zeigen, dass sich die Leistung je nach Betriebssystem um 8 bis 29 % verbessert.

Wir sind gespannt auf Ihre Erfahrungen mit kTLS und NGINX und insbesondere auf die Ergebnisse Ihrer Tests auf anderen Betriebssystemen. Bitte teilen Sie sie im Kommentarbereich unten.


„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."