Files
hysteria2/README.md
T
Sergey Antropoff 2568c2acdf docs: LIMIT при добавлении сервера и force_export в README
Описано, что make install LIMIT не трогает старые VPS и как принудительно
перевыпустить URL/QR через hysteria2_force_export.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 13:37:53 +03:00

19 KiB
Raw Blame History

Hysteria2 Ansible — ветка Salamander

Ветка: salamander
Режим: Salamander obfs — запутывание пакетов для обхода DPI
Основная ветка: main — masquerade под HTTPS-сайт nginx

Ansible-роль для установки Hysteria 2 на Debian/Ubuntu VPS с Salamander obfs — когда masquerade под «обычный сайт» недостаточен.


Выбор ветки: main или salamander

main salamander (эта ветка)
Маскировка HTTPS-сайт nginx + Let's Encrypt Salamander obfs — пакеты выглядят как шум
Порт 80/tcp Нужен (ACME HTTP + masquerade) Не нужен
ACME type: http type: tls (TLS-ALPN на 443)
Сайт-заглушка /var/www/masq (nginx welcome) Нет
Obfs-пароль Обязателен (один на сервер)
URI клиента hysteria2://user:pass@domain:443 + obfs=salamander&obfs-password=...
Лучше когда Нужен «легитимный» сайт в браузере Агрессивный DPI, блокировка QUIC fingerprint

Когда выбирать salamander

  • masquerade из main блокируют или распознают по fingerprint;
  • не нужен фейковый сайт в браузере;
  • готовы хранить дополнительный obfs-пароль.

Когда выбирать main

  • нужен нормальный HTTPS-сайт при открытии домена;
  • достаточно маскировки под nginx;
  • хотите минимум параметров в URI клиента.

Быстрый старт

git clone https://git.antropoff.ru/DevOpsTools/hysteria2.git
cd hysteria2
git checkout salamander

# macOS: установить Ansible (если ещё нет)
brew install ansible

make init
# отредактировать:
#   inventory/hosts.yml
#   group_vars/all.yml
#   group_vars/hysteria2_servers/vault.yml
#   group_vars/hysteria2_servers/vars.yml  (проброс vault → роль)

make vault-encrypt
make ping
make install    # → output/index.html откроется в браузере

После make init создаются локальные файлы из .example (не коммитятся). Пароль vault хранится в .vault_pass.


Makefile

Команда Описание
make help Справка
make init Создать конфиги из .example и .vault_pass
make check Проверить синтаксис playbook
make ping Проверить SSH к VPS
make status systemctl status hysteria-server
make install Установка Salamander + экспорт URL/QR/HTML
make update Обновить бинарник и конфиг; экспорт только для новых/изменённых пользователей
make export Только экспорт (URL, QR, HTML) без изменений на сервере
make uninstall Полное удаление с VPS + output/<server>/ + пересборка output/index.html
make vault-init Создать .vault_pass, включить vault_password_file в ansible.cfg
make vault-encrypt Зашифровать vault.yml
make vault-edit Редактировать vault (редактор nano, см. EDITOR в Makefile)
make vault-view Показать расшифрованный vault
make install LIMIT=vps-de
make install LIMIT=vps-nl                    # только новый сервер — старые не трогаются
make update LIMIT=vps-nl
make export
make uninstall LIMIT=vps-de
make update EXTRA_VARS='hysteria2_force_export=true'   # перевыпустить URL/QR для всех
make install EXTRA_VARS='hysteria2_force_export=true'  # то же при install
make install EXTRA_VARS='hysteria2_open_browser=false'
make update EXTRA_VARS='hysteria2_wait_for_acme=false'

LIMIT — имя хоста из inventory/hosts.yml (например vps-de).


Inventory

