Hysteria2 на Debian 12: пошаговая установка
Классический OpenVPN и даже WireGuard в последние пару лет всё чаще режут по паттернам трафика, а не по IP — DPI видит характерный TCP- или UDP-хендшейк и глушит соединение ещё до того, как вы успели что-то скачать. Hysteria2 решает эту задачу иначе: он гоняет весь трафик через UDP поверх модифицированного QUIC с TLS-шифрованием и обфускацией Salamander, из-за чего со стороны это выглядит как обычный зашумлённый UDP-поток, а не как узнаваемый VPN-протокол. Дальше — пошагово: с нуля до рабочего сервера на Debian 12.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Hysteria2 и когда он оправдан
Hysteria2 (проект apernet/hysteria, вторая ветка протокола) — это не отдельный туннель поверх TCP, а собственный транспорт на базе QUIC с алгоритмом управления перегрузкой Brutal, заточенным под нестабильные и ограниченные по пропускной способности каналы. На практике это даёт три вещи, которых нет у WireGuard и OpenVPN:
- Весь трафик — UDP, обёрнутый в TLS 1.3, поэтому нет отдельного «сигнатурного» TCP-хендшейка VPN-протокола.
- Есть штатная маскировка (
masquerade) — если зайти на порт сервера обычным браузером, он отдаст страницу-прикрытие, а не откажет в соединении, как это делает WireGuard. - Есть отдельный слой обфускации Salamander — лёгкое XOR-подобное перемешивание пакетов поверх уже зашифрованного QUIC, цель которого — сбить активные DPI-классификаторы, которые ищут именно паттерн QUIC/Hysteria.
Важная оговорка сразу: Salamander — это обфускация, а не дополнительное шифрование. Она не защищает данные лучше, чем TLS внутри QUIC, её единственная задача — усложнить автоматическое опознавание протокола. В арсенале DPI-систем такие сигнатуры обновляются, и то, что работает сегодня, через полгода может потребовать доп. настройки. Если вам нужен максимально устойчивый протокол для активно фильтрующей сети, посмотрите также Xray с VLESS Reality — у него другая модель маскировки, и связка «одно на сервере, другое про запас» — рабочая практика.
Кому Hysteria2 подходит лучше всего: медленные или дорогие по трафику каналы (Brutal умеет держать заданную полосу без просадок TCP-подобного congestion control), мобильный интернет с частыми потерями пакетов, и сценарии, где UDP пропускается сетью охотнее, чем нестандартный TCP.
Подготовка Debian 12: зависимости и порт UDP
Hysteria2 распространяется одним статическим Go-бинарником, поэтому тяжёлых зависимостей не требует — нужны только базовые утилиты и открытый UDP-порт.
Обновите систему и поставьте минимальный набор инструментов:
apt update && apt upgrade -y
apt install -y curl openssl ufw
curl нужен для официального установочного скрипта, openssl — для самоподписанного сертификата, если не будете использовать ACME с реальным доменом, ufw — для управления файрволом (подробный разбор — в статье про настройку UFW на Debian 12).
Сразу решите, каким портом будет пользоваться сервер. По умолчанию в примерах используют 443/udp — это осознанный выбор: провайдеры и корпоративные сети реже блокируют трафик на 443-м порту целиком, потому что там же живёт HTTPS. Если 443 уже занят под веб-сервер по TCP — не страшно, TCP и UDP на одном номере порта не конфликтуют, это разные сокеты.
Откройте порт в файрволе заранее:
ufw allow 443/udp
ufw allow OpenSSH
ufw enable
Если сервер новый и у вас ещё нет SSH-доступа по ключу — сначала настройте его, это отдельная база безопасности: подключение по SSH-ключу на Debian 12.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверУстановка Hysteria2 и TLS-сертификат
Официальный способ установки — скрипт из репозитория проекта, который сам определяет архитектуру, скачивает нужный бинарник в /usr/local/bin/hysteria и раскладывает systemd-юниты:
bash <(curl -fsSL https://get.hy2.sh/)
Скрипт создаёт каталог /etc/hysteria/, шаблон config.yaml и два systemd-юнита: hysteria-server.service (использует /etc/hysteria/config.yaml) и шаблонный hysteria-server@.service, который позволяет держать несколько независимых конфигураций — hysteria-server@second.service будет читать /etc/hysteria/second.yaml. Проверьте, что бинарник встал и версия свежая:
hysteria version
Теперь сертификат. Есть два рабочих варианта.
Вариант 1 — есть домен. Дайте Hysteria2 включённый в него встроенный клиент ACME, он сам получит сертификат Let's Encrypt через HTTP-01 (нужен временно открытый 80/tcp) или через встроенный TLS-ALPN. В конфиге это блок acme — покажу его в следующем разделе. Домен для этого варианта не обязателен, но с ним проще и надёжнее с точки зрения TLS-fingerprint: сертификат настоящий, а не самоподписанный.
Вариант 2 — домена нет, работаем по IP. Тогда генерируете самоподписанный сертификат вручную:
mkdir -p /etc/hysteria
openssl req -x509 -nodes -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-keyout /etc/hysteria/key.pem -out /etc/hysteria/cert.pem \
-subj "/CN=bing.com" -days 3650
chown hysteria:hysteria /etc/hysteria/key.pem /etc/hysteria/cert.pem
При таком подходе клиент должен явно доверять этому сертификату (insecure: true / skip-cert-verify на стороне клиента) — сама TLS-сессия при этом всё равно шифрует данные, просто без цепочки доверия публичного CA. Это рабочий и распространённый вариант для личного использования, но для продакшена с несколькими пользователями домен и нормальный ACME-сертификат надёжнее.
Конфигурация сервера: config.yaml и обфускация Salamander
Откройте /etc/hysteria/config.yaml и замените содержимое. Вариант с самоподписанным сертификатом:
listen: :443
tls:
cert: /etc/hysteria/cert.pem
key: /etc/hysteria/key.pem
auth:
type: password
password: замените-на-длинный-случайный-пароль
masquerade:
type: proxy
proxy:
url: https://news.ycombinator.com
rewriteHost: true
obfs:
type: salamander
salamander:
password: замените-на-второй-случайный-пароль
bandwidth:
up: 200 mbps
down: 200 mbps
Если есть домен и хотите ACME вместо ручного сертификата, блок tls заменяется на:
acme:
domains:
- vpn.example.com
email: you@example.com
Разберём ключевые поля:
auth.password— основной пароль клиента, аналог PSK. Генерируйте случайно:openssl rand -base64 24.masquerade— что видит случайный посетитель, зашедший на ваш IP:443 браузером. Типproxyреверс-проксирует запрос на указанный сайт, так что при активном сканировании порт выглядит как обычный веб-ресурс, а не как «порт с VPN».obfs.salamander.password— отдельный пароль именно для слоя обфускации, не путайте его сauth.password. Должен совпадать на клиенте.bandwidth— ограничение полосы, которое сервер сообщает клиенту для настройки Brutal congestion control. Указывайте реальную полосу канала сервера, а не желаемую — заниженное значение душит скорость, завышенное приводит к потерям пакетов и просадкам под нагрузкой.
Значения полосы — это ориентир для congestion control, а не гарантированная скорость: реальная пропускная способность зависит от канала между клиентом и сервером, качества сети провайдера и текущей нагрузки, и у вас цифры почти наверняка будут другими.
Проверьте синтаксис конфига перед запуском:
hysteria server --config /etc/hysteria/config.yaml
Команда запустит сервер в foreground-режиме — если конфиг битый, вы сразу увидите ошибку парсинга в консоли. Убедившись, что сервер поднимается и слушает порт (Ctrl+C, чтобы остановить), переходите к systemd.
systemd-юнит и автозапуск
Установочный скрипт уже создал юнит, поэтому вручную ничего писать не нужно — достаточно включить и запустить сервис:
systemctl enable --now hysteria-server.service
systemctl status hysteria-server.service
Убедитесь, что статус active (running) и в логе нет повторяющихся ошибок биндинга порта или чтения сертификата:
journalctl -u hysteria-server.service -f
Если нужно несколько независимых инстансов на одном сервере (например, разные пароли для разных клиентов или разные порты), используйте шаблонный юнит: положите второй конфиг в /etc/hysteria/second.yaml и запустите systemctl enable --now hysteria-server@second.service. Каждый инстанс работает изолированно, со своим PID и своими логами.
После правки config.yaml сервис нужно перезапускать вручную — автоперечитывания на лету нет:
systemctl restart hysteria-server.service
Проверьте, что порт действительно слушается по UDP:
ss -lunp | grep hysteria
Клиент, проверка соединения и тюнинг UDP
Для быстрой проверки соберите ссылку в формате hysteria2://:
hysteria2://пароль@IP_сервера:443/?obfs=salamander&obfs-password=пароль_обфускации&insecure=1&sni=bing.com#my-server
insecure=1 нужен только для самоподписанного сертификата — для сертификата ACME его нужно убрать, иначе клиент не будет проверять цепочку доверия вообще. sni должен совпадать с CN, который вы указали при генерации сертификата (в примере выше — bing.com), либо с вашим доменом, если используете ACME.
Официальный клиент на Linux/macOS/Windows использует такой же конфиг-файл в YAML:
server: IP_сервера:443
auth: пароль
tls:
sni: bing.com
insecure: true
obfs:
type: salamander
salamander:
password: пароль_обфускации
socks5:
listen: 127.0.0.1:1080
Запуск: hysteria client --config client.yaml — поднимет локальный SOCKS5-прокси на 1080, через который можно тестировать соединение (curl -x socks5h://127.0.0.1:1080 https://ifconfig.me).
По UDP-производительности есть два практичных момента. Во-первых, увеличьте буферы приёма/передачи на сервере — Linux по умолчанию режет их до размера, который заметно снижает пропускную способность QUIC на высоких скоростях:
cat >> /etc/sysctl.conf <<'EOF'
net.core.rmem_max=2500000
net.core.wmem_max=2500000
EOF
sysctl -p
Во-вторых, не путайте это с BBR — BBR регулирует TCP-трафик и на сам QUIC-транспорт Hysteria2 не влияет, потому что там свой congestion control (Brutal). Включать BBR отдельно ради Hysteria2 смысла нет, но он не помешает для остального TCP-трафика сервера (SSH, веб-панели и т.д.).
Если после всех настроек соединение поднимается, но скорость заметно ниже заявленной в bandwidth, для начала проверьте реальную полосу канала между клиентом и сервером — часто узкое место не в Hysteria2, а в самом провайдере или промежуточной сети.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Почему именно UDP, а не TCP, ведь UDP чаще режут по QoS?
QUIC (и Hysteria2 поверх него) спроектирован под UDP из-за более быстрого хендшейка и отсутствия head-of-line blocking. Да, часть операторов режет полосу для «неопознанного» UDP при перегрузке сети, но полная блокировка UDP на 443 встречается реже, чем сигнатурная блокировка TCP-based VPN-протоколов.
Обязательно ли покупать домен?
Нет, можно работать по IP с самоподписанным сертификатом и insecure: true на клиенте — трафик всё равно шифруется TLS-сессией QUIC. Домен и ACME дают более правдоподобный TLS-отпечаток и упрощают ротацию сертификата, но не обязательны для личного использования.
Salamander защищает от блокировки сам по себе?
Нет, это слой обфускации против сигнатурного анализа, а не шифрование и не гарантия обхода. В регионах с активным DPI эффективность обфускации со временем меняется по мере обновления классификаторов на стороне блокировщика.
Можно ли раздавать доступ нескольким пользователям с разными паролями?
В базовой конфигурации auth.type: password — один общий пароль на всех. Для разных учётных записей на одном сервере используйте несколько инстансов через шаблонный юнит hysteria-server@.service с разными конфигами и портами, либо внешний auth.type: http/command с проверкой на своём бэкенде — это отдельная настройка, не входящая в базовую установку.
Как понять, что порт заблокировали именно по DPI, а не из-за банальной ошибки конфига?
Сначала исключите базовые причины: проверьте journalctl -u hysteria-server.service, статус ufw status, совпадение паролей и SNI на клиенте и сервере. Если сервис слушает порт, файрвол открыт, но клиент с другой сети подключается, а с проблемной сети — нет и без внятной ошибки TLS, это косвенный признак фильтрации на уровне сети, а не сервера.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →