Transport Layer Security (TLS) es un protocolo criptográfico extremadamente popular. La implementación de TLS en el kernel (kTLS) mejora el rendimiento al reducir significativamente la necesidad de realizar operaciones de copia entre el espacio de usuario y el kernel.
La combinación de kTLS y sendfile() permite cifrar los datos directamente en el espacio del kernel antes de pasarlos a la pila de red para su transmisión. Esto elimina la necesidad de copiar los datos al espacio de usuario para que las bibliotecas TLS los cifren y, después, volver a copiarlos al espacio del kernel para transmitirlos. kTLS también permite descargar el procesamiento de TLS en el hardware, incluida la descarga del procesamiento criptográfico simétrico de TLS en dispositivos de red.
Los kernels modernos de Linux y FreeBSD permiten delegar el procesamiento de TLS en el kernel, ¡y ahora NGINX Open Source también! NGINX 1.21.4 incorpora compatibilidad con kTLS al servir archivos estáticos y respuestas almacenadas en caché mediante SSL_sendfile(), lo que puede mejorar enormemente el rendimiento. Como se detalla a continuación, tanto el kernel como OpenSSL deben compilarse con kTLS para que NGINX pueda utilizar SSL_sendfile().
En este artículo detallamos qué versiones de sistemas operativos y de OpenSSL son compatibles con kTLS, y mostramos cómo compilar y configurar el kernel y NGINX para usar kTLS. Para que pueda hacerse una idea de la mejora de rendimiento que puede esperar de kTLS, también compartimos las especificaciones y los resultados de nuestras pruebas en FreeBSD y Ubuntu.
Nota: Las implementaciones de kTLS son bastante recientes y evolucionan rápidamente. Este blog describe la compatibilidad con kTLS a fecha de noviembre de 2021, pero esté atento a los anuncios en nginx.org y en el blog de NGINX<.htmla> sobre cambios en la información y las instrucciones aquí proporcionadas.
Requisitos generales
- Sistema operativo: cualquiera de los siguientes:
- FreeBSD 13.0+. A fecha de noviembre de 2021, FreeBSD 13.0+ es el único sistema operativo compatible con kTLS en NGINX sin tener que compilar manualmente NGINX para incorporar OpenSSL 3.0.0+. Consulte Habilitación de kTLS en NGINX en FreeBSD.
- Una distribución de Linux basada en la versión 4.17 o posterior del kernel de Linux, aunque recomendamos utilizar, siempre que sea posible, distribuciones basadas en la versión 5.2 o posterior. (En realidad, la compatibilidad con kTLS está disponible desde la versión 4.13, pero OpenSSL 3.0.0 requiere la versión 4.17 o posterior de las cabeceras del kernel).
- OpenSSL – Versión 3.0.0 o posterior
- NGINX – Versión 1.21.4 o posterior (rama principal)[Editor – NGINX Plus R27 y versiones posteriores admiten kTLS en las versiones compatibles de sistemas operativos basados en Linux; NGINX Plus R26 y versiones posteriores lo admiten en las versiones compatibles de FreeBSD. Para obtener más información sobre los sistemas operativos compatibles, consulte la página de Versiones de NGINX Plus.]
Compatibilidad con sistemas operativos
Sistemas operativos compatibles con kTLS
A fecha de noviembre de 2021, de los sistemas operativos compatibles con NGINX Open Source, los siguientes admiten kTLS y los cifrados indicados. Para obtener más información sobre la compatibilidad con los cifrados, consulte Compatibilidad con protocolos TLS y cifrados.
| Cifrados TLSv1.2 | Conjuntos de cifrados TLSv1.3 | Cifrado TLS_CHACHA20_POLY1305_SHA256 | Versión del kernel de Linux | |
|---|---|---|---|---|
| Amazon Linux 2* | ✅ | ✅ | ❌ | 5.10 |
| CentOS 8** | ✅ | ❌ | ❌ | 4.18 |
| FreeBSD 13.x | ✅ | ✅ | ❌ *** | N/D |
| 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 versión del kernel debe ser la 5.10, no la 4.14; consulte Sistemas operativos que no admiten kTLS y las Preguntas frecuentes sobre Amazon Linux 2
** Hereda el estado de compatibilidad con kTLS de RHEL 8, en el que se basa
*** Consulte el Registro de cambios de FreeBSD
Sistemas operativos que no admiten kTLS
Los siguientes sistemas operativos no son compatibles con kTLS por el motivo indicado:
- Alpine Linux 3.11–3.14 : el kernel se compila con la opción
CONFIG_TLS=n, que impide compilar kTLS como módulo o como parte del kernel. - Amazon Linux 2 – La versión del kernel de Linux es la 4.14 para la AMI predeterminada de Amazon Linux 2 (consulte las preguntas frecuentes sobre Amazon Linux 2).
- CentOS 7.4+ – La versión del kernel de Linux es la 3.10. Hereda el estado de compatibilidad con kTLS de RHEL 7.4+, su distribución de origen.
- Debian 10 y 11: el kernel se compila con la opción
CONFIG_TLS=n(consulte los registros del informe de errores de Debian). - RHEL 7.4+ – La versión del kernel de Linux es la 3.10.
- SLES 12 SP5+ – La versión del kernel de Linux es 4.12.
- Ubuntu 18.04 LTS – La versión del kernel de Linux es la 4.15.
Compatibilidad con protocolos y conjuntos de cifrado TLS
Como se detalla anteriormente, los sistemas operativos compatibles con kTLS ofrecen distintos niveles de compatibilidad con los protocolos y cifrados TLS.
Con TLSv1.2, el módulo kTLS admite los siguientes cifrados:
AES128-GCM-SHA256AES256-GCM-SHA384ECDHE-RSA-AES128-GCM-SHA256ECDHE-RSA-AES256-GCM-SHA384
Con TLSv1.3, el módulo kTLS admite los siguientes conjuntos de cifrado:
TLS_AES_128_GCM_SHA256TLS_AES_256_GCM_SHA384TLS_CHACHA20_POLY1305_SHA256(solo algunos sistemas operativos, según se especifica en «Sistemas operativos compatibles con kTLS»)
Para comprobar qué cifrados TLS compatibles con OpenSSL están habilitados en el binario de NGINX, ejecute el comando openssl-3.0.0/.openssl/bin/openssl ciphers en el directorio donde compiló NGINX (por ejemplo, su directorio personal).
Habilitación de kTLS en NGINX
Como se mencionó en la introducción, kTLS mejora el rendimiento de NGINX porque todo el cifrado y descifrado se lleva a cabo en el kernel. Los datos se cifran directamente en el espacio del kernel —antes de pasarlos a la pila de red para su transmisión—, lo que elimina la necesidad de copiarlos al espacio de usuario para que las bibliotecas TLS los cifren y, después, volver a copiarlos al espacio del kernel para transmitirlos.

