BLOG | NGINX

Amélioration des performances de NGINX avec Kernel TLS et SSL_sendfile( )

NGINX-Partie-de-F5-horiz-black-type-RGB
Miniature de Mikhaïl Isachenkov
Mikhaïl Issachenkov
Publié le 11 novembre 2021

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

La combinaison de kTLS et sendfile() signifie que les données sont cryptées directement dans l'espace du noyau, avant d'être transmises à la pile réseau pour transmission. Cela élimine le besoin de copier les données dans l'espace utilisateur pour les crypter par les bibliothèques TLS, puis de les renvoyer dans l'espace noyau pour la transmission. kTLS permet également de décharger le traitement TLS vers le matériel, y compris le déchargement du traitement de cryptographie symétrique TLS vers les périphériques réseau .

Les noyaux Linux et FreeBSD modernes prennent en charge le déchargement de TLS vers le noyau, et désormais NGINX Open Source le fait é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 détaillé ci-dessous, le noyau et OpenSSL doivent être construits avec kTLS pour que NGINX puisse utiliser SSL_sendfile() .

Dans ce blog, nous détaillons quels systèmes d'exploitation et versions d'OpenSSL prennent en charge kTLS, et montrons comment créer et configurer le noyau et NGINX pour kTLS. Pour vous donner une idée de l'amélioration des performances que vous pouvez attendre de kTLS, nous partageons également les spécifications et les résultats de nos tests sur FreeBSD et Ubuntu.

Remarque : les implémentations kTLS sont assez nouvelles et évoluent rapidement. Ce blog décrit la prise en charge de kTLS à partir de novembre 2021, mais gardez un œil sur les annonces sur nginx.org et le blog NGINX<.htmla> concernant les modifications apportées aux informations et instructions fournies ici.

Exigences générales

  • Système d’exploitation – L’un des suivants :

    • FreeBSD 13.0+. Depuis novembre 2021, FreeBSD 13.0+ est le seul système d'exploitation qui prend en charge kTLS dans NGINX sans compilation manuelle de NGINX pour intégrer OpenSSL 3.0.0+. Voir Activation de NGINX avec kTLS sur FreeBSD .

    • Une distribution Linux construite sur le noyau Linux version 4.17 ou ultérieure, bien que nous vous recommandons d'utiliser celles construites sur la version 5.2 ou ultérieure lorsque cela est possible. (La prise en charge de kTLS est en fait disponible dans la version 4.13, mais OpenSSL 3.0.0 nécessite la version d'en-tête du noyau 4.17 ou ultérieure.)

  • OpenSSL – Version 3.0.0 ou ultérieure

  • NGINX – Version 1.21.4 ou ultérieure (ligne principale)

    [ ÉditeurNGINX Plus R27 et versions ultérieures prennent en charge kTLS sur les versions éligibles du système d'exploitation basé sur Linux ; NGINX Plus R26 et versions ultérieures le prennent en charge sur les versions éligibles de FreeBSD. Pour plus de détails sur les systèmes d'exploitation pris en charge, consultez la page des versions de NGINX Plus.]

Prise en charge du système d'exploitation

Systèmes d'exploitation prenant en charge kTLS

Depuis novembre 2021, parmi les systèmes d'exploitation pris en charge par NGINX Open Source , les suivants prennent en charge kTLS et les chiffrements indiqués. Pour plus de détails sur la prise en charge du chiffrement, voir Protocole TLS et prise en charge du chiffrement .

  Chiffres TLSv1.2 TLSv1.3
suites de chiffrement
Chiffrement TLS_CHACHA20_POLY1305_SHA256 Version 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 5.10 et non 4.14 ; voir les systèmes d'exploitation qui ne prennent pas en charge kTLS et la FAQ d'Amazon Linux 2
** Hérite son statut de support kTLS de RHEL 8 comme source en amont
*** Voir le journal de validation de FreeBSD

