Как стать автором
Обновить

Комментарии 24

На данный момент много проектов смотрят на kernel TLS. Он может сильно изменить имеющиеся стандарты. Например, nfs over tls, который активно развивается, может вытеснить керберос на СХД.

Теоретически, выгоду могут получить любые проекты, использующие TLS. вот сразу в голову пришло — тот же Postfix MTA, всё пересылку ведет через файлы, умеет использовать sendfile, но в режиме TLS такое не поддерживает.
Но меня больше интересуют проекты, в которых уже была реализована поддержка. Правда, я больше искал в направлении WEB-серверов, возможно проекты в других направлениях используют.

а в чём выгода от переноса шифрования в kernel-space?
избавиться от копирования в userspace? так (кроме отдачи статики) данные обычно из userspace приходят.
использовать аппаратное шифрование? а насколько оно хорошо будет работать с 100500 одновременными сессиями?

Выгода действительно в том, чтобы избавиться от копирования при отдаче статичного контента. В основном это раздача on-line видео. В этой заметке Netfilx довольно глубоко описывают профит.
Использование аппаратного шифрования в сетевой карте — это достаточно новая тема. Mellanox предлагает такое только в своих ConnectX-6 DX, которые имеют интерфейсы 2х100 Gbit или 1х200 Gbit. На таких скоростях даже «дешевое» шифрование с использованием AES-NI будет потреблять значительную количество CPU, которое можно было бы использовать в более нужных вещах. Насколько оно хорошо работает — это, конечно, вопрос. Но не думаю, что в этом проблема будет, потому что офлоадить IPSec с множеством соединений научились еще в Intel 82599, а шифрование потока в TLS не сильно отличается.
Выгода действительно в том, чтобы избавиться от копирования при отдаче статичного контента.

ну это лишь один из возможных сценариев использования nginx, мне кажется, что далеко не самый распространённый.
в случае «nginx проксирует и обеспечивает tls» выигрыша, думаю, ждать не стоит.


На таких скоростях даже «дешевое» шифрование с использованием AES-NI будет потреблять значительную количество CPU, которое можно было бы использовать в более нужных вещах. Насколько оно хорошо работает — это, конечно, вопрос.

имелось в виду не "будет ли работать", а "будет ли профит в случае множества относительно медленных клиентов", очевидно, что хранить состояние всех сессий в сетевой карте невозможно, не убьёт ли производительность то, что контекст придётся постоянно передавать в сетевую карту/из сетевой (что-то вроде context switch в OS).


хотя… сетевая карта имеет же доступ к памяти, наверное, эта проблема решаема (и даже уже решена).


Update: прочитал pdf от мелланокса


  • NIC holds the crypto state
  • NIC encrypts / decrypts packets on the fly
  • Cipher text is never held in RAM

всё-таки непонятно сколько одновременных соединений «вытянет» сетевая карта.


и да, в той статье есть таблица, где у kTLS без аппаратного ускорения производительность оказалась ниже, чем в userspace (это я возвращаюсь к вопросу "будет ли выигрыш если исходные данные в userspace")

имелось в виду не «будет ли работать», а «будет ли профит в случае множества относительно медленных клиентов», очевидно, что хранить состояние всех сессий в сетевой карте невозможно, не убьёт ли производительность то, что контекст придётся постоянно передавать в сетевую карту/из сетевой (что-то вроде context switch в OS).

Конкретно у Mellanox в их Crypto-enabled BlueField воткнут «64-bit Armv8 A72» на 16 ядер и 16GB оперативки. Всё это с отдельным интерконнектом в собственно сетевой чип, поэтому вполне можно держать все сессии. Быстро перепрограммировать сетевой чип из BlueField точно умеют, а про передавать контекст в карту/из карты — это в общем случае надо делать только на старте сессии. Карта умеет трекать TCP Seq Number, и TLS Record Number. Соответственно от ядра нужно только получать данные на отправку.
Тут, кстати, нашел доку по картам Chelsio. У них указывается «The typical T6 adapter supports 32K simultaneous TLS/SSLsessions.» — вполне неплохая цифра одновременных TLS соединений.
в случае «nginx проксирует и обеспечивает tls» выигрыша, думаю, ждать не стоит.

По первым тестам использование шифрования в ядре без использования sendfile() давало несколько процентов производительности, но сейчас подтвердить или опровергнуть эти данные не могу — не получается быстро найти статью с картинками сравнения.
А можно ссылочку на статью, где производительность Kernel TLS просела относительно user-space?
А можно ссылочку на статью, где производительность Kernel TLS просела относительно user-space?

так из вашей статьи и взял — доклад mellanox

Ну вы учитывайте что Mellanox-у нужно продавать свое железо с offload.
Поэтому сейлы Mellanox будут "накручивать" цифры всеми приемлемыми способами.
Например, выбирать для тестов версии ядра, комбинации опций и софта показывающие что без offload "жить нельзя".