all:
  children:
    hysteria2_servers:
      hosts:
        vps-de:
          ansible_host: 203.0.113.10
          ansible_port: 2222              # SSH-порт (если не 22)
          ansible_user: root
          ansible_password: "{{ vault_ssh_passwords['vps-de'] }}"
          hysteria2_domain: vpn-de.example.com   # для TLS/SNI и ACME
          hysteria2_users:
            - my
            - friend

        vps-nl:
          ansible_host: 203.0.113.20
          ansible_user: root
          ansible_password: "{{ vault_ssh_passwords['vps-nl'] }}"
          hysteria2_domain: vpn-nl.dynu.net
          hysteria2_users:
            - alice
            - bob

SSH (VPS)

Параметр Где Описание
ansible_host inventory IP VPS
ansible_port inventory SSH-порт (по умолчанию 22)
ansible_user inventory Пользователь SSH (обычно root)
ansible_password inventory + vault Пароль из vault_ssh_passwords
ansible_ssh_private_key_file inventory Альтернатива — SSH-ключ
# group_vars/hysteria2_servers/vault.yml
vault_ssh_passwords:
  vps-de: "root-password-1"
  vps-nl: "root-password-2"

Ключи в vault_ssh_passwords совпадают с именами хостов в inventory.


Как работает Salamander в этом проекте

Сервер (/etc/hysteria/config.yaml)

listen: 0.0.0.0:443

acme:
  type: tls                    # сертификат без порта 80
  domains:
    - vpn-de.example.com
  email: admin@example.com

auth:
  type: userpass
  userpass:
    my: "..."
    friend: "..."

obfs:
  type: salamander
  salamander:
    password: "общий_obfs_пароль_сервера"

Клиент (генерируется автоматически)

server: vpn-de.example.com:443
auth: my:password
obfs:
  type: salamander
  salamander:
    password: общий_obfs_пароль_сервера

URI (пример)

hysteria2://my:password@vpn-de.example.com:443?obfs=salamander&obfs-password=OBFS_PASS#my

Роль вызывает hysteria share — URI и QR уже содержат параметры Salamander.


Пароли

VPN-пользователи (userpass)

  1. Vault (рекомендуется):
vault_hysteria2_user_passwords:
  vps-de:
    friend: "Aingae0Okit1eek4eeZahFohVei4akee"

Подключается через group_vars/hysteria2_servers/vars.yml:

hysteria2_user_passwords: "{{ vault_hysteria2_user_passwords[inventory_hostname] | default({}) }}"
  1. Per-host в inventory:
hysteria2_user_passwords:
  friend: "custom-password"
  1. Автогенерация — Ansible password lookup, если пароль не задан ни в inventory/vault, ни в output/<server>/server-info.yml.

При make update / make export:

  • существующие пользователи сохраняют пароли из server-info.yml (и URL/QR, если домен/порт/obfs не менялись);
  • новые получают автогенерацию и полный экспорт;
  • удалённые из inventory убираются из конфига Hysteria2 и из output/<server>/.

Salamander obfs (один на сервер)

  1. Vault (рекомендуется):
vault_hysteria2_obfs_passwords:
  vps-de: "cry_me_a_r1ver_salamander_obfs"

Подключается через group_vars/hysteria2_servers/vars.yml:

hysteria2_obfs_password: "{{ vault_hysteria2_obfs_passwords[inventory_hostname] | default('') }}"
  1. Авто: Ansible password lookup (hysteria2_obfs_password_length) при первой установке
  2. При update/export: загружается из output/<server>/server-info.yml (как VPN-пароли)

Важно: obfs-пароль на сервере и клиенте должен совпадать. При make update без vault пароль сохраняется из предыдущего экспорта.

Принудительно перевыпустить URL/QR для всех VPN-пользователей: hysteria2_force_export: true.

make install EXTRA_VARS='hysteria2_force_export=true'
make update LIMIT=vps-de EXTRA_VARS='hysteria2_force_export=true'

Добавить второй VPS

После make install на первом сервере можно добавить ещё один хост в inventory/hosts.yml.