Carga de kTLS en el kernel
En las distribuciones modernas de FreeBSD y Linux, kTLS suele compilarse como módulo (con la opción CONFIG_TLS=m). Debe cargar explícitamente el módulo kTLS en el kernel antes de iniciar NGINX.
- En FreeBSD, ejecute estos comandos como usuario
root:
# kldload ktls_ocf.ko# sysctl kern.ipc.tls.enable=1- Para obtener más información sobre las opciones de los comandos de FreeBSD, consulte la página del manual de
ktls(4). - En las distribuciones Linux, ejecute este comando como usuario
root:
# modprobe tlsHabilitar NGINX con kTLS en FreeBSD
Para habilitar la compatibilidad con kTLS en NGINX en FreeBSD, puede seguir las mismas instrucciones que para las distribuciones de Linux. Sin embargo, le recomendamos que siga los pasos que se indican a continuación para aprovechar la compilación de NGINX con kTLS disponible en el port security/openssl-devel de la colección de ports de FreeBSD. Para obtener más información, incluida una descripción general de kTLS, consulte Descarga de TLS en el kernel en el sitio web de FreeBSD.
- Compile OpenSSL 3.0 con compatibilidad con kTLS, seleccionando las opciones adecuadas en el menú de configuración:
# cd /usr/ports/security/openssl-devel && make config && make install- Modifique /etc/make.conf para utilizar openssl-devel como biblioteca SSL predeterminada:
# echo "DEFAULT_VERSIONS+=ssl=openssl-devel" >> /etc/make.conf- Compila NGINX:
# cd /usr/ports/www/nginx-devel && make installCompilación de NGINX con kTLS en distribuciones Linux
La mayoría de las distribuciones de Linux actuales incluyen una versión de OpenSSL anterior a la 3.0.0 (normalmente, la versión 1.1). Por tanto, debe compilar NGINX a partir del código fuente con OpenSSL 3.0.0.
Las dos opciones fundamentales del comando configure que habilitan la compatibilidad con kTLS son:
--with-openssl=../openssl-3.0.0--with-openssl-opt=enable-ktls
Las demás opciones de configure corresponden a los módulos incluidos en los paquetes binarios oficiales de NGINX disponibles en nginx.org. También puede especificar un conjunto personalizado de módulos. Para ver las opciones de compilación utilizadas para su binario actual de NGINX, ejecute nginx -V.
Para compilar NGINX con OpenSSL 3.0.0, ejecute los siguientes comandos:
$ 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 installNota: El binario de NGINX resultante está enlazado estáticamente con las bibliotecas de OpenSSL 3.0.0. Si más adelante necesita aplicar un parche a OpenSSL, deberá descargar y descomprimir el nuevo archivo de código fuente de OpenSSL y, a continuación, ejecutar los comandos anteriores para volver a compilar el binario de NGINX.
Configuración de NGINX
Para habilitar kTLS, incluya la directiva ssl_conf_command con el parámetro Options KTLS en el contexto server{}, como en esta configuración de ejemplo utilizada para nuestras pruebas:
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; } }}Verificar que kTLS está habilitado
Para verificar que NGINX está utilizando kTLS, habilite el modo de depuración y compruebe si aparecen BIO_get_ktls_send() y SSL_sendfile() en el registro de errores.
$ 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: 1048576Nota: Le recomendamos que desactive el modo de depuración después de realizar estas comprobaciones, especialmente en entornos de producción. El registro de depuración afecta al rendimiento debido al gran volumen de operaciones de escritura; además, los registros de depuración pueden alcanzar un tamaño enorme y agotar rápidamente el espacio disponible en la partición del disco.
Mejora del rendimiento con kTLS
Al servir archivos estáticos y respuestas almacenadas en caché con una carga elevada, SSL_sendfile() puede aumentar el rendimiento hasta el doble en comparación con TLS en el espacio de usuario, aunque la mejora del rendimiento depende en gran medida de diversos factores (rendimiento del disco, carga del sistema, etc.). También es posible reducir el uso de la CPU si la tarjeta de red admite la descarga de TLS.
Pruebas de rendimiento
Para medir la mejora de rendimiento en su configuración, siga las instrucciones que se indican a continuación para realizar una sencilla prueba con un solo hilo. Como se detalla más adelante, los resultados de nuestras pruebas indican una mejora de rendimiento de casi un 30 % sin ningún ajuste específico.
Hardware y software utilizados:
- Instancia t3.medium de AWS con:
- 4 GB de RAM
- SSD de uso general de 20 GB
- CPU Intel® Xeon® Platinum 8259CL a 2,50 GHz con 2 núcleos
- FreeBSD 13.0 y Ubuntu 21.10
- TLSv1.3 con el conjunto de cifrado
TLS_AES_256_GCM_SHA384cipher suite - NGINX 1.21.4, compilado y configurado según se especifica en «Habilitación de kTLS en NGINX».
Para realizar la prueba:
- Cree un archivo grande que quepa por completo en la caché de disco:
# truncate -s 1g /data/1G- Ejecute este comando para comprobar el rendimiento; el comando base se repite varias veces para obtener resultados más precisos. Redirija la salida a la utilidad
ministat[FreeBSD][Ubuntu] para realizar un análisis estadístico básico.
# for i in 'seq 1 100'; do curl -k -s -o /dev/null -w '%{speed_download}n' https://localhost/1G | ministatResultados de las pruebas de rendimiento
En los siguientes resultados de nuestras pruebas, presentados como salida de ministat, cada valor representa la velocidad de descarga en kBytes/segundo. La salida se divide en dos líneas para facilitar su lectura.
Rendimiento de FreeBSD 13.0 sin kTLS:
N Min Max Median ...x 10 532225 573348 555616 ... ... Avg Stddev ... 555155.6 10239.137Rendimiento de FreeBSD 13.0 con kTLS:
N Min Max Median ...x 10 629379 723164 717349 ... ... Avg Stddev ... 708600.4 28304.766Rendimiento de Ubuntu 21.10 sin kTLS:
N Min Max Median ...x 10 529199 705720 662354 ... ... Avg Stddev ... 654321.6 48025.103Rendimiento de Ubuntu 21.10 con kTLS:
N Min Max Median ...x 10 619105 760208 756278 ... ... Avg Stddev ... 741848.3 43255.246En nuestras pruebas, kTLS mejoró más el rendimiento con FreeBSD que con Ubuntu. La mejora porcentual fue la siguiente:
| Mín. | Máx. | Mediana | Promedio | |
|---|---|---|---|---|
| FreeBSD 13.0 | 18% | 26% | 29% | 28% |
| Ubuntu 21.10 | 16% | 8% | 14% | 13% |
Resumen
NGINX 1.21.4 incorpora compatibilidad con kTLS al servir archivos estáticos y respuestas almacenadas en caché mediante SSL_sendfile(). Nuestras pruebas muestran que el rendimiento mejora entre un 8 % y un 29 %, dependiendo del sistema operativo.
Nos interesa conocer vuestras experiencias con kTLS y NGINX y, en especial, los resultados de vuestras pruebas en otros sistemas operativos. Compartidlos en la sección de comentarios que aparece a continuación.
Sobre el autor
Artículos relacionados del blog
Únete a F5 NGINX en AppWorld 2024
Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.
Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.
Exposición de APIs en Kubernetes
La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».
NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.
Presentamos NGINX Plus R22
NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.
Presentamos NGINX Plus R17
NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.