O Transport Layer Security (TLS) é um protocolo criptográfico extremamente popular. A implementação do TLS no kernel (kTLS) melhora o desempenho ao reduzir significativamente a necessidade de operações de cópia entre o espaço do usuário e o kernel.
A combinação do kTLS com sendfile() faz com que os dados sejam criptografados diretamente no espaço do kernel antes de serem encaminhados à pilha de rede para transmissão. Isso elimina a necessidade de copiar os dados para o espaço do usuário para que sejam criptografados por bibliotecas TLS e, em seguida, copiá-los de volta para o espaço do kernel para transmissão. O kTLS também permite transferir o processamento TLS para o hardware, incluindo a transferência do processamento criptográfico simétrico do TLS para dispositivos de rede.
Os kernels modernos do Linux e do FreeBSD permitem transferir o processamento de TLS para o kernel, e agora o NGINX Open Source também! O NGINX 1.21.4 introduz suporte a kTLS ao fornecer arquivos estáticos e respostas armazenadas em cache com SSL_sendfile(), o que pode melhorar significativamente o desempenho. Conforme detalhado abaixo, tanto o kernel quanto o OpenSSL devem ser compilados com kTLS para que o NGINX possa usar SSL_sendfile().
Neste blog, detalhamos quais versões de sistemas operacionais e do OpenSSL são compatíveis com kTLS e mostramos como compilar e configurar o kernel e o NGINX para usar kTLS. Para dar uma ideia da melhoria de desempenho que você pode esperar com kTLS, também compartilhamos as especificações e os resultados dos nossos testes no FreeBSD e no Ubuntu.
Observação: as implementações de kTLS são bastante recentes e estão evoluindo rapidamente. Este blog descreve a compatibilidade com kTLS em novembro de 2021, mas fique atento aos anúncios no nginx.org e no blog da NGINX<.htmla> sobre alterações nas informações e instruções fornecidas aqui.
Requisitos gerais
- Sistema operacional – qualquer um dos seguintes:
- FreeBSD 13.0+. Desde novembro de 2021, o FreeBSD 13.0+ é o único sistema operacional compatível com kTLS no NGINX sem a necessidade de compilar manualmente o NGINX para incorporar o OpenSSL 3.0.0+. Consulte Como habilitar o NGINX com kTLS no FreeBSD.
- Uma distribuição Linux baseada na versão 4.17 ou posterior do kernel Linux, embora recomendemos usar, sempre que possível, distribuições baseadas na versão 5.2 ou posterior. (Na verdade, o suporte a kTLS está disponível desde a versão 4.13, mas o OpenSSL 3.0.0 requer a versão 4.17 ou posterior dos cabeçalhos do kernel.)
- OpenSSL – Versão 3.0.0 ou posterior
- NGINX – Versão 1.21.4 ou posterior (mainline)[Editor – NGINX Plus R27 e versões posteriores oferecem suporte a kTLS em versões qualificadas de sistemas operacionais baseados em Linux; NGINX Plus R26 e versões posteriores oferecem esse suporte em versões qualificadas do FreeBSD. Para obter detalhes sobre os sistemas operacionais compatíveis, consulte a página de Versões do NGINX Plus.]
Suporte a sistemas operacionais
Sistemas operacionais compatíveis com kTLS
Em novembro de 2021, entre os sistemas operacionais compatíveis com o NGINX Open Source, os seguintes eram compatíveis com kTLS e com as cifras indicadas. Para obter detalhes sobre a compatibilidade com cifras, consulte Compatibilidade com cifras e o protocolo TLS.
| Cifras TLSv1.2 | Conjuntos de cifras TLSv1.3 | Cifra TLS_CHACHA20_POLY1305_SHA256 | Versão do kernel 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 |
* A versão do kernel deve ser a 5.10, e não a 4.14; consulte Sistemas operacionais que não oferecem suporte a kTLS e as Perguntas frequentes sobre o Amazon Linux 2
** Herda o status de suporte a kTLS do RHEL 8, no qual se baseia
*** Consulte o registro de commits do FreeBSD
Sistemas operacionais que não oferecem suporte a kTLS
Os sistemas operacionais a seguir não oferecem suporte a kTLS, pelo motivo indicado:
- Alpine Linux 3.11–3.14 – O kernel é compilado com a opção
CONFIG_TLS=n, o que impede a compilação do kTLS como um módulo ou como parte do kernel. - Amazon Linux 2 – a versão do kernel Linux é a 4.14 para a AMI padrão do Amazon Linux 2 (consulte as Perguntas frequentes sobre o Amazon Linux 2).
- CentOS 7.4+ – A versão do kernel Linux é 3.10. Herda o status de suporte a kTLS do RHEL 7.4+, que é sua fonte upstream.
- Debian 10 e 11 – O kernel é compilado com a opção
CONFIG_TLS=n(consulte os logs do relatório de bug do Debian). - RHEL 7.4+ – A versão do kernel Linux é 3.10.
- SLES 12 SP5+ – a versão do kernel Linux é 4.12.
- Ubuntu 18.04 LTS – a versão do kernel Linux é 4.15.
Suporte a protocolos e cifras TLS
Conforme detalhado acima, os sistemas operacionais compatíveis com kTLS variam quanto ao suporte a protocolos TLS e conjuntos de cifras.
Com o TLSv1.2, o módulo kTLS oferece suporte às seguintes cifras:
AES128-GCM-SHA256AES256-GCM-SHA384ECDHE-RSA-AES128-GCM-SHA256ECDHE-RSA-AES256-GCM-SHA384
Com o TLSv1.3, o módulo kTLS oferece suporte aos seguintes conjuntos de cifras:
TLS_AES_128_GCM_SHA256TLS_AES_256_GCM_SHA384TLS_CHACHA20_POLY1305_SHA256(somente alguns sistemas operacionais, conforme especificado em Sistemas operacionais compatíveis com kTLS)
Para verificar quais cifras TLS compatíveis com o OpenSSL estão habilitadas no seu binário do NGINX, execute o comando openssl-3.0.0/.openssl/bin/openssl ciphers no diretório em que você compilou o NGINX (por exemplo, seu diretório pessoal).
Habilitando o kTLS no NGINX
Como mencionado na introdução, o kTLS melhora o desempenho do NGINX porque toda a criptografia e descriptografia ocorrem no kernel. Os dados são criptografados diretamente no espaço do kernel – antes de serem encaminhados à pilha de rede para transmissão –, eliminando a necessidade de copiá-los para o espaço do usuário a fim de serem criptografados por bibliotecas TLS e, em seguida, copiá-los de volta para o espaço do kernel para transmissão.

