В данной статье покажу как собрать 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 от остатков OpenSSL

rm -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 от haproxy

rm -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

Комментарии (3)


  1. 13werwolf13
    13.08.2025 12:31

    несомненно интересная тема и полезная статья с примерами конфигов.. Но у меня задёргался глаз на этапе cp haproxy /usr/sbin/haproxy.. я бы руки оторвал.. по самую ж..
    эту тему обсуждали уже столько раз что разжёвывать уже сил нет.. ну хотя бы сюда заглянуть стоило бы для начала. ну или просто сдёрнуть родные спеки от вашего дистрибутива и поправив пару строчек собрать родной для дистрибутива пакет.. ну зачем так больно то?!


    1. ki11j0y Автор
      13.08.2025 12:31

      Действительно, я не стал паковать .deb, на это было две причины, характер статьи не подразумевает сборки deb и вторая рассказать про QUIC в контексте HA. Вариант make install заменил на копирование бинарного файла, для ранее установленного HA, который я бережено забекапил перед процедурой замены, это упростило задачи тестирования, т.к. все необходимые операции выполнил установщик haproxy(3.0) из репозитория, могу добавить сноску что это было сделано в рамках тестирования протокола и к продакшену такой метод не подходит.


      1. 13werwolf13
        13.08.2025 12:31

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