La seguridad de la capa de transporte (TLS) es un protocolo de criptografía 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 del usuario y el kernel.
La combinación de kTLS y sendfile()
significa que los datos se cifran directamente en el espacio del kernel, antes de pasar a la pila de red para su transmisión. Esto elimina la necesidad de copiar datos en el espacio del usuario para ser cifrados por las bibliotecas TLS y luego nuevamente en el espacio del kernel para su transmisión. kTLS también permite la descarga del procesamiento de TLS al hardware, incluida la descarga del procesamiento de criptografía simétrica de TLS a los dispositivos de red .
Los kernels modernos de Linux y FreeBSD admiten la descarga de TLS al kernel, ¡y ahora NGINX Open Source también lo hace! NGINX 1.21.4 presenta soporte para kTLS al servir archivos estáticos y respuestas almacenadas en caché con 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 use SSL_sendfile()
.
En este blog detallamos qué sistemas operativos y versiones de OpenSSL admiten kTLS y mostramos cómo construir y configurar el kernel y NGINX para kTLS. Para darle una idea de la mejora del 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 nuevas y evolucionan rápidamente. Este blog describe el soporte para kTLS a partir de noviembre de 2021, pero esté atento a los anuncios en nginx.org y el blog NGINX<.htmla> sobre cambios en la información y las instrucciones proporcionadas aquí.
Sistema operativo – Cualquiera de los siguientes:
FreeBSD 13.0+. A partir de noviembre de 2021, FreeBSD 13.0+ es el único sistema operativo que admite kTLS en NGINX sin una compilación manual de NGINX para incorporar OpenSSL 3.0.0+. Consulte Habilitación de NGINX con kTLS en FreeBSD .
Una distribución de Linux basada en la versión del kernel de Linux 4.17 o posterior, aunque recomendamos usar aquellas basadas en la versión 5.2 o posterior cuando sea posible. (La compatibilidad con kTLS está disponible en la versión 4.13, pero OpenSSL 3.0.0 requiere la versión del encabezado del kernel 4.17 o posterior).
OpenSSL – Versión 3.0.0 o posterior
NGINX – Versión 1.21.4 o posterior (línea principal)
[ Editor – NGINX Plus R27 y posteriores admiten kTLS en versiones elegibles del sistema operativo basado en Linux; NGINX Plus R26 y posteriores lo admiten en versiones elegibles de FreeBSD. Para obtener detalles sobre los sistemas operativos compatibles, consulte la página de versiones de NGINX Plus.]
A partir de noviembre de 2021, de los sistemas operativos compatibles con NGINX Open Source , los siguientes admiten kTLS y los cifrados indicados. Para obtener detalles sobre la compatibilidad con cifrado, consulte Protocolo TLS y compatibilidad con cifrado .
Cifrados TLSv1.2 | TLSv1.3 conjuntos de cifrado |
Cifrado TLS_CHACHA20_POLY1305_SHA256 |
Versión del kernel de 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 versión del kernel debe ser 5.10, no 4.14; consulte Sistemas operativos que no admiten kTLS y las Preguntas frecuentes de Amazon Linux 2
** Hereda su estado de soporte de kTLS de RHEL 8 como su fuente ascendente
*** Consulte el registro de confirmaciones de FreeBSD
Los siguientes sistemas operativos no admiten kTLS, por el motivo indicado:
CONFIG_TLS=n
, que deshabilita la construcción de kTLS como módulo o como parte del kernel.CONFIG_TLS=n
(consulte los registros de informes de errores de Debian ).Como se detalla anteriormente , los sistemas operativos que admiten kTLS varían en su compatibilidad con protocolos y cifrados TLS.
Con TLSv1.2, el módulo kTLS admite estos cifrados:
AES128-GCM-SHA256
AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
Con TLSv1.3, el módulo kTLS admite estos conjuntos de cifrado:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
(solo algunos sistemas operativos, como se especifica en Sistemas operativos que admiten kTLS )Para verificar qué cifrados TLS compatibles con OpenSSL están habilitados en su binario NGINX, ejecute el comando openssl-3.0.0/.openssl/bin/openssl
ciphers
en el directorio donde creó NGINX (por ejemplo, su directorio de inicio).
Como se mencionó en la introducción, kTLS mejora el rendimiento de NGINX porque todo el cifrado y descifrado se realizan 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 copiar los datos en el espacio del usuario para que las bibliotecas TLS los cifren y luego vuelvan al espacio del kernel para su transmisión.
En las distribuciones modernas de FreeBSD y Linux, kTLS generalmente se construye como un 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 detalles sobre las opciones de comando de FreeBSD, consulte la página del manual de ktls(4)
.
En distribuciones de Linux, ejecute este comando como usuario root
:
# modprobe tls
Para habilitar la compatibilidad con kTLS en NGINX en FreeBSD, puede utilizar las mismas instrucciones que para las distribuciones de Linux. Sin embargo, le recomendamos que realice los siguientes pasos para aprovechar la compilación de NGINX con kTLS en el puerto security/openssl-devel en la Colección de puertos 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.
Construya OpenSSL 3.0 con soporte kTLS, seleccionando las opciones apropiadas 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 la biblioteca SSL predeterminada:
# echo "VERSIONES_PREDETERMINADAS+=ssl=openssl-devel" >> /etc/make.conf
Construir NGINX:
# cd /usr/ports/www/nginx-devel && make install
La mayoría de las distribuciones de Linux actuales incluyen una versión de OpenSSL anterior a la 3.0.0 (comúnmente, la versión 1.1). Por lo tanto, debes compilar NGINX desde la fuente con OpenSSL 3.0.0.
Las dos opciones cruciales en el comando de configuración
que habilitan la compatibilidad con kTLS son:
--con-openssl=../openssl-3.0.0
--with-openssl-opt=habilitar-ktls
Las otras opciones de configuración
son para los módulos incluidos en los paquetes binarios oficiales de NGINX disponibles en nginx.org . Puede especificar un conjunto personalizado de módulos en su lugar. Para ver las opciones de compilación utilizadas para su binario NGINX actual, 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 \ --usuario=nginx \ --grupo=nginx \ --con-compatibilidad \ --con-archivo-aio \ --con-subprocesos \ --con-módulo_adicional_http \ --con-módulo_solicitud_autenticación_http \ --con-módulo_dav_http \ --con-módulo_flv_http \ --con-módulo_gunzip_http \ --con-módulo_gzip_estático_http \ --con-módulo_mp4_http \ --con-módulo_índice_aleatorio_http \ --con-módulo_realip_http \ --con-módulo_de_enlace_seguro_http \ --con-módulo_de_sección_http \ --con-módulo_ssl_http \ --con-módulo_de_estado_de_stub_http \ --con-submódulo_http \ --con-módulo_v2_http \ --con-correo \ --con-módulo_ssl_de-correo \ --con-flujo \ --con-módulo_realip_de-flujo \ --con-módulo_ssl_de-flujo \ --con-módulo_de_prelectura_ssl_de-flujo \ --con-openssl=../openssl-3.0.0 \ --con-openssl-opt=habilitar-ktls \ --con-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=seguridad-de-formato -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \ -with-ld-opt='-Wl,-Bfunciones-simbólicas -Wl,-z,relro -Wl,-z,ahora -Wl,--según-sea-necesario -pie' $ make –j4 $ make install
Nota: El binario NGINX resultante está vinculado estáticamente con las bibliotecas OpenSSL 3.0.0. Si más adelante necesita parchar OpenSSL, deberá descargar y descomprimir el nuevo archivo fuente de OpenSSL y luego ejecutar los comandos anteriores para reconstruir el binario 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 muestra utilizada para nuestras pruebas :
Procesos_de_trabajo automático; registro_de_errores /var/log/nginx/error.log depuración;
eventos {}
http {
enviar_archivo_en;
servidor {
escuchar 443 ssl;
certificado_ssl ssl/ejemplo.crt;
clave_certificado_ssl ssl/ejemplo.key;
comando_conf_ssl Opciones KTLS;
protocolos_ssl TLSv1.3;
ubicación / {
raíz /datos;
}
}
}
Para verificar que NGINX está usando kTLS, habilite el modo de depuración y verifique BIO_get_ktls_send()
y SSL_sendfile()
en el registro de errores.
$ grep BIO /var/log/nginx/error.log 2021/11/10 16:02:46 [depuración] 274550#274550: *2 BIO_get_ktls_send(): 1 10/11/2021 16:02:49 [depuración] 274550#274550: *3 BIO_get_ktls_send(): 1 $ grep SSL_sendfile /var/log/nginx/error.log 2021/11/10 16:02:46 [depuración] 274550#274550: *2 SSL_sendfile: 1048576 10/11/2021 16:02:49 [depuración] 274550#274550: *3 Archivo de envío SSL: 1048576
Nota: 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 implica una pérdida de rendimiento debido al gran volumen de operaciones de escritura; además, los registros de depuración pueden ser enormes y agotar rápidamente el espacio disponible en la partición del disco.
Al servir archivos estáticos y respuestas almacenadas en caché bajo una carga pesada, SSL_sendfile()
puede aumentar el rendimiento hasta 2 veces en comparación con TLS de espacio de usuario, pero el tamaño del aumento de rendimiento depende significativamente de varios factores (rendimiento del disco, carga del sistema, etc.). También es posible reducir el uso de la CPU si su tarjeta de red admite la descarga TLS.
Para medir el aumento de rendimiento en su configuración, utilice las siguientes instrucciones para ejecutar una prueba simple de un solo hilo. Como se detalla a continuación, los resultados de nuestras pruebas indican un aumento del rendimiento de hasta casi un 30% sin ningún ajuste específico.
Hardware y software utilizados:
TLS_AES_256_GCM_SHA384
Para realizar la prueba:
Cree un archivo grande que quepa completamente en la memoria caché del disco:
# truncar -s 1g /datos/1G
Ejecute este comando para verificar el rendimiento; el comando base se repite varias veces para obtener resultados más precisos. Envíe la salida a la utilidad ministat
[ FreeBSD ] [ Ubuntu ] para realizar un análisis estadístico básico.
# para i en 'seq 1 100'; hacer curl -k -s -o /dev/null -w '%{speed_download}\n' https://localhost/1G | ministat
En los siguientes resultados de nuestras pruebas, presentados como salida de ministat
, cada valor es la velocidad de descarga en kBytes/segundo. La salida se divide en dos líneas para facilitar la legibilidad.
Rendimiento para FreeBSD 13.0 sin kTLS:
N Mín Máx Mediana ...x 10 532225 573348 555616 ...
... Desviación estándar promedio
... 555155.6 10239.137
Rendimiento para FreeBSD 13.0 con kTLS:
N Mín Máx Mediana ...x 10 629379 723164 717349 ...
... Desviación estándar promedio
... 708600.4 28304.766
Rendimiento para Ubuntu 21.10 sin kTLS:
N Mín Máx Mediana ...x 10 529199 705720 662354 ...
... Desviación estándar promedio
... 654321.6 48025.103
Rendimiento para Ubuntu 21.10 con kTLS:
N Mín Máx Mediana ...x 10 619105 760208 756278 ...
... Desviación estándar promedio
... 741848.3 43255.246
En nuestras pruebas, kTLS mejoró el rendimiento más con FreeBSD que con Ubuntu. La mejora porcentual fue la siguiente:
Mínimo | Máximo | Mediana | Promedio | |
---|---|---|---|---|
FreeBSD 13.0 | 18 % | 26 % | 29 % | 28 % |
Ubuntu 21.10 | 16 % | 8 % | 14 % | 13 % |
NGINX 1.21.4 introduce soporte para kTLS al servir archivos estáticos y respuestas almacenadas en caché con SSL_sendfile()
. Nuestras pruebas muestran que el rendimiento mejora entre un 8% y un 29%, dependiendo del sistema operativo.
Nos interesa conocer sus experiencias con kTLS y NGINX, ¡y especialmente los resultados de sus pruebas en otros sistemas operativos! Por favor compártalos en la sección de comentarios a continuación.
"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.