Да, точно. Но тут сравнение с Gnu TLS c малым размером TLS Record, который умещается в один TCP пакет. Такое поведение не самое распространенное, и не позволяет использовать механизмы GSO и TSO в ядре. Ну и версия kTLS там правда очень древняя. Была еще статья, в которой сравнивался OpenSSL (кажется 1.1.0) в более честных условиях, там были изменения в обратную сторону, но незначительные

и да, в той статье есть таблица, где у kTLS без аппаратного ускорения производительность оказалась ниже, чем в userspace (это я возвращаюсь к вопросу «будет ли выигрыш если исходные данные в userspace»)

Это одна из первых статей, после этого в ядре было несколько итераций оптимизации кода AES. Но я не берусь утверждать, что стало сильно лучше, вероятнее всего при проксировании действительно профита видно не будет

Бонусов несколько.


Во-первых это развитие, приведение в порядок и оптимизация механизмов off-load. AES относительно дешево реализуется в железе, а перенос шифрования с CPU на NIC позволяет увеличить производительность отдачи контента в разы. На всякий стоит пояснить:


  • Когда шифрованием занимается CPU, то ему нужно (как минимум) прочитать данные из памяти, затем зашифровать и записать в память, а потом снова прочитать через DMA сетевой картой.
  • Если же шифрованием занимает NIC, то можно обойтись однократным чтением из памяти.
  • Т.е. утилизация RAM bandwidth получается в три раза меньше, и это не считая затрат CPU на само шифрование и управление буферами для зашифрованных данных. Соответственно, условный Netflix сможет раздавать со своих блейдов в три раза больше, и/или использовать менее мощные, более холодные и дешевые процессоры (ARM).

Без AES-offload в NIC выигрыш скромнее, но всё же есть. В основном за счет уменьшения кол-ва переключений между ядром и userspace — примерно также как при использовании "обычного" системного вызова sendfile.


Возможно vadimfedorenko стоит добавить эту инфу в статью.

Т.е. утилизация RAM bandwidth получается в три раза меньше, и это не считая затрат CPU на само шифрование и управление буферами для зашифрованных данных. Соответственно, условный Netflix сможет раздавать со своих блейдов в три раза больше, и/или использовать менее мощные, более холодные и дешевые процессоры (ARM)

ну тут вы утрируете, конечно, если бы скорость отдачи была равна (memory bandwidth)/3, все были бы счастливы )


но в целом согласен, некоторый выигрыш тут возможен. но, думается, что в реальной жизни он будет невелик — скорости отдачи несопоставимы с пропускной способностью памяти, для aes и в процессорах оффлоадилки есть.


Без AES-offload в NIC выигрыш скромнее, но всё же есть. В основном за счет уменьшения кол-ва переключений между ядром и userspace — примерно также как при использовании "обычного" системного вызова sendfile.

это только в том случае, если данные не проходят через userspace, а они зачастую таки проходят.


так-то понятно, что связка (sendfile/sockmap/etc) + ktls выглядит интересно с точки зрения производительности. и аппаратное шифрование тут будет актуально.


P.S. речь про то, что после прочтения статьи возникает ощущение «у меня есть nginx и есть tls — значит оно мне надо». а может оказаться, что не надо )

ну тут вы утрируете, конечно, если бы скорость отдачи была равна (memory bandwidth)/3, все были бы счастливы )

Есть разные сценарии.


К примеру, если у вас CDN большого масштаба, то ваша целевое состояние = минимальное кол-во работающих серверов с загрузкой ~95%.
Соответственно, в целевом (эффективном) состоянии, на таких серверах вы будите упираться либо в disk i/o (для "холодного" контента), либо в memory bandwidth (для "горячего" контента).


Конечно это не массовый сценарий, но в любом случае нормальный offload для AES действительно поднимает верхний предел отдачи в три раза. Это позволяет не только увидеть другие узкие места, но и делает осмысленным их устранение.

Зависит от CDN, но могу сказать, что CPU остается достаточно много. Больше баланс сетевой нагрузки и размера диска. Offload в NIC как таковой не нужен, потому что CPU именно и занимается шифрованием как раз.

Сильно зависит от количества обслуживающих серверов в PoP. Речь же идет о том, чтобы максимально раздавать с одного сервера, а не закатывать полные стойки серверов в IX.

Все правильно, естественно ресурсы должны максимально использоваться. Но ресурсов много. Память была упомянута выше. Я упомянул диски как одну из реальных проблем для большого CDN с большим количеством клиентов. Диски — не очень дешевое удовольствие тоже. Если разгрузить CPU, то придется другие вещи расширять. Но реально те же диски большего размера стоят дороже, к примеру.

Не хочу вступать в дискуссию, но если у вас чего-то остается много, то вы за это переплатили.


