Améliorer les performances de NGINX avec Kernel TLS et SSL_sendfile( )

NGINX | 11 novembre 2021

Transport Layer Security (TLS) est un protocole cryptographique extrêmement répandu. L’implémentation de TLS dans le noyau (kTLS) améliore les performances en réduisant considérablement les opérations de copie entre l’espace utilisateur et le noyau.

La combinaison de kTLS et de sendfile() permet de chiffrer les données directement dans l’espace noyau avant de les transmettre à la pile réseau. Il n’est ainsi plus nécessaire de copier les données dans l’espace utilisateur pour qu’elles soient chiffrées par les bibliothèques TLS, puis de les recopier dans l’espace noyau pour leur transmission. kTLS permet également de déléguer le traitement TLS au matériel, notamment de déléguer aux périphériques réseau le traitement cryptographique symétrique de TLS.

Les noyaux Linux et FreeBSD modernes permettent de décharger le traitement TLS vers le noyau, et désormais NGINX Open Source le permet également ! NGINX 1.21.4 introduit la prise en charge de kTLS lors de la diffusion de fichiers statiques et de réponses mises en cache avec SSL_sendfile(), ce qui peut considérablement améliorer les performances. Comme expliqué ci-dessous, le noyau et OpenSSL doivent tous deux avoir été compilés avec la prise en charge de kTLS pour que NGINX puisse utiliser SSL_sendfile().

Dans cet article, nous détaillons les versions des systèmes d’exploitation et d’OpenSSL qui prennent en charge kTLS, et expliquons comment compiler et configurer le noyau et NGINX pour utiliser kTLS. Pour vous donner une idée des gains de performances que vous pouvez attendre de kTLS, nous présentons également les caractéristiques techniques et les résultats de nos tests sur FreeBSD et Ubuntu.

Remarque : les implémentations de kTLS sont relativement récentes et évoluent rapidement. Cet article décrit la prise en charge de kTLS en novembre 2021, mais restez à l’affût des annonces publiées sur nginx.org et sur le blog de NGINX<.htmla> concernant les modifications apportées aux informations et aux instructions fournies ici.

Exigences générales

  • Système d’exploitation – Au choix parmi :
    • FreeBSD 13.0+. Depuis novembre 2021, FreeBSD 13.0+ est le seul système d’exploitation prenant en charge kTLS dans NGINX sans compilation manuelle de NGINX pour y intégrer OpenSSL 3.0.0+. Consultez la section « Activation de kTLS dans NGINX sous FreeBSD ».
    • Une distribution Linux basée sur la version 4.17 ou ultérieure du noyau Linux, bien que nous recommandions, dans la mesure du possible, d’utiliser une distribution basée sur la version 5.2 ou ultérieure. (La prise en charge de kTLS est en fait disponible à partir de la version 4.13, mais OpenSSL 3.0.0 nécessite la version 4.17 ou ultérieure des en-têtes du noyau.)
  • OpenSSL – Version 3.0.0 ou ultérieure
  • NGINX – Version 1.21.4 ou ultérieure (branche principale)[Éditeur – NGINX Plus R27 et les versions ultérieures prennent en charge kTLS sur les versions compatibles des systèmes d’exploitation Linux ; NGINX Plus R26 et les versions ultérieures le prennent en charge sur les versions compatibles de FreeBSD. Pour plus d’informations sur les systèmes d’exploitation pris en charge, consultez la page Versions de NGINX Plus.]

Prise en charge des systèmes d’exploitation

Systèmes d’exploitation prenant en charge kTLS

En novembre 2021, parmi les systèmes d’exploitation pris en charge par NGINX Open Source, les suivants prennent en charge kTLS et les suites de chiffrement indiquées. Pour plus d’informations sur la prise en charge des suites de chiffrement, consultez Prise en charge des protocoles TLS et des suites de chiffrement.

 Chiffrements TLSv1.2Suites de chiffrement
TLSv1.3
Chiffrement TLS_CHACHA20_POLY1305_SHA256Version du noyau Linux
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

* La version du noyau doit être la 5.10, et non la 4.14 ; consultez Systèmes d’exploitation ne prenant pas en charge kTLS ainsi que la FAQ d’Amazon Linux 2
** Hérite de l’état de prise en charge de kTLS de RHEL 8, dont il est dérivé
*** Consultez le journal des commits de FreeBSD

Systèmes d’exploitation ne prenant pas en charge kTLS

Les systèmes d’exploitation suivants ne prennent pas en charge kTLS, pour la raison indiquée :

  • Alpine Linux 3.11–3.14 – Le noyau est compilé avec l’option CONFIG_TLS=n, ce qui empêche la compilation de kTLS en tant que module ou partie intégrante du noyau.
  • Amazon Linux 2 – La version du noyau Linux est la 4.14 pour l’AMI Amazon Linux 2 par défaut (voir la FAQ d’Amazon Linux 2).
  • CentOS 7.4+ – La version du noyau Linux est la 3.10. Le statut de la prise en charge de kTLS est hérité de RHEL 7.4+, sa source en amont.
  • Debian 10 et 11 – Le noyau est compilé avec l’option CONFIG_TLS=n (voir les journaux du rapport de bogue Debian).
  • RHEL 7.4+ – La version du noyau Linux est 3.10.
  • SLES 12 SP5+ – la version du noyau Linux est 4.12.
  • Ubuntu 18.04 LTS – la version du noyau Linux est 4.15.

