Hysteria2 Ansible — ветка main

Ветка: main
Режим: masquerade — маскировка под HTTPS-сайт nginx
Альтернатива: salamander — обфускация Salamander для агрессивного DPI

Ansible-роль для установки Hysteria 2 на Debian/Ubuntu VPS: Let's Encrypt, masquerade под nginx, несколько пользователей, экспорт URL/QR и HTML-каталог.


Выбор ветки: 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

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

  • нужен нормальный HTTPS-сайт при открытии домена в браузере;
  • достаточно маскировки под nginx;
  • хотите минимум параметров в URI клиента;
  • провайдер не «палит» Hysteria/QUIC внутри TLS.

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

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

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

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

# 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 Установка masquerade + экспорт 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
          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.


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

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

listen: 0.0.0.0:443

acme:
  type: http
  domains:
    - vpn-de.example.com
  email: admin@example.com

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

masquerade:
  type: file
  file:
    dir: /var/www/masq
  listenHTTP: :80
  listenHTTPS: :443
  forceHTTPS: true

Сайт-заглушка

В /var/www/masq/index.html — официальная страница Welcome to nginx!
При открытии домена в браузере — валидный HTTPS-сайт с Let's Encrypt.

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

server: vpn-de.example.com:443
auth: my:password

URI (пример)

hysteria2://my:password@vpn-de.example.com:443#my

Роль вызывает hysteria share — URI и QR формируются автоматически.


Пароли VPN-пользователей

  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, если домен/порт не менялись);
  • новые получают автогенерацию и полный экспорт;
  • удалённые из inventory убираются из конфига Hysteria2 и из output/<server>/.

Принудительно перевыпустить URL/QR для всех: hysteria2_force_export: truegroup_vars/all.yml или EXTRA_VARS).

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=<хост>.

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


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

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

Перед make install / make update на control node (ваш Mac):

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

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

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

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

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

  • бинарник /usr/local/bin/hysteria и unit-файлы systemd;
  • /etc/hysteria/ (конфиг и ACME);
  • /var/lib/hysteria и пользователь hysteria;
  • /var/www/masq (сайт-заглушка, ветка main);
  • symlink'и multi-user.target.wants/hysteria-server*;
  • временные /tmp/hysteria-client-*.yaml;
  • правила ufw, добавленные при install;
  • пакеты 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 делает это сам.

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

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

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


Firewall

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

  • 80/tcp — ACME HTTP + masquerade HTTP
  • 443/tcp — HTTPS masquerade
  • 443/udp — Hysteria2

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

output/
├── index.html                 ← все серверы (открывается в браузере)
├── vps-de/
│   ├── index.html             ← страница сервера
│   ├── my.url
│   ├── my.png                 ← QR PNG
│   ├── my.qr.txt             ← QR ASCII
│   ├── my.txt
│   └── server-info.yml
└── vps-nl/
    └── ...

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

  • пароль и 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_domain host Домен с A-записью на IP
hysteria2_users host Список имён VPN-пользователей
hysteria2_acme_email group Email для Let's Encrypt
hysteria2_user_passwords host/vault Фиксированные пароли VPN (vars.yml + vault)
hysteria2_password_length group Длина автогенерируемого пароля (40)
hysteria2_force_export group Перегенерировать URL/QR для всех (false по умолчанию)
hysteria2_output_dir group Папка экспорта (./output)
hysteria2_output_name host Подпапка экспорта (inventory_hostname)
hysteria2_listen_port group Порт Hysteria2 (443)
hysteria2_upgrade_system group apt upgrade перед install (true)
hysteria2_configure_firewall group Открыть порты в ufw (true)
hysteria2_generate_qr_png group PNG QR через qrencode
hysteria2_wait_for_acme group Пауза при первом ACME (install)
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-пароли по серверам

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


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

  • output/ содержит пароли и URL — не коммитить.gitignore)
  • inventory/hosts.yml, vault.yml, .vault_pass — не коммитить
  • После make init выполните make vault-encrypt

Требования

  • Control node: macOS или Linux с Ansible 2.14+ (brew install ansible на Mac)
  • VPS: Debian/Ubuntu с sudo
  • Домен с A-записью на IP сервера
  • Порты 80/tcp и 443/tcp+udp доступны с интернета (ветка main)
  • Для авто-открытия браузера: macOS (open) или Linux (xdg-open)

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

roles/hysteria2/
├── defaults/
│   ├── main.yml              ← основные переменные
│   └── uninstall.yml         ← переменные удаления
├── files/
│   └── install_server.sh     ← официальный скрипт (синхронизация с get.hy2.sh)
├── tasks/
│   ├── main.yml              ← порядок задач и теги
│   ├── validate.yml
│   ├── users.yml             ← пароли (inventory / vault / server-info.yml)
│   ├── sync_install_script.yml
│   ├── install.yml           ← пакеты, бинарник
│   ├── configure.yml         ← masquerade + ACME + ufw
│   ├── update.yml            ← обновление бинарника
│   ├── export_prepare.yml    ← инкрементальный экспорт
│   ├── export.yml            ← URL, QR, HTML сервера
│   ├── export_global.yml     ← общий output/index.html
│   ├── share_user.yml
│   ├── reuse_export_user.yml
│   └── uninstall.yml
└── templates/
    ├── config.yaml.j2        ← acme http + masquerade file
    ├── client.yaml.j2
    ├── masq/index.html.j2
    └── export/               ← HTML-каталоги

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

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

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

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

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

S
Description
Ansible-роль для установки Hysteria 2 на Debian/Ubuntu VPS по методике с маскировкой под свой сайт (ACME + masquerade file) или с Salamander obfs - когда masquerade под «обычный сайт» недостаточен и DPI у вашего "провайдера" совсем жестит.
https://devops.org.ru
Readme 128 KiB
Languages
Shell 48.2%
Jinja 41.8%
Makefile 10%