И на всякий уточню:


  • понятно, что далеко не всегда есть возможность не покупать лишнего, просто исходя из доступного спектра моделей и других обстоятельств.
  • в перспективе Mellanox (или еще кто-нибудь) смогут пустить offload в серию и снизить цены, соответственно блейды на ARM-ах станут дешевле и будут ближе к оптимуму (без лишних мощностей и холоднее).
  • чтобы это было возможно инфраструктуру offload в ядре нужно допиливать, что понемногу и происходит.
Я говорил к тому, что CPU на CDN особо ни для чего не используется. Поэтому смысл покупать CPU чтобы он простаивал. Там 80 ядер или сколько в сервере, почему бы им не заняться шифрованием?
Но абсолютно ясно, что не хочется доплачивать за что-то, что не используется. Но в реальности есть куча переменных, таких как размер дисков, количество клиентов, региональная нагрузка на определенном PoP-е, стратегия кэширования (например, стратегия кэширования видео сильно сказывается на вытеснении кэша). К этому добавляется неидеальность софта тоже.

Пропустил я этот тред. Конкретно на вопрос


в чём выгода от переноса шифрования в kernel-space?

про TLS handshakes мы с JackMonterey отвечали в https://netdevconf.info/0x14/session.html?talk-performance-study-of-kernel-TLS-handshakes (видео https://www.youtube.com/watch?v=THJ6zC1V10c). При том, что мы еще не закончили оптимизацию математики, уже виден прирост производительности на 80% относительно OpenSSL/Nginx, latency может быть до 4 раз меньше. В моей демо на Security Weekly https://www.youtube.com/watch?v=IxLB3aUAECk хендшейки на виртаулке в несколько раз становились быстрее.


Причин несколько: отсутсвие копирований, оптимизированная работа с памятью, отсутствие контекст свитчей. Ну и конечно, более новые алгоритмы криптографии тоже дают свой эфект.


Более подробно будем еще рассказывать на следующем HighLoad++ https://www.highload.ru/moscow/2020/abstracts/7085 и Linux Conf Au'21 https://linux.conf.au/schedule/presentation/64/

Интересно, надо вам статью так же в англоязычный интеренет закинуть
да, надеюсь будет время перевести

Что-то не работает KTLS на этом патченом nginx со свежерелизнутым openssl-3.0.0 (и с патченым тоже) ;(

в конфиге есть и sendfile on; и ssl_ktls on; все остальное по дефолту, ничего специфического нет.

$ssl_ktls_status в лог пишет прочерк (

user nginx nginx;
worker_processes auto;
##worker_cpu_affinity auto;
#thread_pool default threads=256 max_queue=1024;
#worker_rlimit_nofile 128000;
#timer_resolution 1ms;
#pcre_jit on;

error_log /var/log/nginx/error_log info;

events {
        worker_connections 1024;
        use epoll;
#       accept_mutex off;
}

http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        log_format main
                '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $bytes_sent '
                '"$http_referer" "$http_user_agent" '
                '"$gzip_ratio" "$ssl_ktls_status"';

        client_header_timeout 10m;
        client_body_timeout 10m;
        send_timeout 10m;

        connection_pool_size 256;
        client_header_buffer_size 1k;
        large_client_header_buffers 4 2k;
        request_pool_size 4k;

        gzip off;

        output_buffers 2 256k;
        postpone_output 1460;

#       aio                   threads=default;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        ssl_ktls on;

        keepalive_timeout 75 20;

        ignore_invalid_headers on;
        index index.html;

#ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
#ssl_session_cache shared:SSL:10m;
#ssl_session_timeout 30m;
#ssl_prefer_server_ciphers on;
#ssl_ciphers AES128:AES256:HIGH:!aNULL:!MD5;             # AES128 cause least CPU load


        server {
                listen *:80 default rcvbuf=32768 backlog=2048 reuseport deferred so_keepalive=5s:3:3;

                listen *:443 http2 ssl default rcvbuf=32768 backlog=2048 reuseport deferred so_keepalive=5s:3:3;
                server_name localhost;
                ssl_certificate test.crt;
                ssl_certificate_key test.crt;

                access_log /var/log/nginx/localhost.access_log main;
                error_log /var/log/nginx/localhost.error_log info;

                root /var/www/localhost/htdocs;
        }
}

ядро 5.10, с

CONFIG_TLS=y
CONFIG_TLS_DEVICE=y

и всеми возможными шифрами

Свежерелизнутый OpenSSL-3.0.0 поменял подход к включению этой фичи. Сейчас надо в явном виде включать эти опции при инициализации SSL context, тогда как изначально фича была "default on" с возможностью выключения. Соответствующие правки в форк nginx планирую, но скорее всего сразу после того, как OpenSSL 3.0.0 будет официально поддержан в nginx - upstream.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации