Transport Layer Security (TLS) é um protocolo de criptografia 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.
Combinar kTLS e sendfile()
significa que os dados são criptografados diretamente no espaço do kernel, antes de serem passados para a pilha de rede para transmissão. Isso elimina a necessidade de copiar dados para o espaço do usuário para serem criptografados pelas bibliotecas TLS e depois de volta para o espaço do kernel para transmissão. O kTLS também permite o descarregamento do processamento TLS para o hardware, incluindo o descarregamento do processamento criptográfico simétrico TLS para dispositivos de rede .
Os kernels modernos do Linux e do FreeBSD suportam o descarregamento de TLS para o kernel, e agora o NGINX Open Source também! O NGINX 1.21.4 introduz suporte para kTLS ao servir arquivos estáticos e respostas em cache com SSL_sendfile()
, o que pode melhorar muito o desempenho. Conforme detalhado abaixo, tanto o kernel quanto o OpenSSL devem ser construídos com kTLS para que o NGINX use SSL_sendfile()
.
Neste blog, detalhamos quais sistemas operacionais e versões do OpenSSL oferecem suporte ao kTLS e mostramos como construir e configurar o kernel e o NGINX para o kTLS. Para lhe dar uma ideia da melhoria de desempenho que você pode esperar do kTLS, também compartilhamos as especificações e os resultados dos nossos testes no FreeBSD e no Ubuntu.
Observação: as implementações do kTLS são bastante novas e evoluem rapidamente. Este blog descreve o suporte ao kTLS a partir de novembro de 2021, mas fique atento aos anúncios no nginx.org e no blog NGINX<.htmla> sobre mudanças nas informações e instruções fornecidas aqui.
Sistema operacional – Qualquer um dos seguintes:
FreeBSD 13.0+. Em novembro de 2021, o FreeBSD 13.0+ era o único sistema operacional compatível com kTLS no NGINX sem uma compilação manual do NGINX para incorporar o OpenSSL 3.0.0+. Veja Habilitando o NGINX com kTLS no FreeBSD .
Uma distribuição Linux construída no kernel Linux versão 4.17 ou posterior, embora recomendemos usar aquelas construídas na versão 5.2 ou posterior quando possível. (o suporte ao kTLS está realmente disponível na versão 4.13, mas o OpenSSL 3.0.0 requer o cabeçalho do kernel versão 4.17 ou posterior.)
OpenSSL – Versão 3.0.0 ou posterior
NGINX – Versão 1.21.4 ou posterior (linha principal)
[ Editor – NGINX Plus R27 e posteriores oferecem suporte a kTLS em versões qualificadas de sistemas operacionais baseados em Linux; NGINX Plus R26 e posteriores oferecem suporte a ele em versões qualificadas do FreeBSD. Para obter detalhes sobre os sistemas operacionais suportados, consulte a página de versões do NGINX Plus.]
Em novembro de 2021, dos sistemas operacionais suportados pelo NGINX Open Source , os seguintes suportavam kTLS e as cifras indicadas. Para obter detalhes sobre o suporte à cifra, consulte Protocolo TLS e suporte à cifra .
Cifras TLSv1.2 | TLSv1.3 conjuntos de cifras |
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 5.10, não 4.14; veja SOs que não suportam kTLS e as Perguntas frequentes do Amazon Linux 2
** Herda seu status de suporte kTLS do RHEL 8 como sua fonte upstream
*** Veja o log de commits do FreeBSD
Os seguintes sistemas operacionais não oferecem suporte ao kTLS, pelo motivo indicado:
CONFIG_TLS=n
, que desabilita a construção do kTLS como um módulo ou como parte do kernel.CONFIG_TLS=n
(veja os logs de relatórios de bugs do Debian ).Conforme detalhado acima , os sistemas operacionais que oferecem suporte ao kTLS variam em seu suporte aos protocolos e cifras TLS.
Com o TLSv1.2, o módulo kTLS suporta estas cifras:
AES128-GCM-SHA256
AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
Com o TLSv1.3, o módulo kTLS suporta estes conjuntos de cifras:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
(apenas alguns sistemas operacionais, conforme especificado em SOs que suportam kTLS )Para verificar quais cifras TLS suportadas pelo OpenSSL estão habilitadas no seu binário NGINX, execute o comando openssl-3.0.0/.openssl/bin/openssl
ciphers
no diretório onde você construiu o NGINX (por exemplo, seu diretório inicial).
Conforme 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 passados para a pilha de rede para transmissão – eliminando a necessidade de copiar dados para o espaço do usuário para serem criptografados pelas bibliotecas TLS e, em seguida, de volta para o espaço do kernel para transmissão.
Nas distribuições modernas de FreeBSD e Linux, o kTLS geralmente é criado como um módulo (com a opção CONFIG_TLS=m
). Você deve carregar explicitamente o módulo kTLS no kernel antes de iniciar o NGINX.
No FreeBSD, execute estes comandos como usuário root
:
# kldload ktls_ocf.ko # sysctl kern.ipc.tls.enable=1
Para detalhes sobre as opções de comando do FreeBSD, consulte a página de manual do ktls(4)
.
Em distribuições Linux, execute este comando como usuário root
:
# modprobe tls
Para habilitar o suporte a kTLS no NGINX no FreeBSD, você pode usar as mesmas instruções para distribuições Linux. No entanto, recomendamos que você execute as seguintes etapas para aproveitar a compilação do NGINX com kTLS na porta security/openssl-devel na Coleção de Ports do FreeBSD . Para mais informações, incluindo uma visão geral do kTLS, consulte TLS Offload in the Kernel no site do FreeBSD.
Crie o OpenSSL 3.0 com suporte a kTLS, selecionando as opções apropriadas no menu de configuração:
# cd /usr/ports/security/openssl-devel && fazer configuração && fazer instalação
Modifique /etc/make.conf para usar openssl-devel como a biblioteca SSL padrão:
# echo "VERSÕES_PADRÃO+=ssl=openssl-devel" >> /etc/make.conf
Crie o NGINX:
# cd /usr/ports/www/nginx-devel && make install
A maioria das distribuições Linux atuais inclui uma versão do OpenSSL anterior à 3.0.0 (comumente, versão 1.1). Então você precisa construir o NGINX a partir do código-fonte com o OpenSSL 3.0.0.
As duas opções cruciais no comando configure
que habilitam o suporte ao kTLS são:
--com-openssl=../openssl-3.0.0
--com-openssl-opt=habilitar-ktls
As outras opções de configuração
são para os módulos incluídos nos pacotes binários oficiais do NGINX disponíveis em nginx.org . Em vez disso, você pode especificar um conjunto personalizado de módulos. Para ver as opções de compilação usadas para seu binário NGINX atual, execute nginx
-V
.
Para construir o NGINX com 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 \ --com-módulo_realip_http \ --com-módulo_link_seguro_http \ --com-módulo_slice_http \ --com-módulo_ssl_http \ --com-módulo_status_stub_http \ --com-módulo_sub_http \ --com-módulo_v2_http \ --com-mail \ --com-módulo_ssl_mail \ --com-stream \ --com-stream_realip_module \ --com-stream_ssl_module \ --com-stream_ssl_preread_module \ --com-openssl=../openssl-3.0.0 \ --com-openssl-opt=enable-ktls \ --com-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \ -com-ld-opt='-Wl,-Bfunções-simbólicas -Wl,-z,relro -Wl,-z,agora -Wl,--conforme-necessário -pie' $ make –j4 $ make install
Observação: O binário NGINX resultante é vinculado estaticamente às bibliotecas OpenSSL 3.0.0. Se mais tarde você precisar corrigir o OpenSSL, deverá baixar e descompactar o novo arquivo de origem do OpenSSL e, em seguida, executar os comandos acima para reconstruir o binário 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 para 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 Opções KTLS;
ssl_protocols TLSv1.3;
location / {
root /data;
}
}
}
Para verificar se o NGINX está usando kTLS, ative o modo de depuração e verifique BIO_get_ktls_send()
e SSL_sendfile()
no log de erros.
$ grep BIO /var/log/nginx/error.log 2021/11/10 16:02:46 [depuração] 274550#274550: *2 BIO_get_ktls_send(): 1 2021/11/10 16:02:49 [depuração] 274550#274550: *3 BIO_get_ktls_send(): 1 $ grep SSL_sendfile /var/log/nginx/error.log 2021/11/10 16:02:46 [depuração] 274550#274550: *2 SSL_sendfile: 1048576 2021/11/10 16:02:49 [depuração] 274550#274550: *3 SSL_sendfile: 1048576
Observação: Recomendamos que você desabilite o modo de depuração depois de fazer essas verificações, especialmente em ambientes de produção. O registro de depuração acarreta uma perda de desempenho devido ao grande volume de operações de gravação; além disso, os registros de depuração podem ser enormes e esgotar rapidamente o espaço disponível na partição do disco.
Ao servir arquivos estáticos e respostas em cache sob carga pesada, SSL_sendfile()
pode aumentar a taxa de transferência em até 2x em comparação ao TLS de espaço do usuário, mas o tamanho do aumento 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 sua placa de rede suportar descarregamento TLS.
Para medir o aumento de desempenho em sua configuração, use as instruções a seguir para executar um teste simples de um thread. Conforme detalhado abaixo, nossos resultados de teste indicam um aumento de desempenho de até quase 30% sem nenhum ajuste específico.
Hardware e software utilizados:
TLS_AES_256_GCM_SHA384
Para realizar o teste:
Crie um arquivo grande que caiba completamente no cache de disco:
# truncar -s 1g /dados/1G
Execute este comando para verificar a taxa de transferência; o comando base é repetido várias vezes para resultados mais precisos. Envie a saída para o utilitário ministat
[ FreeBSD ][ Ubuntu ] para uma análise estatística básica.
# para i em 'seq 1 100'; faça curl -k -s -o /dev/null -w '%{speed_download}\n' https://localhost/1G | ministat
Nos resultados a seguir dos nossos testes, apresentados como saída do ministat
, cada valor é a velocidade de download em kBytes/segundo. A saída é dividida em duas linhas para maior legibilidade.
Taxa de transferência para FreeBSD 13.0 sem kTLS:
N Mín. Máx. Mediana ...x 10 532225 573348 555616 ...
... Desvio Padrão Médio
... 555155.6 10239.137
Taxa de transferência para FreeBSD 13.0 com kTLS:
N Mín. Máx. Mediana ...x 10 629379 723164 717349 ...
... Desvio Padrão Médio
... 708600.4 28304.766
Taxa de transferência para Ubuntu 21.10 sem kTLS:
N Mín. Máx. Mediana ...x 10 529199 705720 662354 ...
... Desvio Padrão Médio
... 654321.6 48025.103
Taxa de transferência para Ubuntu 21.10 com kTLS:
N Mín. Máx. Mediana ...x 10 619105 760208 756278 ...
... Desvio Padrão Médio
... 741848.3 43255.246
Em nossos testes, o kTLS melhorou mais o desempenho com o FreeBSD do que com o Ubuntu. A melhoria percentual foi a seguinte:
Mínimo | Máx. | Mediana | Média | |
---|---|---|---|---|
FreeBSD 13.0 | 18% | 26% | 29% | 28% |
Ubuntu 21.10 | 16% | 8% | 14% | 13% |
O NGINX 1.21.4 introduz suporte para kTLS ao servir arquivos estáticos e respostas em cache com SSL_sendfile()
. Nossos testes mostram que o desempenho melhora entre 8% e 29%, dependendo do sistema operacional.
Estamos interessados em saber sobre suas experiências com kTLS e NGINX, e especialmente os resultados de seus testes em outros sistemas operacionais! Por favor, compartilhe-os na seção de comentários abaixo.
"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."