Без LIMIT make install пройдёт по всем серверам из inventory. На уже установленном пароли и файлы URL/QR не перегенерируются (берутся из output/<server>/server-info.yml), если вы не меняли его hysteria2_users, домен или порт.

Чтобы не трогать уже работающий VPS и экспорт:

make install LIMIT=новый-сервер

LIMIT — имя нового хоста из inventory (например vps-nl).

Добавить / удалить пользователя

  1. Отредактируйте hysteria2_users в inventory/hosts.yml.
  2. Запустите make update LIMIT=<хост>.

Пароли и obfs существующих клиентов не меняются (из server-info.yml).
Новому пользователю генерируется пароль и создаются URL/QR с параметрами Salamander.
Удалённый пользователь пропадает из конфига и из output/<server>/.


Установка бинарника Hysteria2

Официальный скрипт install_server.sh хранится в roles/hysteria2/files/.

Перед make install / make update на control node:

  1. Скачивается копия с https://get.hy2.sh/
  2. Сравнивается SHA256 с локальным файлом в роли
  3. При отличии — локальная копия обновляется
  4. Скрипт копируется на VPS и запускается оттуда

make update — что меняется

Компонент Поведение
Бинарник hysteria Обновляется (install_server.sh --force)
/etc/hysteria/config.yaml Перекатывается (auth + obfs)
Пароли VPN / obfs Сохраняются для существующей конфигурации
URL / QR Только для новых, изменённых или при hysteria2_force_export=true
apt upgrade Не выполняется
Ожидание ACME Не выполняется

make uninstall — полная очистка

На VPS (официальный install_server.sh --remove + дочистка Ansible):

  • бинарник /usr/local/bin/hysteria и unit-файлы systemd;
  • /etc/hysteria/ (конфиг и ACME);
  • /var/lib/hysteria и пользователь hysteria;
  • symlink'и multi-user.target.wants/hysteria-server*;
  • временные /tmp/hysteria-client-*.yaml;
  • правила ufw: 443/tcp, 443/udp (порт из hysteria2_listen_port);
  • пакеты curl, micro, qrencode.

На control node:

  • удаляется output/<имя_сервера>/;
  • пересобирается общий output/index.html (сервер убирается из списка; при LIMIT=... тоже);
  • если серверов не осталось — output/index.html удаляется.

Let's Encrypt — обновление сертификата

Да, Hysteria2 обновляет сертификат автоматически.

При блоке acme: в конфиге встроенный ACME-клиент Hysteria2 сам получает и продлевает сертификат Let's Encrypt (срок ~90 дней). Повторный make install или certbot для продления не нужны — процесс hysteria-server делает это сам.

Условия для авто-продления (ветка salamander):

  • сервер запущен и доступен из интернета;
  • домен указывает на IP VPS;
  • порт 443/tcp открыт (ACME TLS-ALPN challenge);
  • конфиг acme не удалён.

Проверка логов: journalctl -u hysteria-server -f


Firewall

По умолчанию открываются только порты Hysteria2:

  • 443/tcp
  • 443/udp

Порт 80 не используется — в отличие от ветки main.


Результат: папка output/

output/
├── index.html                 ← все серверы (открывается в браузере)
├── vps-de/
│   ├── index.html             ← страница сервера + obfs-пароль
│   ├── my.url                 ← URI с obfs=salamander
│   ├── my.png                 ← QR PNG
│   ├── my.qr.txt             ← QR ASCII
│   ├── my.txt
│   └── server-info.yml        ← mode, obfs_password, users
└── vps-nl/
    └── ...

HTML-страницы показывают:

  • режим Salamander и obfs-password с кнопкой копирования;
  • пароль и URL каждого пользователя;
  • QR-коды;
  • ссылки на файлы и страницы серверов.

После make install, make update и make export output/index.html автоматически открывается в браузере (macOS: open, Linux: xdg-open).

Отключить: hysteria2_open_browser: false в group_vars/all.yml или EXTRA_VARS.


QR-коды

PNG генерируются средствами Ansible (без Python):

  1. apt install qrencode на VPS (остаётся установленным)
  2. qrencode -o user.png "hysteria2://..."
  3. fetch — скачивание PNG на control node

ASCII QR — hysteria share --qruser.qr.txt.


Переменные

Переменная Где Описание
hysteria2_mode defaults salamander (информативно)
hysteria2_domain host Домен для TLS/SNI/ACME
hysteria2_users host VPN-пользователи
hysteria2_acme_email group Email Let's Encrypt
hysteria2_user_passwords host/vault Фиксированные пароли VPN
hysteria2_password_length group Длина автопароля VPN (40)
hysteria2_force_export group Перегенерировать URL/QR для всех (false)
hysteria2_obfs_password host/vault Пароль Salamander (или авто)
hysteria2_obfs_password_length group Длина автопароля obfs (32)
hysteria2_output_dir group Папка экспорта (./output)
hysteria2_listen_port group Порт (443)
hysteria2_upgrade_system group apt upgrade перед install
hysteria2_configure_firewall group Открыть порты в ufw
hysteria2_generate_qr_png group PNG QR через qrencode
hysteria2_wait_for_acme group Пауза при первом ACME
hysteria2_open_browser group Открыть output/index.html после экспорта
hysteria2_uninstall_rebuild_global_index group Пересобрать output/index.html после uninstall (true)
vault_ssh_passwords vault SSH-пароли root
vault_hysteria2_user_passwords vault VPN-пароли по серверам
vault_hysteria2_obfs_passwords vault obfs-пароли по серверам

Полный список: roles/hysteria2/defaults/main.yml, defaults/uninstall.yml.


Безопасность

  • output/ содержит пароли, obfs-ключи и URL — не коммитить.gitignore)
  • inventory/hosts.yml, vault.yml, .vault_pass — не коммитить
  • После make init выполните make vault-encrypt
  • Salamander не делает вас невидимым: IP VPS и UDP-поток всё ещё можно анализировать

Требования

  • Control node: macOS или Linux с Ansible 2.14+ (brew install ansible на Mac)
  • VPS: Debian/Ubuntu с sudo
  • Домен с A-записью на IP (для ACME TLS)
  • Порт 443/tcp+udp доступен с интернета
  • Клиент Hysteria2 с поддержкой Salamander (Shadowrocket, NekoBox, Hiddify и др.)
  • Для авто-открытия браузера: macOS (open) или Linux (xdg-open)

Структура роли

roles/hysteria2/
├── defaults/
│   ├── main.yml
│   └── uninstall.yml
├── files/
│   └── install_server.sh
├── tasks/
│   ├── main.yml
│   ├── validate.yml
│   ├── users.yml
│   ├── obfs.yml              ← пароль Salamander obfs
│   ├── sync_install_script.yml
│   ├── install.yml
│   ├── configure.yml         ← Salamander, без masquerade
│   ├── update.yml
│   ├── export_prepare.yml
│   ├── export.yml
│   ├── export_global.yml
│   ├── share_user.yml
│   ├── reuse_export_user.yml
│   └── uninstall.yml
└── templates/
    ├── config.yaml.j2        ← acme tls + obfs salamander
    ├── client.yaml.j2
    └── export/

Переключение между ветками

git fetch origin
git checkout main        # masquerade + nginx
git checkout salamander  # Salamander obfs (эта ветка)

Конфиги на уже установленном сервере не меняются при переключении ветки в git.
Чтобы применить другой режим на VPS:

git checkout main         # или salamander
make install              # перекатит конфиг сервера
# или
make update

Переключение режима меняет /etc/hysteria/config.yaml на сервере. Клиентские URI/QR нужно перевыпустить (make export или make update).