Compare commits
5 Commits
salamander
...
d61a26557a
| Author | SHA1 | Date | |
|---|---|---|---|
| d61a26557a | |||
| 2d44916893 | |||
| 3ca7dde4b2 | |||
| ad7846febe | |||
| e90e2bad8b |
@@ -5,6 +5,8 @@
|
|||||||
SHELL := /bin/bash
|
SHELL := /bin/bash
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
export EDITOR="nano"
|
||||||
|
|
||||||
ANSIBLE ?= ansible-playbook
|
ANSIBLE ?= ansible-playbook
|
||||||
ANSIBLE_ADHOC ?= ansible
|
ANSIBLE_ADHOC ?= ansible
|
||||||
INVENTORY ?= inventory/hosts.yml
|
INVENTORY ?= inventory/hosts.yml
|
||||||
|
|||||||
@@ -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
|
```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
|
make init
|
||||||
# отредактировать:
|
# отредактировать inventory/hosts.yml, group_vars/all.yml, vault
|
||||||
# inventory/hosts.yml
|
|
||||||
# group_vars/all.yml
|
|
||||||
# group_vars/hysteria2_servers/vault.yml
|
|
||||||
|
|
||||||
make vault-encrypt # зашифровать пароли VPS
|
make vault-encrypt
|
||||||
make ping # проверить SSH
|
make ping
|
||||||
make install # установка → output/ → браузер откроется сам
|
make install # → output/index.html откроется в браузере
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Makefile
|
## Makefile
|
||||||
|
|
||||||
| Команда | Описание |
|
| Команда | Описание |
|
||||||
@@ -26,23 +60,24 @@ make install # установка → output/ → браузер отк
|
|||||||
| `make init` | Создать конфиги из `.example` |
|
| `make init` | Создать конфиги из `.example` |
|
||||||
| `make ping` | Проверить SSH к VPS |
|
| `make ping` | Проверить SSH к VPS |
|
||||||
| `make status` | `systemctl status hysteria-server` |
|
| `make status` | `systemctl status hysteria-server` |
|
||||||
| `make install` | Установка + экспорт + `output/index.html` + открытие в браузере |
|
| `make install` | Установка masquerade + экспорт URL/QR/HTML |
|
||||||
| `make update` | Обновить бинарник, конфиг, перевыпустить экспорт |
|
| `make update` | Обновить бинарник, конфиг, перевыпустить экспорт |
|
||||||
| `make export` | Только экспорт URL/QR/HTML |
|
| `make export` | Только экспорт (URL, QR, HTML) |
|
||||||
| `make uninstall` | Удалить Hysteria2 с VPS |
|
| `make uninstall` | Удалить Hysteria2 с VPS |
|
||||||
| `make vault-encrypt` | Зашифровать vault |
|
| `make vault-encrypt` | Зашифровать vault |
|
||||||
| `make vault-edit` | Редактировать vault |
|
| `make vault-edit` | Редактировать vault |
|
||||||
|
|
||||||
### Примеры
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make install LIMIT=vps-de
|
make install LIMIT=vps-de
|
||||||
make update LIMIT=vps-nl
|
make update LIMIT=vps-nl
|
||||||
make export
|
make export
|
||||||
make uninstall LIMIT=vps-de EXTRA_VARS='hysteria2_uninstall_remove_local_output=true'
|
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
|
## Inventory
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -70,7 +105,7 @@ all:
|
|||||||
- bob
|
- bob
|
||||||
```
|
```
|
||||||
|
|
||||||
### SSH-подключение к VPS
|
### SSH (VPS)
|
||||||
|
|
||||||
| Параметр | Где | Описание |
|
| Параметр | Где | Описание |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -78,7 +113,7 @@ all:
|
|||||||
| `ansible_port` | inventory | SSH-порт (по умолчанию `22`) |
|
| `ansible_port` | inventory | SSH-порт (по умолчанию `22`) |
|
||||||
| `ansible_user` | inventory | Пользователь SSH (обычно `root`) |
|
| `ansible_user` | inventory | Пользователь SSH (обычно `root`) |
|
||||||
| `ansible_password` | inventory + vault | Пароль из `vault_ssh_passwords` |
|
| `ansible_password` | inventory + vault | Пароль из `vault_ssh_passwords` |
|
||||||
| `ansible_ssh_private_key_file` | inventory | Альтернатива паролю — SSH-ключ |
|
| `ansible_ssh_private_key_file` | inventory | Альтернатива — SSH-ключ |
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# group_vars/hysteria2_servers/vault.yml
|
# group_vars/hysteria2_servers/vault.yml
|
||||||
@@ -89,9 +124,61 @@ vault_ssh_passwords:
|
|||||||
|
|
||||||
Ключи в `vault_ssh_passwords` совпадают с **именами хостов** в inventory.
|
Ключи в `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-пользователей
|
## Пароли VPN-пользователей
|
||||||
|
|
||||||
1. **Vault** (рекомендуется):
|
1. **Vault (рекомендуется):**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
vault_hysteria2_user_passwords:
|
vault_hysteria2_user_passwords:
|
||||||
@@ -99,22 +186,56 @@ vault_hysteria2_user_passwords:
|
|||||||
friend: "Aingae0Okit1eek4eeZahFohVei4akee"
|
friend: "Aingae0Okit1eek4eeZahFohVei4akee"
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Per-host в inventory**:
|
Подключается через `group_vars/hysteria2_servers/vars.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Per-host в inventory:**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
hysteria2_user_passwords:
|
hysteria2_user_passwords:
|
||||||
friend: "custom-password"
|
friend: "custom-password"
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Автогенерация** — `pwgen -s 40`, если пароль не задан.
|
3. **Автогенерация** — Ansible `password` lookup (длина `hysteria2_password_length`), если пароль не задан.
|
||||||
|
|
||||||
При `make update` пароли подтягиваются из `output/<server>/server-info.yml`, если не указаны в vault/inventory.
|
При `make update` пароли подтягиваются из `output/<server>/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/`
|
||||||
|
|
||||||
```
|
```
|
||||||
output/
|
output/
|
||||||
├── index.html ← общий каталог всех серверов (открывается в браузере)
|
├── index.html ← все серверы (открывается в браузере)
|
||||||
├── vps-de/
|
├── vps-de/
|
||||||
│ ├── index.html ← страница сервера
|
│ ├── index.html ← страница сервера
|
||||||
│ ├── my.url
|
│ ├── my.url
|
||||||
@@ -126,27 +247,17 @@ output/
|
|||||||
└── ...
|
└── ...
|
||||||
```
|
```
|
||||||
|
|
||||||
### HTML-страницы
|
HTML-страницы показывают:
|
||||||
|
|
||||||
**`output/index.html`** — общий каталог:
|
- пароль и URL каждого пользователя с **кнопкой копирования**;
|
||||||
- все серверы и пользователи на одной странице
|
- QR-коды;
|
||||||
- навигация по серверам
|
- ссылки на файлы и страницы серверов.
|
||||||
- поля ссылки/пароля с кнопкой копирования
|
|
||||||
- QR-коды
|
|
||||||
- ссылки на файлы и страницы серверов
|
|
||||||
|
|
||||||
**`output/<server>/index.html`** — страница одного сервера (тот же стиль, все пользователи сервера).
|
|
||||||
|
|
||||||
После `make install`, `make update` и `make export` **`output/index.html` автоматически открывается в браузере** (macOS: `open`, Linux: `xdg-open`).
|
После `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-коды
|
## QR-коды
|
||||||
|
|
||||||
@@ -158,6 +269,8 @@ PNG генерируются средствами Ansible (без Python):
|
|||||||
|
|
||||||
ASCII QR — `hysteria share --qr` → `user.qr.txt`.
|
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_user_passwords` | host/vault | Свои пароли VPN |
|
||||||
| `hysteria2_output_dir` | group | Папка экспорта (по умолчанию `./output`) |
|
| `hysteria2_output_dir` | group | Папка экспорта (по умолчанию `./output`) |
|
||||||
| `hysteria2_output_name` | host | Имя подпапки (по умолчанию `inventory_hostname`) |
|
| `hysteria2_output_name` | host | Имя подпапки (по умолчанию `inventory_hostname`) |
|
||||||
|
| `hysteria2_listen_port` | group | Порт Hysteria2 (443) |
|
||||||
| `hysteria2_generate_qr_png` | group | PNG QR через `qrencode` |
|
| `hysteria2_generate_qr_png` | group | PNG QR через `qrencode` |
|
||||||
| `hysteria2_open_browser` | group | Открыть `output/index.html` после экспорта |
|
| `hysteria2_open_browser` | group | Открыть `output/index.html` после экспорта |
|
||||||
| `hysteria2_uninstall_remove_local_output` | extra-vars | Удалить `output/<server>/` при uninstall |
|
| `hysteria2_uninstall_remove_local_output` | extra-vars | Удалить `output/<server>/` при uninstall |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Безопасность
|
## Безопасность
|
||||||
|
|
||||||
- `output/` содержит пароли и URL — в `.gitignore`
|
- `output/` содержит пароли и URL — **не коммитить** (в `.gitignore`)
|
||||||
- `inventory/hosts.yml`, `vault.yml`, `.vault_pass` — не коммитить
|
- `inventory/hosts.yml`, `vault.yml`, `.vault_pass` — не коммитить
|
||||||
- После `make init` выполните `make vault-encrypt`
|
- После `make init` выполните `make vault-encrypt`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Требования
|
## Требования
|
||||||
|
|
||||||
- Ansible 2.14+
|
- Ansible 2.14+
|
||||||
- Debian/Ubuntu VPS с sudo
|
- Debian/Ubuntu VPS с sudo
|
||||||
- Домен с A-записью на IP сервера
|
- Домен с A-записью на IP сервера
|
||||||
- Для авто-открытия браузера: macOS или Linux с `xdg-open`
|
- Для авто-открытия браузера: 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`).
|
||||||
|
|||||||
+2
-1
@@ -3,7 +3,8 @@ inventory = inventory/hosts.yml
|
|||||||
roles_path = roles
|
roles_path = roles
|
||||||
host_key_checking = False
|
host_key_checking = False
|
||||||
retry_files_enabled = False
|
retry_files_enabled = False
|
||||||
stdout_callback = yaml
|
stdout_callback = default
|
||||||
|
result_format = yaml
|
||||||
interpreter_python = auto_silent
|
interpreter_python = auto_silent
|
||||||
|
|
||||||
[privilege_escalation]
|
[privilege_escalation]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Email для Let's Encrypt (ACME)
|
# Email для Let's Encrypt (ACME)
|
||||||
hysteria2_acme_email: admin@example.com
|
hysteria2_acme_email: admin@example.com
|
||||||
|
|
||||||
# Длина автогенерируемых паролей (pwgen)
|
# Длина автогенерируемых паролей VPN-пользователей
|
||||||
hysteria2_password_length: 40
|
hysteria2_password_length: 40
|
||||||
|
|
||||||
# Обновлять систему перед установкой (apt update && apt upgrade)
|
# Обновлять систему перед установкой (apt update && apt upgrade)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
hosts: localhost
|
hosts: localhost
|
||||||
connection: local
|
connection: local
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
|
become: false
|
||||||
tags: [install, update, export]
|
tags: [install, update, export]
|
||||||
tasks:
|
tasks:
|
||||||
- name: Generate global index.html and open in browser
|
- name: Generate global index.html and open in browser
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ hysteria2_acme_email: ""
|
|||||||
hysteria2_users: []
|
hysteria2_users: []
|
||||||
|
|
||||||
# Опционально: фиксированные пароли { username: password }
|
# Опционально: фиксированные пароли { username: password }
|
||||||
# Пустое значение или отсутствие ключа — автогенерация через pwgen
|
# Пустое значение или отсутствие ключа — автогенерация на control node (Ansible password lookup)
|
||||||
|
|
||||||
hysteria2_password_length: 40
|
hysteria2_password_length: 40
|
||||||
hysteria2_listen_port: 443
|
hysteria2_listen_port: 443
|
||||||
@@ -20,6 +20,12 @@ hysteria2_masq_dir: /var/www/masq
|
|||||||
hysteria2_config_path: /etc/hysteria/config.yaml
|
hysteria2_config_path: /etc/hysteria/config.yaml
|
||||||
hysteria2_service_name: hysteria-server
|
hysteria2_service_name: hysteria-server
|
||||||
|
|
||||||
|
# Официальный install_server.sh: хранится в roles/hysteria2/files/, синхронизируется с get.hy2.sh
|
||||||
|
hysteria2_install_script_url: "https://get.hy2.sh/"
|
||||||
|
hysteria2_install_script_name: install_server.sh
|
||||||
|
hysteria2_install_script_staging_dir: "{{ playbook_dir }}/.cache/hysteria2"
|
||||||
|
hysteria2_install_script_remote_path: /tmp/hysteria2-install_server.sh
|
||||||
|
|
||||||
# Локальный каталог для экспорта URL и QR (на control node)
|
# Локальный каталог для экспорта URL и QR (на control node)
|
||||||
hysteria2_output_dir: "{{ playbook_dir }}/output"
|
hysteria2_output_dir: "{{ playbook_dir }}/output"
|
||||||
hysteria2_output_name: "{{ inventory_hostname }}"
|
hysteria2_output_name: "{{ inventory_hostname }}"
|
||||||
|
|||||||
Executable
+1170
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@
|
|||||||
dest: "{{ hysteria2_output_dir }}/{{ hysteria2_output_name }}/index.html"
|
dest: "{{ hysteria2_output_dir }}/{{ hysteria2_output_name }}/index.html"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
vars:
|
vars:
|
||||||
generated_at: "{{ ansible_date_time.date }} {{ ansible_date_time.time }}"
|
generated_at: "{{ now(utc=false, fmt='%Y-%m-%d %H:%M:%S') }}"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
dest: "{{ hysteria2_output_dir }}/index.html"
|
dest: "{{ hysteria2_output_dir }}/index.html"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
vars:
|
vars:
|
||||||
generated_at: "{{ ansible_date_time.date }} {{ ansible_date_time.time }}"
|
generated_at: "{{ now(utc=false, fmt='%Y-%m-%d %H:%M:%S') }}"
|
||||||
total_users: "{{ hysteria2_global_servers | map(attribute='users') | map('length') | sum }}"
|
total_users: "{{ hysteria2_global_servers | map(attribute='users') | map('length') | sum }}"
|
||||||
when: hysteria2_global_servers | default([]) | length > 0
|
when: hysteria2_global_servers | default([]) | length > 0
|
||||||
become: false
|
become: false
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
when:
|
when:
|
||||||
- hysteria2_open_browser | bool
|
- hysteria2_open_browser | bool
|
||||||
- hysteria2_global_servers | default([]) | length > 0
|
- hysteria2_global_servers | default([]) | length > 0
|
||||||
- ansible_system == 'Darwin'
|
- ansible_facts['system'] == 'Darwin'
|
||||||
changed_when: false
|
changed_when: false
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
when:
|
when:
|
||||||
- hysteria2_open_browser | bool
|
- hysteria2_open_browser | bool
|
||||||
- hysteria2_global_servers | default([]) | length > 0
|
- hysteria2_global_servers | default([]) | length > 0
|
||||||
- ansible_system == 'Linux'
|
- ansible_facts['system'] == 'Linux'
|
||||||
changed_when: false
|
changed_when: false
|
||||||
become: false
|
become: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
upgrade: dist
|
upgrade: dist
|
||||||
|
|
||||||
- name: Install curl, micro, pwgen and qrencode
|
- name: Install curl, micro and qrencode
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
name: "{{ _hysteria2_apt_packages }}"
|
name: "{{ _hysteria2_apt_packages }}"
|
||||||
state: present
|
state: present
|
||||||
@@ -19,15 +19,22 @@
|
|||||||
vars:
|
vars:
|
||||||
_hysteria2_apt_packages: >-
|
_hysteria2_apt_packages: >-
|
||||||
{{
|
{{
|
||||||
['curl', 'micro', 'pwgen']
|
['curl', 'micro']
|
||||||
+ (['qrencode'] if hysteria2_generate_qr_png | bool else [])
|
+ (['qrencode'] if hysteria2_generate_qr_png | bool else [])
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
- name: Sync official Hysteria2 install script on control node
|
||||||
|
ansible.builtin.import_tasks: sync_install_script.yml
|
||||||
|
|
||||||
|
- name: Copy Hysteria2 install script to server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ hysteria2_install_script_name }}"
|
||||||
|
dest: "{{ hysteria2_install_script_remote_path }}"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
- name: Install Hysteria2 via official script
|
- name: Install Hysteria2 via official script
|
||||||
ansible.builtin.shell:
|
ansible.builtin.command:
|
||||||
cmd: bash <(curl -fsSL https://get.hy2.sh/)
|
cmd: "{{ hysteria2_install_script_remote_path }}"
|
||||||
executable: /bin/bash
|
|
||||||
args:
|
|
||||||
creates: /usr/local/bin/hysteria
|
creates: /usr/local/bin/hysteria
|
||||||
register: _hysteria2_install
|
register: _hysteria2_install
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure staging directory for install script sync
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ hysteria2_install_script_staging_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0700"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
- name: Fetch official install script for version check
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ hysteria2_install_script_url }}"
|
||||||
|
dest: "{{ hysteria2_install_script_staging_dir }}/{{ hysteria2_install_script_name }}.remote"
|
||||||
|
mode: "0644"
|
||||||
|
force: true
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
register: _hysteria2_remote_script
|
||||||
|
|
||||||
|
- name: Stat local install script in role files
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ role_path }}/files/{{ hysteria2_install_script_name }}"
|
||||||
|
checksum_algorithm: sha256
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
register: _hysteria2_local_script
|
||||||
|
|
||||||
|
- name: Stat remote install script from official server
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ hysteria2_install_script_staging_dir }}/{{ hysteria2_install_script_name }}.remote"
|
||||||
|
checksum_algorithm: sha256
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
register: _hysteria2_remote_script_stat
|
||||||
|
|
||||||
|
- name: Update bundled install script when official version is newer
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ hysteria2_install_script_staging_dir }}/{{ hysteria2_install_script_name }}.remote"
|
||||||
|
dest: "{{ role_path }}/files/{{ hysteria2_install_script_name }}"
|
||||||
|
mode: "0755"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
|
when: >-
|
||||||
|
not _hysteria2_local_script.stat.exists
|
||||||
|
or _hysteria2_local_script.stat.checksum
|
||||||
|
!= _hysteria2_remote_script_stat.stat.checksum
|
||||||
|
register: _hysteria2_script_updated
|
||||||
|
|
||||||
|
- name: Report install script sync result
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: >-
|
||||||
|
{{
|
||||||
|
'Официальный install_server.sh обновлён в roles/hysteria2/files/'
|
||||||
|
if (_hysteria2_script_updated.changed | default(false))
|
||||||
|
else 'Локальный install_server.sh актуален (совпадает с ' ~ hysteria2_install_script_url ~ ')'
|
||||||
|
}}
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
run_once: true
|
||||||
@@ -1,8 +1,16 @@
|
|||||||
---
|
---
|
||||||
|
- name: Sync official Hysteria2 install script on control node
|
||||||
|
ansible.builtin.import_tasks: sync_install_script.yml
|
||||||
|
|
||||||
|
- name: Copy Hysteria2 install script to server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ hysteria2_install_script_name }}"
|
||||||
|
dest: "{{ hysteria2_install_script_remote_path }}"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
- name: Update Hysteria2 binary via official script
|
- name: Update Hysteria2 binary via official script
|
||||||
ansible.builtin.shell:
|
ansible.builtin.command:
|
||||||
cmd: bash <(curl -fsSL https://get.hy2.sh/)
|
cmd: "{{ hysteria2_install_script_remote_path }} --force"
|
||||||
executable: /bin/bash
|
|
||||||
register: _hysteria2_update
|
register: _hysteria2_update
|
||||||
notify: Restart hysteria-server
|
notify: Restart hysteria-server
|
||||||
|
|
||||||
|
|||||||
@@ -60,16 +60,24 @@
|
|||||||
- update
|
- update
|
||||||
- export
|
- export
|
||||||
|
|
||||||
- name: Generate missing user passwords with pwgen
|
- name: Generate missing user passwords
|
||||||
ansible.builtin.command:
|
ansible.builtin.set_fact:
|
||||||
cmd: "pwgen -s {{ hysteria2_password_length }} 1"
|
_hysteria2_users_with_passwords: "{{ _hysteria2_users_with_passwords | default([]) + [ _entry ] }}"
|
||||||
register: _hysteria2_pwgen
|
vars:
|
||||||
changed_when: false
|
_entry:
|
||||||
when: item.password | length == 0
|
name: "{{ item.name }}"
|
||||||
|
password: >-
|
||||||
|
{{
|
||||||
|
lookup(
|
||||||
|
'password',
|
||||||
|
'/dev/null chars=ascii_letters,digits length=' ~ (hysteria2_password_length | string)
|
||||||
|
)
|
||||||
|
if item.password | length == 0
|
||||||
|
else item.password
|
||||||
|
}}
|
||||||
loop: "{{ hysteria2_resolved_users }}"
|
loop: "{{ hysteria2_resolved_users }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item.name }}"
|
label: "{{ item.name }}"
|
||||||
index_var: _hysteria2_user_idx
|
|
||||||
tags:
|
tags:
|
||||||
- install
|
- install
|
||||||
- update
|
- update
|
||||||
@@ -77,25 +85,7 @@
|
|||||||
|
|
||||||
- name: Apply generated passwords
|
- name: Apply generated passwords
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
hysteria2_resolved_users: "{{ hysteria2_resolved_users | default([]) + [ _entry ] }}"
|
hysteria2_resolved_users: "{{ _hysteria2_users_with_passwords }}"
|
||||||
vars:
|
|
||||||
_generated: >-
|
|
||||||
{{
|
|
||||||
_hysteria2_pwgen.results[_hysteria2_user_idx].stdout | default('')
|
|
||||||
if (
|
|
||||||
item.password | length == 0
|
|
||||||
and not (_hysteria2_pwgen.results[_hysteria2_user_idx].skipped | default(false))
|
|
||||||
)
|
|
||||||
else item.password
|
|
||||||
}}
|
|
||||||
_entry:
|
|
||||||
name: "{{ item.name }}"
|
|
||||||
password: "{{ _generated }}"
|
|
||||||
loop: "{{ hysteria2_resolved_users }}"
|
|
||||||
loop_control:
|
|
||||||
label: "{{ item.name }}"
|
|
||||||
index_var: _hysteria2_user_idx
|
|
||||||
when: _hysteria2_pwgen is defined
|
|
||||||
tags:
|
tags:
|
||||||
- install
|
- install
|
||||||
- update
|
- update
|
||||||
|
|||||||
Reference in New Issue
Block a user