Carregando o kTLS no kernel
Nas distribuições modernas do FreeBSD e do Linux, o kTLS geralmente é compilado como um módulo (com a opção CONFIG_TLS=m). É necessário carregar explicitamente o módulo kTLS no kernel antes de iniciar o NGINX.
- No FreeBSD, execute estes comandos como o usuário
root:
# kldload ktls_ocf.ko# sysctl kern.ipc.tls.enable=1- Para obter detalhes sobre as opções de comando do FreeBSD, consulte a página do manual de
ktls(4). - Em distribuições Linux, execute este comando como usuário
root:
# modprobe tlsHabilitando o NGINX com kTLS no FreeBSD
Para habilitar o suporte a kTLS no NGINX no FreeBSD, você pode seguir as mesmas instruções usadas para distribuições Linux. No entanto, recomendamos que você execute as etapas a seguir para aproveitar a compilação do NGINX com kTLS disponível no port security/openssl-devel da Coleção de Ports do FreeBSD. Para obter mais informações, incluindo uma visão geral do kTLS, consulte Descarregamento de TLS no kernel no site do FreeBSD.
- Compile o OpenSSL 3.0 com suporte a kTLS, selecionando as opções apropriadas no menu de configuração:
# cd /usr/ports/security/openssl-devel && make config && make install- Modifique /etc/make.conf para usar openssl-devel como a biblioteca SSL padrão:
# echo "DEFAULT_VERSIONS+=ssl=openssl-devel" >> /etc/make.conf- Compile o NGINX:
# cd /usr/ports/www/nginx-devel && make installCompilando o NGINX com kTLS em distribuições Linux
A maioria das distribuições Linux atuais inclui uma versão do OpenSSL anterior à 3.0.0 (geralmente, a versão 1.1). Portanto, é necessário compilar o NGINX a partir do código-fonte com o OpenSSL 3.0.0.
As duas opções essenciais do comando configure que habilitam o suporte a kTLS são:
--with-openssl=../openssl-3.0.0--with-openssl-opt=enable-ktls
As outras opções de configure são destinadas aos módulos incluídos nos pacotes binários oficiais do NGINX disponíveis em nginx.org. Como alternativa, você pode especificar um conjunto personalizado de módulos. Para ver as opções de compilação usadas no seu binário atual do NGINX, execute nginx -V.
Para compilar o NGINX com o OpenSSL 3.0.0, execute os seguintes 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 installObservação: O binário do NGINX resultante é vinculado estaticamente às bibliotecas do OpenSSL 3.0.0. Se posteriormente você precisar aplicar uma correção ao OpenSSL, deverá baixar e descompactar o novo arquivo de código-fonte do OpenSSL e, em seguida, executar os comandos acima para recompilar o binário do NGINX.
Configurando o NGINX
Para habilitar o kTLS, inclua a diretiva ssl_conf_command com o parâmetro Options KTLS no contexto server{}, como nesta configuração de exemplo usada em nossos testes:
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; } }}Verificando se o kTLS está habilitado
Para verificar se o NGINX está usando kTLS, ative o modo de depuração e verifique se há ocorrências de BIO_get_ktls_send() e SSL_sendfile() no log de erros.
$ 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: 1048576Observação: Recomendamos desativar o modo de depuração após realizar essas verificações, especialmente em ambientes de produção. O registro em log de depuração causa perda de desempenho devido ao grande volume de operações de gravação. Além disso, os logs de depuração podem ser enormes e esgotar rapidamente o espaço disponível na partição do disco.
Melhoria de desempenho com kTLS
Ao disponibilizar arquivos estáticos e respostas em cache sob carga intensa, SSL_sendfile() pode aumentar a taxa de transferência em até 2x em comparação com o TLS no espaço do usuário, mas o ganho de desempenho depende significativamente de vários fatores (desempenho do disco, carga do sistema etc.). Também é possível reduzir o uso da CPU se a sua placa de rede for compatível com o descarregamento de TLS.
Testando o desempenho
Para medir o ganho de desempenho na sua configuração, siga as instruções abaixo para executar um teste simples com uma única thread. Conforme detalhado a seguir, os resultados dos nossos testes indicam um ganho de desempenho de quase 30%, sem nenhum ajuste específico.
Hardware e software utilizados:
- Instância t3.medium da AWS com:
- 4 GB de RAM
- SSD de uso geral de 20 GB
- CPU Intel® Xeon® Platinum 8259CL de 2,50 GHz com 2 núcleos
- FreeBSD 13.0 e Ubuntu 21.10
- TLSv1.3 com o conjunto de cifras
TLS_AES_256_GCM_SHA384cipher suite - NGINX 1.21.4, compilado e configurado conforme especificado em Como habilitar o kTLS no NGINX.
Para realizar o teste:
- Crie um arquivo grande que caiba completamente no cache de disco:
# truncate -s 1g /data/1G- Execute este comando para verificar a taxa de transferência; o comando base é repetido várias vezes para obter resultados mais precisos. Redirecione a saída para o utilitário
ministat[FreeBSD][Ubuntu] para realizar uma análise estatística básica.
# for i in 'seq 1 100'; do curl -k -s -o /dev/null -w '%{speed_download}n' https://localhost/1G | ministatResultados dos testes de desempenho
Nos resultados dos nossos testes a seguir, apresentados como saída do ministat, cada valor representa a velocidade de download em kBytes/segundo. A saída foi dividida em duas linhas para facilitar a leitura.
Taxa de transferência do FreeBSD 13.0 sem kTLS:
N Min Max Median ...x 10 532225 573348 555616 ... ... Avg Stddev ... 555155.6 10239.137Taxa de transferência do FreeBSD 13.0 com kTLS:
N Min Max Median ...x 10 629379 723164 717349 ... ... Avg Stddev ... 708600.4 28304.766Taxa de transferência no Ubuntu 21.10 sem kTLS:
N Min Max Median ...x 10 529199 705720 662354 ... ... Avg Stddev ... 654321.6 48025.103Taxa de transferência no Ubuntu 21.10 com kTLS:
N Min Max Median ...x 10 619105 760208 756278 ... ... Avg Stddev ... 741848.3 43255.246Em nossos testes, o kTLS melhorou mais o desempenho no FreeBSD do que no Ubuntu. O aumento percentual foi o seguinte:
| Mín. | Máx. | Mediana | Média | |
|---|---|---|---|---|
| FreeBSD 13.0 | 18% | 26% | 29% | 28% |
| Ubuntu 21.10 | 16% | 8% | 14% | 13% |
Resumo
O NGINX 1.21.4 introduz suporte a kTLS ao fornecer arquivos estáticos e respostas armazenadas em cache com SSL_sendfile(). Nossos testes mostram que o desempenho melhora entre 8% e 29%, dependendo do sistema operacional.
Queremos saber mais sobre suas experiências com o kTLS e o NGINX, especialmente os resultados dos seus testes em outros sistemas operacionais! Compartilhe-os na seção de comentários abaixo.
Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.