Systèmes d'exploitation qui ne prennent 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 construit avec l'option CONFIG_TLS=n , qui désactive la construction de kTLS en tant que module ou en tant que partie du noyau.
  • Amazon Linux 2 – La version du noyau Linux est 4.14 pour l’AMI Amazon Linux 2 par défaut (voir la FAQ Amazon Linux 2 ).
  • CentOS 7.4+ – La version du noyau Linux est 3.10. Hérite son statut de prise en charge kTLS de RHEL 7.4+ comme source en amont.
  • Debian 10 et 11 – Le noyau est construit avec l’option CONFIG_TLS=n (voir les journaux de rapport de bugs Debian ).
  • RHEL 7.4+ – La version du noyau Linux est3.10 .
  • SLES 12 SP5+ – La version du noyau Linux est4.12 .
  • Ubuntu 18.04 LTS – La version du noyau Linux est4.15 .

Prise en charge du protocole TLS et du chiffrement

Comme détaillé ci-dessus , les systèmes d’exploitation qui prennent en charge kTLS varient dans leur prise en charge des protocoles et des chiffrements TLS.

Avec TLSv1.2, le module kTLS prend en charge ces chiffrements :

  • 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 ces suites de chiffrement :

Pour vérifier quels chiffrements 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 créé NGINX (par exemple, votre répertoire personnel).

Activation de kTLS dans NGINX

Comme mentionné dans l'introduction, kTLS améliore les performances de NGINX car tout le chiffrement et le déchiffrement ont lieu dans le noyau. Les données sont chiffrées directement dans l'espace noyau, avant d'être transmises à la pile réseau pour transmission, ce qui élimine le besoin de copier les données dans l'espace utilisateur pour être chiffrées par les bibliothèques TLS, puis de les renvoyer dans l'espace noyau pour la transmission.

Diagramme du noyau TLS (kTLS) avec NGINX

Chargement de kTLS dans le noyau

Dans les distributions modernes FreeBSD et Linux, kTLS est généralement construit comme un 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 de détails sur les options de commande 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 sur FreeBSD

Pour activer la prise en charge de kTLS dans NGINX sur FreeBSD, vous pouvez utiliser les mêmes instructions que pour les distributions Linux. Cependant, nous vous recommandons d'effectuer les étapes suivantes pour tirer parti de la version de NGINX avec kTLS dans le port security/openssl-devel de la collection de ports FreeBSD . Pour plus d'informations, y compris un aperçu de kTLS, voir TLS Offload in the Kernel sur le site Web de FreeBSD.

  1. Créez OpenSSL 3.0 avec 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
    
  2. Modifiez /etc/make.conf pour utiliser openssl-devel comme bibliothèque SSL par défaut :

    # echo "VERSIONS_PAR_DEFAUT+=ssl=openssl-devel" >> /etc/make.conf
    
  3. Créer NGINX :

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

Création de NGINX avec kTLS sur les distributions Linux

La plupart des distributions Linux actuelles incluent une version OpenSSL antérieure à 3.0.0 (généralement, la version 1.1). Vous devez donc créer NGINX à partir de la source avec OpenSSL 3.0.0.

Les deux options cruciales de la commande configure qui activent la prise en charge de kTLS sont :

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

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

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

$ 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 \ --avec-module_realip_http \ --avec-module_lien_secure_http \ --avec-module_tranche_http \ --avec-module_ssl_http \ --avec-module_état_stub_http \ --avec-module_sous-http \ --avec-module_http_v2 \ --avec-mail \ --avec-module_ssl_mail \ --avec-stream \ --avec-module_realip_stream \ --avec-module_ssl_stream \ --avec-module_prélecture_ssl_stream \ --avec-openssl=../openssl-3.0.0 \ --avec-openssl-opt=enable-ktls \ --avec-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \ -with-ld-opt='-Wl,-Bfonctions-symboliques -Wl,-z,relro -Wl,-z,maintenant -Wl,--as-needed -pie' $ make –j4 $ make install

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

Configuration de NGINX

Pour activer kTLS, incluez 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 :

processus_travailleurs auto; journal_erreur /var/log/nginx/error.log débogage ;

événements {}