Prise en charge des protocoles et des suites de chiffrement TLS

Comme indiqué ci-dessus, les systèmes d’exploitation prenant en charge kTLS ne prennent pas tous en charge les mêmes protocoles TLS et suites de chiffrement.

Avec TLSv1.2, le module kTLS prend en charge les suites de chiffrement suivantes :

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

Avec TLSv1.3, le module kTLS prend en charge les suites de chiffrement suivantes :

Pour vérifier quels algorithmes de chiffrement TLS pris en charge par OpenSSL sont activés dans votre binaire NGINX, exécutez la commande openssl-3.0.0/.openssl/bin/openssl ciphers dans le répertoire où vous avez compilé NGINX (par exemple, votre répertoire personnel).

Activation de kTLS dans NGINX

Comme indiqué dans l’introduction, kTLS améliore les performances de NGINX, car toutes les opérations de chiffrement et de déchiffrement s’effectuent dans le noyau. Les données sont chiffrées directement dans l’espace noyau – avant d’être transmises à la pile réseau en vue de leur envoi –, ce qui évite de devoir les copier dans l’espace utilisateur pour qu’elles soient chiffrées par les bibliothèques TLS, puis de les recopier dans l’espace noyau pour leur transmission.

Schéma de TLS dans le noyau (kTLS) avec NGINX

Chargement de kTLS dans le noyau

Dans les distributions FreeBSD et Linux modernes, kTLS est généralement compilé sous forme de module (avec l’option « CONFIG_TLS=m »). Vous devez charger explicitement le module kTLS dans le noyau avant de démarrer NGINX.

  • Sous FreeBSD, exécutez ces commandes en tant qu’utilisateur root :
# kldload ktls_ocf.ko# sysctl kern.ipc.tls.enable=1
  • Pour plus d’informations sur les options de commande de FreeBSD, consultez la page de manuel de ktls(4).
  • Sur les distributions Linux, exécutez cette commande en tant qu’utilisateur root :
# modprobe tls

Activation de NGINX avec kTLS sous FreeBSD

Pour activer la prise en charge de kTLS dans NGINX sous FreeBSD, vous pouvez suivre les mêmes instructions que pour les distributions Linux. Toutefois, nous vous recommandons de suivre les étapes ci-dessous afin d’utiliser la version de NGINX avec kTLS fournie par le port security/openssl-devel de la collection de ports FreeBSD. Pour plus d’informations, notamment une présentation de kTLS, consultez la page Déchargement de TLS dans le noyau sur le site web de FreeBSD.

  1. Compilez OpenSSL 3.0 avec la prise en charge de kTLS en sélectionnant les options appropriées dans le menu de configuration :
# cd /usr/ports/security/openssl-devel && make config && make install
  1. Modifiez /etc/make.conf afin d’utiliser openssl-devel comme bibliothèque SSL par défaut :
# echo "DEFAULT_VERSIONS+=ssl=openssl-devel" >> /etc/make.conf
  1. Compilez NGINX :
# cd /usr/ports/www/nginx-devel && make install

Compiler NGINX avec kTLS sur les distributions Linux

La plupart des distributions Linux actuelles incluent une version d’OpenSSL antérieure à la version 3.0.0 (généralement la version 1.1). Vous devez donc compiler NGINX à partir du code source avec OpenSSL 3.0.0.

Les deux options essentielles de la commande « configure » qui permettent d’activer la prise en charge de kTLS sont les suivantes :

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

Les autres options de configure concernent les modules inclus dans les paquets binaires NGINX officiels disponibles sur nginx.org. Vous pouvez également spécifier un ensemble personnalisé de modules. Pour afficher les options de compilation utilisées pour votre binaire NGINX actuel, exécutez nginx -V.

Pour compiler NGINX avec OpenSSL 3.0.0, exécutez les commandes suivantes :

$ 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 --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-3.0.0 --with-openssl-opt=enable-ktls --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' -with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'$ make –j4$ make install

Remarque : Le binaire NGINX obtenu est lié statiquement aux bibliothèques OpenSSL 3.0.0. Si vous devez ultérieurement appliquer un correctif à OpenSSL, vous devrez télécharger et décompresser la nouvelle archive du code source d’OpenSSL, puis exécuter les commandes ci-dessus pour recompiler le binaire NGINX.

Configuration de NGINX

Pour activer kTLS, ajoutez la directive ssl_conf_command avec le paramètre Options KTLS dans le contexte server{} comme dans cet exemple de configuration utilisé pour nos tests :

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 Options KTLS;        ssl_protocols TLSv1.3;        location / {            root /data;    	}    }}

Vérification de l’activation de kTLS

Pour vérifier que NGINX utilise kTLS, activez le mode de débogage et recherchez BIO_get_ktls_send() et SSL_sendfile() dans le journal des erreurs.

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

Remarque : Nous vous recommandons de désactiver le mode de débogage après avoir effectué ces vérifications, en particulier dans les environnements de production. La journalisation du débogage entraîne une baisse des performances en raison du volume important d’opérations d’écriture. De plus, les journaux de débogage peuvent être très volumineux et rapidement saturer l’espace disponible sur la partition du disque.

Amélioration des performances avec kTLS

Lors de la diffusion de fichiers statiques et de réponses mises en cache sous forte charge, SSL_sendfile() peut multiplier le débit par deux par rapport à une implémentation TLS en espace utilisateur, mais l’ampleur du gain de performances dépend fortement de divers facteurs (performances du disque, charge du système, etc.). Il est également possible de réduire l’utilisation du processeur si votre carte réseau prend en charge le déchargement TLS.

Tester les performances

Pour mesurer le gain de performances sur votre configuration, suivez les instructions ci-dessous afin d’effectuer un test simple sur un seul thread. Comme indiqué ci-après, les résultats de nos tests montrent un gain de performances pouvant atteindre près de 30 %, sans aucun réglage particulier.

Matériel et logiciels utilisés :

  • Instance AWS t3.medium avec :
    • 4 Go de RAM
    • SSD polyvalent de 20 Go
    • Processeur Intel® Xeon® Platinum 8259CL à 2,50 GHz avec 2 cœurs
  • FreeBSD 13.0 et Ubuntu 21.10
  • TLSv1.3 avec la suite de chiffrement « TLS_AES_256_GCM_SHA384 »
  • NGINX 1.21.4, compilé et configuré comme indiqué dans « Activation de kTLS dans NGINX ».

Pour effectuer le test :

  1. Créez un fichier volumineux qui tient entièrement dans le cache disque :
# truncate -s 1g /data/1G
  1. Exécutez cette commande pour vérifier le débit ; la commande de base est répétée plusieurs fois afin d’obtenir des résultats plus précis. Redirigez la sortie vers l’utilitaire ministat[FreeBSD][Ubuntu] pour effectuer une analyse statistique élémentaire.
# for i in 'seq 1 100'; do curl -k -s -o /dev/null -w '%{speed_download}n' https://localhost/1G | ministat

Résultats des tests de performance

Dans les résultats de nos tests ci-dessous, présentés sous forme de sortie de « ministat », chaque valeur correspond à la vitesse de téléchargement en ko/s. La sortie est répartie sur deux lignes pour en faciliter la lecture.

Débit sous FreeBSD 13.0 sans kTLS :

    N           Min           Max        Median     ...x  10        532225        573348        555616     ...     ...      Avg        Stddev     ... 555155.6     10239.137

Débit pour FreeBSD 13.0 avec kTLS :

    N           Min           Max        Median     ...x  10        629379        723164        717349     ...         ...      Avg        Stddev   ... 708600.4     28304.766

Débit sous Ubuntu 21.10 sans kTLS :

    N           Min           Max        Median     ...x  10        529199        705720        662354     ...         ...      Avg        Stddev   ... 654321.6     48025.103

Débit sous Ubuntu 21.10 avec kTLS :

    N           Min           Max        Median     ...x  10        619105        760208        756278     ...         ...      Avg        Stddev   ... 741848.3     43255.246

Lors de nos tests, kTLS a davantage amélioré les performances avec FreeBSD qu’avec Ubuntu. Le gain de performances en pourcentage était le suivant :

 Min.Max.MédianeMoyenne
FreeBSD 13.018 %26 %29 %28 %
Ubuntu 21.1016 %8 %14 %13 %

Résumé

NGINX 1.21.4 prend désormais en charge kTLS lors de la diffusion de fichiers statiques et de réponses mises en cache avec SSL_sendfile(). Nos tests montrent que les performances s’améliorent de 8 % à 29 %, selon le système d’exploitation.

Nous aimerions connaître votre expérience avec kTLS et NGINX, et tout particulièrement les résultats de vos tests sur d’autres systèmes d’exploitation ! N’hésitez pas à les partager dans la section des commentaires ci-dessous.


Partager
Mots-clés : F5 NGINX, 2021, News, Tech

Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
NGINX | 13/10/2025

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA

Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
NGINX | 03/11/2023

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?

Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
NGINX | 11/03/2020

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX

Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
NGINX | 11/06/2019

Un testeur d’expressions régulières pour NGINX et NGINX Plus

Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.

Caches partagés avec les clusters de cache NGINX Plus, partie 1
NGINX | 24/01/2017

Caches partagés avec les clusters de cache NGINX Plus, partie 1

Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.

Introduction aux microservices
NGINX | 19/05/2015

Introduction aux microservices

Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.