Files
hysteria2/README.md
T
Sergey Antropoff 0745fdce2c feat: incremental user passwords and export on update
Preserve passwords from server-info.yml and vault; generate only for new users; remove deleted users from output; re-export URL/QR only when password, domain, port, obfs or files changed.
2026-07-01 13:06:33 +03:00

13 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

make init
# отредактировать inventory/hosts.yml, group_vars/all.yml, vault

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

Makefile

Команда Описание
make help Справка
make init Создать конфиги из .example
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 Полное удаление Hysteria2 с VPS + output/<server>/ + пересборка output/index.html
make vault-encrypt Зашифровать vault
make vault-edit Редактировать vault
make install LIMIT=vps-de
make update LIMIT=vps-nl
make export
make uninstall LIMIT=vps-de
make uninstall LIMIT=vps-de EXTRA_VARS='hysteria2_uninstall_remove_local_output=false'
make install EXTRA_VARS='hysteria2_open_browser=false'
make update EXTRA_VARS='hysteria2_wait_for_acme=false'

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:

  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:

  1. Авто: Ansible password lookup (hysteria2_obfs_password_length) при первой установке
  2. При update/export: загружается из output/<server>/server-info.yml (как VPN-пароли)

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


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_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_generate_qr_png group PNG QR через qrencode
hysteria2_open_browser group Открыть output/index.html после экспорта
hysteria2_uninstall_remove_local_output group Удалить output/<server>/ при uninstall (по умолчанию true)
hysteria2_uninstall_rebuild_global_index group Пересобрать output/index.html после uninstall (по умолчанию true)
vault_hysteria2_obfs_passwords vault obfs-пароли по серверам

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

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

Требования

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

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

roles/hysteria2/
├── tasks/
│   ├── obfs.yml          ← генерация/загрузка obfs-пароля
│   ├── configure.yml     ← Salamander, без masquerade
│   ├── export.yml        ← URL, QR, HTML сервера
│   └── export_global.yml ← общий output/index.html
└── templates/
    ├── config.yaml.j2    ← acme tls + obfs salamander
    ├── client.yaml.j2    ← клиент с obfs
    └── export/           ← HTML-каталоги

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

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).