В данной статье покажу как собрать HAProxy для поддержки «правильного» QUIC не в режиме совместимости, со сборкой OpenSSL 3.5 с подде ржкой QUIC в дистрибутивах с системным OpenSSL 3.0, с выходом Debian 13 задача упростилась, достаточно собрать только HAProxy, в дистрибутив уже встроен OpenSSL 3.5 с полной поддержкой QUIC для работы сервера. Далее буду сокращать HAProxy до HA.
Disclaimer — все ниже сказанное про установку сделано в качестве ускорения процесса тестирования протокола, для продакшена, лучше собрать deb пакет.
Подготовка к сборке
Для сборки нам потребуется установить базовые пакеты, так же установим HA из репозитория для удобства в дальнейшем:apt install -y build-essential libpcre2-dev zlib1g-dev libsystemd-dev liblua5.3-dev libssl-dev curl ca-certificates haproxy
Подготовим директорию для сборки и перейдем в нее:mkdir -p ~/build/openssl && cd ~/build
Сборка OpenSSL 3.5+QUIC
На момент написания последняя LTS версия OpenSSL 3.5.1 (обновился на OpenSSL 3.5.2)
Новые релизы можно проверить тут. Загрузим ее:curl -LO https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz
Распакуем и перейдем в директорию: tar xvf openssl-3.5.1.tar.gz && cd openssl-3.5.1
Создадим директорию для хранения библиотек OpenSSL:mkdir /opt/openssl-custom
Настроим сборку для полной поддержки QUIC и разместим OpenSSL отдельно от системных файлов добавив версию к директории: ./Configure enable-quic linux-x86_64 --prefix=/opt/openssl-custom/openssl-3.5.1
Запустим сборку:make -j"$(nproc)"
Установим в директорию OpenSSL:make install_sw
Для удобства создадим симлинк на openssl-3.5.1, в дальнейшем для сборки HA потребует пересоздать симлинк на новую версию OpenSSL при обновлении:ln -sfn /opt/openssl-custom/openssl-3.5.1 /opt/openssl-custom/openssl
Очистим build от остатков OpenSSLrm -rf ~/build/openssl*
Сборка HAProxy 3.2
На момент написания последняя LTS версия 3.2.3
Новые релизы можно посмотреть тут.
Загрузим релиз:curl -LO https://www.haproxy.org/download/3.2/src/haproxy-3.2.3.tar.gz
Распакуем и перейдем в директорию:tar xvf haproxy-3.2.3.tar.gz && cd haproxy-3.2.3
Соберем с использованием динамической библиотеки OpenSSL, и добавим модуль Prometheus:
make -j"$(nproc)" TARGET=linux-glibc \
USE_OPENSSL=1 USE_QUIC=1 USE_PROMEX=1 \
SSL_INC=/opt/openssl-custom/openssl/include SSL_LIB=/opt/openssl-custom/openssl/lib64 \
LDFLAGS="-Wl,-rpath=/opt/openssl-custom/openssl/lib64" \
USE_PCRE2=1 USE_ZLIB=1 \
USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib \
USE_SYSTEMD=1
Пользователям Debian 13 и аналогичных с поддержкой QUIC собирать OpenSSL не требуется, вся необходимая поддержка присутствует в системе, команда для сборки будет выглядеть иначе:
make -j"$(nproc)" TARGET=linux-glibc \
USE_OPENSSL=1 USE_QUIC=1 USE_PROMEX=1 \
USE_PCRE2=1 USE_ZLIB=1 \
USE_LUA=1 LUA_INC=/usr/include/lua5.3 LUA_LIB=/usr/lib \
USE_SYSTEMD=1
Проверим собранный HA:
Выполним ./haproxy -vv
, проверяем на +QUIC -QUIC_OPENSSL_COMPAT и версию OpenSSL
Далее выполним:ldd ./haproxy | grep ssl
Вывод должен ссылаться на openssl-custom.
Установка скомпилированного HA:
Остановим сервис:systemctl stop haproxy
Для начала скопируем оригинальный файл:cp /usr/sbin/haproxy /usr/sbin/haproxy.repo
Произведем замену:cp haproxy /usr/sbin/haproxy
Проверим используемые библиотеки для дистрибутивов без нативной поддержки QUIC:ldd /usr/sbin/haproxy | grep ssl
ldd /usr/sbin/haproxy | grep crypto
Если ссылается на /opt/openssl-custom/openssl/ значит все выполнено правильно.
Очистим build от haproxyrm -rf ~/build/haproxy*
Вывод команд
# ldd /usr/sbin/haproxy | grep ssl
libssl.so.3 => /opt/openssl-custom/openssl/lib64/libssl.so.3 (0x00007dd8efcf0000)
libcrypto.so.3 => /opt/openssl-custom/openssl/lib64/libcrypto.so.3 (0x00007dd8ef600000)
# ldd /usr/sbin/haproxy | grep crypto
libcrypto.so.3 => /opt/openssl-custom/openssl/lib64/libcrypto.so.3 (0x000072e226e00000)
Проверим версию: haproxy -vv
Вывод должен быть похож на такой(вывод не полный):
HAProxy version 3.2.3-1844da7 2025/07/09 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2030.
Known bugs: http://www.haproxy.org/bugs/bugs-3.2.3.html
Build options :
OPTIONS = USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1 USE_QUIC=1 USE_PROMEX=1 USE_PCRE2=1
Feature list : +OPENSSL +PROMEX +QUIC -QUIC_OPENSSL_COMPAT
Built with multi-threading support (MAX_TGROUPS=32, MAX_THREADS=1024, default=6).
Built with SSL library version : OpenSSL 3.5.1 1 Jul 2025
Running on SSL library version : OpenSSL 3.5.1 1 Jul 2025
QUIC: connection socket-owner mode support : yes
QUIC: GSO emission support : yes
Available multiplexer protocols :
quic : mode=HTTP side=FE mux=QUIC flags=HTX|NO_UPG|FRAMED
Здесь нас интересуют флаги: USE_QUIC=1 +OPENSSL +QUIC -QUIC_OPENSSL_COMPAT
SSL library version OpenSSL 3.5.1,
QUIC: connection socket-owner mode support : yes
QUIC: GSO emission support : yes
Available multiplexer protocols:
quic : mode=HTTP side=FE mux=QUIC flags=HTX|NO_UPG|FRAMED
Если все указанные флаги как на примере значит присутствует полная поддержка QUIC.
Теперь создадим базовый шаблон конфигурации для проверки, на порту 8080 будет доступен сервис статистики:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /var/run/haproxy/admin.sock level admin mode 660
stats timeout 30s
user haproxy
group haproxy
daemon
# Улучшенная безопастность и совместимость со старыми браузерами.
ssl-default-bind-curves X25519:prime256v1:secp384r1
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options prefer-client-ciphers ssl-min-ver TLSv1.2 #no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options ssl-min-ver TLSv1.2 #no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 40s
timeout client 1m
timeout server 1m
timeout tunnel 1h
timeout http-request 30s
frontend stats
bind *:8080
mode http
stats enable
stats uri /
stats refresh 10s
stats show-version
Теперь запустим командой:systemctl start haproxy
Проверим запуск:systemctl status haproxy
Подготовим frontend к интеграции QUIC
У меня есть такой frontend:
frontend http
bind [::]:80 v4v6
mode http
http-request redirect scheme https code 301 unless { ssl_fc }
frontend https
bind [::]:443 v4v6 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1 strict-sni
http-request reject if { req.hdr(user-agent) -m sub evil }
http-request deny if { path -m sub /. }
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains;"
use_backend http_site1 if { ssl_fc_sni -i example.ru }
Необходимо к нему добавить QUIC, есть два пути, вынести в отдельный frontend либо внести в существующий https frontend.
Ниже пример отдельно вынесенного frontend
frontend f_quic
bind quic4@:443 ssl crt /etc/haproxy/certs/ alpn h3 strict-sni ssl-min-ver TLSv1.3 allow-0rtt
bind quic6@:443 ssl crt /etc/haproxy/certs/ alpn h3 strict-sni ssl-min-ver TLSv1.3 allow-0rtt
http-request return status 200 content-type text/plain lf-string "Status 200 OK! Your IP %[src]." if { path /quic } { ssl_fc_alpn -i h3 }
use_backend http_site1 if { ssl_fc_sni -i example.ru }
quic4@:443 и quic6@:443 добавляет слушатель на порт 443 UDP
http-request return status 200 — вернет статус 200 если используется QUIC по пути example.ru/quic после проверки соответственно убрать данный ответ.
В любом варианте в frontend https необходимо добавить заголовок для объявления о наличии QUIC, что бы приложения понимали что можно обновить соединение, если с соединением будут проблемы произойдет откат на TCP:
http-after-response add-header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400'
Пример frontend https из примера выше с добавленным заголовком и QUIC:
frontend https
bind [::]:443 v4v6 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1 strict-sni
bind quic4@:443 ssl crt /etc/haproxy/certs/ alpn h3 strict-sni ssl-min-ver TLSv1.3 allow-0rtt
bind quic6@:443 ssl crt /etc/haproxy/certs/ alpn h3 strict-sni ssl-min-ver TLSv1.3 allow-0rtt
http-request reject if { req.hdr(user-agent) -m sub evil }
http-request deny if { path -m sub /. }
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains;"
http-after-response add-header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400'
use_backend http_site1 if { ssl_fc_sni -i example.ru }
Про TLS 1.3 0-RTT early data в QUIC/HTTP3 ( allow-0rtt )
TLS 1.3 позволяет клиенту сразу отправить данные вместе с первым пакетом ClientHello (0-RTT), не дожидаясь окончания рукопожатия.
Это ускоряет время отклика (нет лишнего round trip), но уязвимо для replay-атак, потому что эти данные могут быть воспроизведены злоумышленником на другом соединении.
HAProxy даёт ACL ssl_fc_has_early, которая выполняется, если клиент отправил «ранние» данные.
Для защиты от replay-атак можно добавить http-request wait-for-handshake if { ssl_fc_has_early }
— который заставляет HA отложить обработку запроса до окончания TLS-handshake.
Без данной директивы есть риск атак на 0-RTT, HA начнет обрабатывать 0-RTT до полного завершения handshake.
С данной директивой HA ждёт окончания handshake, прежде чем применять правила, что убирает риск, но может лишить 0-RTT прироста скорости.
На текущий момент анализировать 0-RTT на раннем этапе через QUIC не получится, директива ssl_fc_has_early работает только с TCP на раннем этапе, по этому с QUIC можем использовать только на этапе http.
Таблица безопасности HTTP-методов в контексте TLS 1.3 0-RTT early data и replay-атак
Метод | Назначение | Изменяет состояние сервера | Идемпотентный? | Риск при 0-RTT | Рекомендация |
---|---|---|---|---|---|
GET | Получение ресурса | ❌ | ✅ | Низкий | Разрешить |
HEAD | Получение заголовков без тела | ❌ | ✅ | Низкий | Разрешить |
OPTIONS | Узнать возможности/методы | ❌ | ✅ | Низкий | Разрешить |
TRACE | Эхо-запрос для диагностики | ❌ | ✅ | Низкий (но редко используется) | Можно разрешить или отключить вовсе |
POST | Создание/отправка данных | ✅ | ❌ | Высокий | Блокировать |
PUT | Полная замена ресурса | ✅ | ✅* | Высокий | Блокировать |
PATCH | Частичное обновление ресурса | ✅ | ❌ | Высокий | Блокировать |
DELETE | Удаление ресурса | ✅ | ✅* | Высокий | Блокировать |
CONNECT | Установление туннеля (обычно для HTTPS-прокси) | Может | ❌ | Средний/Высокий | Блокировать |
Добавим фильтрацию 0-RTT по IP и безопасным методам, для QUIC фильтрацию произведем на этапе HTTP в TCP IP-адреса можно отфильтровать на раннем этапе соединения, пример:
frontend https
...
tcp-request connection reject if { ssl_fc_has_early} !{ src -f /etc/haproxy/acl/ip.list }
...
http-request deny if { ssl_fc_has_early } !{ method GET HEAD OPTIONS TRACE }
...
frontend quic
...
# Отклоним любой 0-RRT для всех кроме IP списка и только если ALPN H3
http-request deny if { ssl_fc_has_early } { ssl_fc_alpn h3 } !{ src -f /etc/haproxy/acl/ip.list }
...
# Вариант 1, отклоним сразу все не безопасные методы через 0-RTT
http-request deny if { ssl_fc_has_early } !{ method GET HEAD OPTIONS TRACE }
...
# Вариант 2 мягкое отклонение через ожидание полного handshake для не безопасных методов
http-request wait-for-handshake if { ssl_fc_has_early } !{ method GET HEAD OPTIONS TRACE }
Фильтрация QUIC соединений
В статьях ранее (например тут) я писал как можно фильтровать TCP соединения по количеству, скорости открытия, IP адресам:
Пример для фильтрации по IP FireHol в TCP:
tcp-request connection reject if { src -f /etc/haproxy/firehol/level1.acl }
tcp-request connection reject if { src -f /etc/haproxy/firehol/level2.acl }
tcp-request connection reject if { src -f /etc/haproxy/firehol/level3.acl }
tcp-request connection reject if { src -f /etc/haproxy/firehol/abusers_1d.acl }
Для того что бы настроить такую же фильтрацию в QUIC с версии HAProxy 3.1 добавили новые функции:
quic-initial reject аналогичен tcp-request connection reject, отклоняет соединение QUIC до подтверждения TLS и отправит клиенту CONNECTION_REFUSED с кодом ошибки.
quic-initial dgram-drop равен tcp-request connection silent-drop, игнорирует все Initial пакеты QUIC
quic-initial dgram-drop if { src -f /etc/haproxy/firehol/level1.acl }
stick-table type ip size 10k expire 30s store conn_cur,conn_rate(5s)
quic-initial track-sc0 src
quic-initial reject if !{ src -f /etc/haproxy/acl/whiteip.acl } && { sc0_conn_cur gt 100 }
quic-initial reject if !{ src -f /etc/haproxy/acl/whiteip.acl } && { sc0_conn_rate gt 30 }
quic-initial dgram-drop — молча отбросит все запросы с IP адресов из списка.
stick-table добавляет анонимную таблицу для хранения IP и соединений.
{ src -f /etc/haproxy/acl/whiteip.acl } — добавляет список белых IP, параметр не обязательный, если нет списка, удалите его, иначе HA не запуститься.
{ sc0_conn_cur gt 100 } — счетчик общего кол-ва соединений с одного IP.
{ sc0_conn_rate gt 30 } — счетчик установления соединений(rate limit) с одного IP, лимит 30 соединений за 5сек.
Оператор ! — инвертирует значение.
Оператор && сработает только если IP не из списка и превышено значение счетчика, если IP будет в списке то оператор не сработает
Для ограничения лимитов для IP из списка можно использовать такой оператор:
quic-initial reject if { src -f /etc/haproxy/acl/whiteip.acl } && { sc0_conn_cur gt 200 }
quic-initial reject if { src -f /etc/haproxy/acl/whiteip.acl } && { sc0_conn_rate gt 100 }
На примере увеличили счетчики общего кол-ва подключений до 200, и rate limit до 100.
Все выше сказанное будет работать и в TCP, с параметром tcp-request connection reject
Как итог conn_cur защищает от висящих соединений с множеством открытых сессий например DDoS, а conn_rate защищает от всплесков подключений например флуд, перебор, лимиты потребуется настроить под свою нагрузку.
Тюнинг сервера и HA для работы с QUIC (при необходимости)
Первое что необходимо сделать увеличить лимиты UDP в ядре:nano /etc/sysctl.conf
В конец sysctl.conf добавляем следующие значения:
Для начала увеличим стандартный буфер до 208КБ добавив:net.core.rmem_default = 212992
net.core.wmem_default = 212992
Теперь увеличим максимальный до 4МБ:net.core.rmem_max=4194304
net.core.wmem_max=4194304
Теперь установим нижний размер буфера до 4КБ (чтобы маленькие пакеты не резервировали слишком много памяти):net.ipv4.udp_rmem_min=4096
net.ipv4.udp_wmem_min=4096
Оптимизируем очередь пакетов увеличив ее с 100 до 4096:net.core.netdev_max_backlog = 4096
Увеличим максимальное кол-во пакетов в очереди на входе:net.ipv4.netfilter.ip_conntrack_max = 262144
Установим алгоритм управления перегрузкой TCP — используем BBR:net.ipv4.tcp_congestion_control = bbr
Установим по умолчанию и максимумы для TCP буферов приёма и отправки (в байтах): net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 65536 4194304
Увеличение максимального размера очереди ожидающих входящих соединений: net.core.somaxconn = 65535
Включим повторное использования сокетов в состоянии TIME-WAIT для новых соединений: net.ipv4.tcp_tw_reuse = 1
Уменьшим временя ожидания FIN для более быстрого освобождения ресурсов:net.ipv4.tcp_fin_timeout = 15
Оптимизируем конфигурацию HA:
В конец строк bind quic4@ и bind quic6@ добавим использование BBR для QUIC:
quic-cc-algo bbr # Включим алгоритм BBR для QUIC соединений.
Так же дополнительно в конец секции global можно добавить (применять с осторожностью):
tune.ssl.cachesize 200000 # Установим размер кэша SSL сессий
tune.bufsize 16384 # Установим буфер в 16КБ для обработки одного пакета
tune.buffers.limit 65536 # Установим максимальное число выделяемых буферов.
tune.quic.frontend.max-tx-mem 64m # Установим максимальный размер памяти (64МБ) выделяемый под передачу QUIC.
maxconn 50000 # Установим максимальное число соединений.
Полный конфиг для sysctl.conf
net.core.rmem_default = 212992
net.core.wmem_default = 212992
net.core.rmem_max=4194304
net.core.wmem_max=4194304
net.ipv4.udp_rmem_min=4096
net.ipv4.udp_wmem_min=4096
net.core.netdev_max_backlog = 4096
net.ipv4.netfilter.ip_conntrack_max = 262144
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 65536 4194304
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
Заключение
На этом настройка прокси сервера и системы закончена, на выходе получили полностью рабочий QUIC протокол, HAProxy LTS последней версии, которой нет в репозиториях и стабильный OpenSSL 3.5 в качестве динамической библиотеки.
Следующий LTS релиз Ubuntu должен содержать и HA 3.2 и OpenSSL 3.5+quic и тогда QUIC войдет в массы, у меня такое видение.
Ремарка для пользователей xray
XHTTP способен работать через QUIC, для этого в секцию QUIC нужно добавить путь к XHTTP, а на клиенте выбрать h3,h2 в alpn подключения.
Не могу сказать как РКН отреагирует на трафик по QUIC и забанят ли ваш сервер/домен, внутри страны должно быть нормально, если использовать промежуточный сервер, от хостера QUIC с сервера в РФ спокойно доходит до сервера за бугром, однако все зависеть будет от хостера. По этому вариант с клиент XHTTP H3>сервер xray РФ>восходящие соединение XHTTP H3> сервер xray за бугром — пока работает, для QUIC потребуется более мощное железо, однако и скорость будет выше и задержка ниже. Для 100–200Мбит от хостера и сервера с 1 ядром, QUIC избыточен, TCP выдает более высокие показатели скорости.
Данная ремарка для тех кто обходит только зарубежные санкции, обход блокировок РКН может повлечь ответственность вплоть до уголовной.
Пример как завести XHTTP:
frontend f_https
bind [::]:443 v4v6 strict-sni ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
...
http-after-response add-header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400'
...
use_backend http_site1 if { ssl_fc_sni -i example.ru }
use_backend xray_xhttp if { req.hdr(Host) -i example.ru } { path_beg -i /yoursecretpath }
...
frontend f_quic
bind quic4@:443 ssl crt /etc/haproxy/certs/ alpn h3 strict-sni allow-0rtt ssl-min-ver TLSv1.3
bind quic6@:443 ssl crt /etc/haproxy/certs/ alpn h3 strict-sni allow-0rtt ssl-min-ver TLSv1.3
...
http-request wait-for-handshake if { ssl_fc_has_early }
...
use_backend http_site1 if { ssl_fc_sni -i example.ru }
use_backend xray_xhttp if { req.hdr(Host) -i example.ru } { path_beg -i /yoursecretpath }
...
backend xray_xhttp # через UNIX Socket
mode http
option forwardfor if-none
http-request add-header X-Real-Ip %[src]
http-request set-header Host %[req.hdr(Host)]
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Host %[req.hdr(host)]
retry-on conn-failure empty-response response-timeout
server xhttp1 /xui/xhttp.sock check
# Или
backend xray_xhttp # через порт
mode http
option forwardfor if-none
http-request add-header X-Real-Ip %[src]
http-request set-header Host %[req.hdr(Host)]
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Host %[req.hdr(host)]
server xhttp1 127.0.0.1:3333 send-proxy check
...
Использовать send-proxy не обязательно в контексте XHTTP/gRPC/WS/HttpUpgrade, достаточно указать правильные заголовки для передачи реального IP клиента и домена/хоста.
При использовании правильного набора шифров как на примере ниже, отпечаток JA3 будет похож на Chrome 80+ по этому в клиентах uTLS выбирать нужно Chrome, если раскомментировать no-tls-ticket то отпечаток не будет похож на Chrome.
Ссылка на конфигурацию
Конфигурация:
global
# intermediate configuration
ssl-default-bind-curves X25519:prime256v1:secp384r1
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options prefer-client-ciphers ssl-min-ver TLSv1.2 #no-tls-tickets
ssl-default-server-curves X25519:prime256v1:secp384r1
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options ssl-min-ver TLSv1.2 #no-tls-tickets
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl-dh-param-file /path/to/dhparam
ssl-dh-param-file вам нужно сгенерировать, или на сервере или с сайта mozilla, или использовать параметр tune.ssl.default-dh-param 2048