diff --git a/README.md b/README.md index 6fe7373..731d64c 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,57 @@ -# Ansible-роль: Hysteria2 Server +# Hysteria2 Ansible — ветка **main** -Ansible-роль для установки [Hysteria 2](https://v2.hysteria.network/) на Debian/Ubuntu VPS: ACME-сертификат, masquerade под nginx, несколько пользователей, экспорт URL/QR и HTML-каталог. +> **Ветка:** `main` +> **Режим:** **masquerade** — маскировка под HTTPS-сайт nginx +> **Альтернатива:** [`salamander`](https://git.antropoff.ru/DevOpsTools/hysteria2/src/branch/salamander) — обфускация Salamander для агрессивного DPI + +Ansible-роль для установки [Hysteria 2](https://v2.hysteria.network/) на 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-пароль. + +--- ## Быстрый старт ```bash -cd ~/Разработка/hysteria2 +git clone https://git.antropoff.ru/DevOpsTools/hysteria2.git +cd hysteria2 +git checkout main -make init # inventory, group_vars, vault, .vault_pass -# отредактировать: -# inventory/hosts.yml -# group_vars/all.yml -# group_vars/hysteria2_servers/vault.yml +make init +# отредактировать inventory/hosts.yml, group_vars/all.yml, vault -make vault-encrypt # зашифровать пароли VPS -make ping # проверить SSH -make install # установка → output/ → браузер откроется сам +make vault-encrypt +make ping +make install # → output/index.html откроется в браузере ``` +--- + ## Makefile | Команда | Описание | @@ -26,23 +60,24 @@ make install # установка → output/ → браузер отк | `make init` | Создать конфиги из `.example` | | `make ping` | Проверить SSH к VPS | | `make status` | `systemctl status hysteria-server` | -| `make install` | Установка + экспорт + `output/index.html` + открытие в браузере | +| `make install` | Установка masquerade + экспорт URL/QR/HTML | | `make update` | Обновить бинарник, конфиг, перевыпустить экспорт | -| `make export` | Только экспорт URL/QR/HTML | +| `make export` | Только экспорт (URL, QR, HTML) | | `make uninstall` | Удалить Hysteria2 с VPS | | `make vault-encrypt` | Зашифровать vault | | `make vault-edit` | Редактировать vault | -### Примеры - ```bash make install LIMIT=vps-de make update LIMIT=vps-nl make export make uninstall LIMIT=vps-de EXTRA_VARS='hysteria2_uninstall_remove_local_output=true' -make install EXTRA_VARS='hysteria2_open_browser=false' # без авто-открытия браузера +make install EXTRA_VARS='hysteria2_open_browser=false' +make update EXTRA_VARS='hysteria2_wait_for_acme=false' ``` +--- + ## Inventory ```yaml @@ -70,7 +105,7 @@ all: - bob ``` -### SSH-подключение к VPS +### SSH (VPS) | Параметр | Где | Описание | |---|---|---| @@ -78,7 +113,7 @@ all: | `ansible_port` | inventory | SSH-порт (по умолчанию `22`) | | `ansible_user` | inventory | Пользователь SSH (обычно `root`) | | `ansible_password` | inventory + vault | Пароль из `vault_ssh_passwords` | -| `ansible_ssh_private_key_file` | inventory | Альтернатива паролю — SSH-ключ | +| `ansible_ssh_private_key_file` | inventory | Альтернатива — SSH-ключ | ```yaml # group_vars/hysteria2_servers/vault.yml @@ -89,9 +124,61 @@ vault_ssh_passwords: Ключи в `vault_ssh_passwords` совпадают с **именами хостов** в inventory. +--- + +## Как работает masquerade в этом проекте + +### Сервер (`/etc/hysteria/config.yaml`) + +```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. + +### Клиент (генерируется автоматически) + +```yaml +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** (рекомендуется): +1. **Vault (рекомендуется):** ```yaml vault_hysteria2_user_passwords: @@ -99,7 +186,12 @@ vault_hysteria2_user_passwords: friend: "Aingae0Okit1eek4eeZahFohVei4akee" ``` -2. **Per-host в inventory**: +Подключается через `group_vars/hysteria2_servers/vars.yml`: + +```yaml +``` + +2. **Per-host в inventory:** ```yaml hysteria2_user_passwords: @@ -110,43 +202,62 @@ hysteria2_user_passwords: При `make update` пароли подтягиваются из `output//server-info.yml`, если не указаны в vault/inventory. +--- + +## 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 ← общий каталог всех серверов (открывается в браузере) +├── index.html ← все серверы (открывается в браузере) ├── vps-de/ -│ ├── index.html ← страница сервера +│ ├── index.html ← страница сервера │ ├── my.url -│ ├── my.png ← QR PNG -│ ├── my.qr.txt ← QR ASCII +│ ├── my.png ← QR PNG +│ ├── my.qr.txt ← QR ASCII │ ├── my.txt │ └── server-info.yml └── vps-nl/ └── ... ``` -### HTML-страницы +HTML-страницы показывают: -**`output/index.html`** — общий каталог: -- все серверы и пользователи на одной странице -- навигация по серверам -- поля ссылки/пароля с кнопкой копирования -- QR-коды -- ссылки на файлы и страницы серверов - -**`output//index.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`. -```yaml -# group_vars/all.yml -hysteria2_open_browser: false -``` - -Или: `make install EXTRA_VARS='hysteria2_open_browser=false'` +--- ## QR-коды @@ -158,6 +269,8 @@ PNG генерируются средствами Ansible (без Python): ASCII QR — `hysteria share --qr` → `user.qr.txt`. +--- + ## Переменные | Переменная | Где | Описание | @@ -168,19 +281,64 @@ ASCII QR — `hysteria share --qr` → `user.qr.txt`. | `hysteria2_user_passwords` | host/vault | Свои пароли VPN | | `hysteria2_output_dir` | group | Папка экспорта (по умолчанию `./output`) | | `hysteria2_output_name` | host | Имя подпапки (по умолчанию `inventory_hostname`) | +| `hysteria2_listen_port` | group | Порт Hysteria2 (443) | | `hysteria2_generate_qr_png` | group | PNG QR через `qrencode` | | `hysteria2_open_browser` | group | Открыть `output/index.html` после экспорта | | `hysteria2_uninstall_remove_local_output` | extra-vars | Удалить `output//` при uninstall | +--- + ## Безопасность -- `output/` содержит пароли и URL — в `.gitignore` +- `output/` содержит пароли и URL — **не коммитить** (в `.gitignore`) - `inventory/hosts.yml`, `vault.yml`, `.vault_pass` — не коммитить - После `make init` выполните `make vault-encrypt` +--- + ## Требования - Ansible 2.14+ - Debian/Ubuntu VPS с sudo - Домен с A-записью на IP сервера - Для авто-открытия браузера: macOS или Linux с `xdg-open` + +--- + +## Структура роли + +``` +roles/hysteria2/ +├── tasks/ +│ ├── install.yml ← пакеты, hysteria, qrencode +│ ├── configure.yml ← masquerade + ACME + firewall +│ ├── export.yml ← URL, QR, HTML сервера +│ └── export_global.yml ← общий output/index.html +└── templates/ + ├── config.yaml.j2 ← acme http + masquerade file + ├── client.yaml.j2 + ├── masq/index.html.j2 + └── export/ ← HTML-каталоги +``` + +--- + +## Переключение между ветками + +```bash +git fetch origin +git checkout main # masquerade + nginx (эта ветка) +git checkout salamander # Salamander obfs +``` + +Конфиги на **уже установленном** сервере **не меняются** при переключении ветки в git. +Чтобы применить другой режим на VPS: + +```bash +git checkout salamander # или main +make install # перекатит конфиг сервера +# или +make update +``` + +> Переключение режима **меняет** `/etc/hysteria/config.yaml` на сервере. Клиентские URI/QR нужно **перевыпустить** (`make export` или `make update`).