Compare commits
5 Commits
salamander
...
f5417a0f5c
| Author | SHA1 | Date | |
|---|---|---|---|
| f5417a0f5c | |||
| d2da39be08 | |||
| 3ca7dde4b2 | |||
| ad7846febe | |||
| e90e2bad8b |
@@ -5,6 +5,8 @@
|
||||
SHELL := /bin/bash
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
export EDITOR="nano"
|
||||
|
||||
ANSIBLE ?= ansible-playbook
|
||||
ANSIBLE_ADHOC ?= ansible
|
||||
INVENTORY ?= inventory/hosts.yml
|
||||
@@ -60,7 +62,7 @@ init: ## Создать inventory, group_vars и .vault_pass из примеро
|
||||
@echo "$(GREEN)Готово. Отредактируйте:$(NC)"
|
||||
@echo " inventory/hosts.yml"
|
||||
@echo " group_vars/all.yml"
|
||||
@echo " group_vars/hysteria2_servers/vault.yml → затем: make vault-encrypt"
|
||||
@echo " group_vars/hysteria2_servers/vault.yml → затем: make vault-encrypt"
|
||||
|
||||
check: ## Проверить синтаксис playbook
|
||||
$(ANSIBLE) playbook.yml --syntax-check $(VAULT_ARGS)
|
||||
|
||||
@@ -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,54 +186,78 @@ 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:
|
||||
friend: "custom-password"
|
||||
```
|
||||
|
||||
3. **Автогенерация** — `pwgen -s 40`, если пароль не задан.
|
||||
3. **Автогенерация** — Ansible `password` lookup (длина `hysteria2_password_length`), если пароль не задан.
|
||||
|
||||
При `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/
|
||||
├── 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/<server>/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/<server>/` при 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`).
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@ inventory = inventory/hosts.yml
|
||||
roles_path = roles
|
||||
host_key_checking = False
|
||||
retry_files_enabled = False
|
||||
stdout_callback = yaml
|
||||
stdout_callback = default
|
||||
result_format = yaml
|
||||
interpreter_python = auto_silent
|
||||
|
||||
[privilege_escalation]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Email для Let's Encrypt (ACME)
|
||||
hysteria2_acme_email: admin@example.com
|
||||
|
||||
# Длина автогенерируемых паролей (pwgen)
|
||||
# Длина автогенерируемых паролей VPN-пользователей
|
||||
hysteria2_password_length: 40
|
||||
|
||||
# Обновлять систему перед установкой (apt update && apt upgrade)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: true
|
||||
become: false
|
||||
tags: [install, update, export]
|
||||
tasks:
|
||||
- name: Generate global index.html and open in browser
|
||||
|
||||
@@ -9,7 +9,7 @@ hysteria2_acme_email: ""
|
||||
hysteria2_users: []
|
||||
|
||||
# Опционально: фиксированные пароли { username: password }
|
||||
# Пустое значение или отсутствие ключа — автогенерация через pwgen
|
||||
# Пустое значение или отсутствие ключа — автогенерация на control node (Ansible password lookup)
|
||||
|
||||
hysteria2_password_length: 40
|
||||
hysteria2_listen_port: 443
|
||||
@@ -20,6 +20,12 @@ hysteria2_masq_dir: /var/www/masq
|
||||
hysteria2_config_path: /etc/hysteria/config.yaml
|
||||
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)
|
||||
hysteria2_output_dir: "{{ playbook_dir }}/output"
|
||||
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"
|
||||
mode: "0644"
|
||||
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
|
||||
become: false
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
dest: "{{ hysteria2_output_dir }}/index.html"
|
||||
mode: "0644"
|
||||
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 }}"
|
||||
when: hysteria2_global_servers | default([]) | length > 0
|
||||
become: false
|
||||
@@ -60,7 +60,7 @@
|
||||
when:
|
||||
- hysteria2_open_browser | bool
|
||||
- hysteria2_global_servers | default([]) | length > 0
|
||||
- ansible_system == 'Darwin'
|
||||
- ansible_facts['system'] == 'Darwin'
|
||||
changed_when: false
|
||||
become: false
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
when:
|
||||
- hysteria2_open_browser | bool
|
||||
- hysteria2_global_servers | default([]) | length > 0
|
||||
- ansible_system == 'Linux'
|
||||
- ansible_facts['system'] == 'Linux'
|
||||
changed_when: false
|
||||
become: false
|
||||
failed_when: false
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
|
||||
- name: Install curl, micro, pwgen and qrencode
|
||||
- name: Install curl, micro and qrencode
|
||||
ansible.builtin.apt:
|
||||
name: "{{ _hysteria2_apt_packages }}"
|
||||
state: present
|
||||
@@ -19,15 +19,22 @@
|
||||
vars:
|
||||
_hysteria2_apt_packages: >-
|
||||
{{
|
||||
['curl', 'micro', 'pwgen']
|
||||
['curl', 'micro']
|
||||
+ (['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
|
||||
ansible.builtin.shell:
|
||||
cmd: bash <(curl -fsSL https://get.hy2.sh/)
|
||||
executable: /bin/bash
|
||||
args:
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ hysteria2_install_script_remote_path }}"
|
||||
creates: /usr/local/bin/hysteria
|
||||
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
|
||||
ansible.builtin.shell:
|
||||
cmd: bash <(curl -fsSL https://get.hy2.sh/)
|
||||
executable: /bin/bash
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ hysteria2_install_script_remote_path }} --force"
|
||||
register: _hysteria2_update
|
||||
notify: Restart hysteria-server
|
||||
|
||||
|
||||
@@ -60,16 +60,24 @@
|
||||
- update
|
||||
- export
|
||||
|
||||
- name: Generate missing user passwords with pwgen
|
||||
ansible.builtin.command:
|
||||
cmd: "pwgen -s {{ hysteria2_password_length }} 1"
|
||||
register: _hysteria2_pwgen
|
||||
changed_when: false
|
||||
when: item.password | length == 0
|
||||
- name: Generate missing user passwords
|
||||
ansible.builtin.set_fact:
|
||||
_hysteria2_users_with_passwords: "{{ _hysteria2_users_with_passwords | default([]) + [ _entry ] }}"
|
||||
vars:
|
||||
_entry:
|
||||
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_control:
|
||||
label: "{{ item.name }}"
|
||||
index_var: _hysteria2_user_idx
|
||||
tags:
|
||||
- install
|
||||
- update
|
||||
@@ -77,25 +85,7 @@
|
||||
|
||||
- name: Apply generated passwords
|
||||
ansible.builtin.set_fact:
|
||||
hysteria2_resolved_users: "{{ hysteria2_resolved_users | default([]) + [ _entry ] }}"
|
||||
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
|
||||
hysteria2_resolved_users: "{{ _hysteria2_users_with_passwords }}"
|
||||
tags:
|
||||
- install
|
||||
- update
|
||||
|
||||
Reference in New Issue
Block a user