http {
envoyer le fichier ;

serveur {
écouter 443 ssl ;
certificat_ssl ssl/exemple.crt ;
clé_certificat_ssl ssl/exemple.key ;
ssl_conf_command Options KTLS ;
protocoles_ssl TLSv1.3 ;

emplacement / {
racine / données ;
}
}
}

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.log 2021/11/10 16:02:46 [débogage] 274550#274550 : *2 BIO_get_ktls_send() : 1 2021/11/10 16:02:49 [débogage] 274550#274550 : *3 BIO_get_ktls_send() : 1 $ grep SSL_sendfile /var/log/nginx/error.log 2021/11/10 16:02:46 [débogage] 274550#274550 : *2 SSL_sendfile : 1048576 2021/11/10 16:02:49 [débogage] 274550#274550 : *3 SSL_sendfile : 1048576

Note: 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 de 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 volumineux et épuiser rapidement l'espace disponible sur la partition de disque.

Amélioration des performances avec kTLS

Lors de la diffusion de fichiers statiques et de réponses mises en cache sous une charge importante, SSL_sendfile() peut augmenter le débit jusqu'à 2 fois par rapport à TLS dans l'espace utilisateur, mais l'ampleur de l'augmentation des performances dépend considérablement 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.

Test des performances

Pour mesurer l’amélioration des performances de votre configuration, utilisez les instructions suivantes pour exécuter un test simple à un seul thread. Comme détaillé ci-dessous, nos résultats de test indiquent une amélioration des performances allant jusqu'à près de 30 % sans aucun réglage spécifique.

Matériel et logiciel utilisés :

  • Instance AWS t3.medium avec :
    • 4 Go de RAM
    • SSD à usage général 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, créé et configuré comme spécifié dans Activation de kTLS dans NGINX .

Pour effectuer le test :

  1. Créez un fichier volumineux qui tient entièrement dans le cache du disque :

    # tronquer -s 1g /data/1G
    
  2. Exécutez cette commande pour vérifier le débit ; la commande de base est répétée plusieurs fois pour des résultats plus précis. Envoyez la sortie à l'utilitaire ministat [ FreeBSD ][ Ubuntu ] pour une analyse statistique de base.

     

    # pour i dans 'seq 1 100'; faire curl -k -s -o /dev/null -w '%{speed_download}\n' https://localhost/1G | ministat
    

Résultats des tests de performance

Dans les résultats suivants de nos tests, présentés sous forme de sortie de ministat , chaque valeur est la vitesse de téléchargement en Ko/seconde. La sortie est divisée sur deux lignes pour plus de lisibilité.

Débit pour FreeBSD 13.0 sans kTLS :

    N Min Max Médiane ...x 10 532225 573348 555616 ... 

...      Moyenne Écart-type 
... 555155.6 10239.137

Débit pour FreeBSD 13.0 avec kTLS :

    N Min Max Médiane ...x 10 629379 723164 717349 ... 

...      Moyenne Écart-type
... 708600.4 28304.766

Débit pour Ubuntu 21.10 sans kTLS :

    N Min Max Médiane ...x 10 529199 705720 662354 ... 

...      Moyenne Écart-type
... 654321.6 48025.103

Débit pour Ubuntu 21.10 avec kTLS :

    N Min Max Médiane ...x 10 619105 760208 756278 ... 

...      Moyenne Écart-type
... 741848.3 43255.246

Lors de nos tests, kTLS a amélioré les performances avec FreeBSD plus qu'avec Ubuntu. Le pourcentage d’amélioration était le suivant :

  Min Max Médian Moy.
FreeBSD 13.0 18% 26% 29% 28%
Ubuntu 21.10 16% 8% 14% 13%

Résumé

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() . Nos tests montrent que les performances s’améliorent entre 8 % et 29 %, selon le système d’exploitation.

Nous sommes intéressés par vos expériences avec kTLS et NGINX, et surtout par les résultats de vos tests sur d’autres systèmes d’exploitation ! S'il vous plaît, partagez-les dans la section commentaires ci-dessous.


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."