feat(mediaserver): поддержка vault_hysteria2_url — вставить URL целиком

- defaults: добавить mediaserver_hysteria2_url (приоритет над server/auth/obfs)
- tasks: парсинг URL через python3 urlparse → set_fact переопределяет отдельные переменные
- vault.yml.example: vault_hysteria2_url с примером, оба способа задокументированы
- README: способ 1 теперь реальный — одна строка в vault, всё разбирается автоматически
This commit is contained in:
Sergey Antropoff
2026-04-26 00:49:11 +03:00
parent 6176fb0e0e
commit 357474f98f
4 changed files with 106 additions and 40 deletions

View File

@@ -65,51 +65,50 @@ Init-контейнер автоматически прописывает в `co
### Настройка Hysteria2 сервера
#### Способ 1 — URL (Shadowrocket / Clash / NekoBox / hyst2 import)
#### Способ 1 — URL целиком (Shadowrocket / NekoBox / Hiddify / любой клиент)
Hysteria2 поддерживает стандартный URL-формат — его можно скопировать прямо из Shadowrocket, NekoBox, Hiddify и любого другого клиента:
```
hysteria2://PASSWORD@HOST:PORT?insecure=0&obfs=salamander&obfs-password=OBFS_PASS#MyProxy
```
Части URL:
| Часть | Значение |
|---|---|
| `PASSWORD` | Пароль аутентификации (`auth`) |
| `HOST:PORT` | Адрес и порт сервера |
| `insecure=1` | Отключить проверку TLS-сертификата (self-signed) |
| `insecure=0` | Проверять сертификат (Let's Encrypt / доверенный CA) |
| `obfs=salamander` | Включить obfuscation типа salamander |
| `obfs-password=...` | Пароль для obfuscation |
| `#MyProxy` | Имя (метка — игнорируется, только для отображения) |
Примеры URL:
```
# Без obfuscation, с проверкой TLS
hysteria2://mypassword@vps.example.com:443
# Без obfuscation, самоподписанный сертификат
hysteria2://mypassword@1.2.3.4:443?insecure=1
# С salamander obfuscation
hysteria2://mypassword@vps.example.com:443?obfs=salamander&obfs-password=obfsecret
# Полный вариант с именем
hysteria2://mypassword@vps.example.com:443?insecure=0&obfs=salamander&obfs-password=obfsecret#MyVPS
```
Чтобы использовать URL в vault — просто разбери его на части:
Скопируй URL из клиента и вставь **одной строкой** в vault:
```yaml
# Из URL: hysteria2://mypassword@vps.example.com:443?obfs=salamander&obfs-password=obfsecret
vault_hysteria2_server: "vps.example.com:443"
vault_hysteria2_auth: "mypassword"
# group_vars/all/vault.yml
vault_hysteria2_url: "hysteria2://mypassword@vps.example.com:443?insecure=0&obfs=salamander&obfs-password=obfsecret#MyVPS"
```
Obfuscation и TLS задаются отдельными переменными — см. ниже.
Ansible автоматически разберёт URL на составные части — `server`, `auth`, `insecure`, `obfs_type`, `obfs_password`. Ничего больше не нужно.
Структура URL:
```
hysteria2://PASSWORD@HOST:PORT?insecure=0&obfs=salamander&obfs-password=OBFS_PASS#Name
↑ ↑ ↑ ↑ ↑ ↑
пароль адрес:порт TLS (0/1) тип obfs пароль obfs метка (игн.)
```
| Параметр | Значение |
|---|---|
| `PASSWORD` | Пароль аутентификации |
| `HOST:PORT` | Адрес и порт сервера |
| `insecure=1` | Не проверять TLS (self-signed сертификат) |
| `insecure=0` | Проверять TLS (Let's Encrypt / доверенный CA) |
| `obfs=salamander` | Включить obfuscation — скрывает протокол от DPI |
| `obfs-password=...` | Пароль obfuscation |
| `#Name` | Метка — игнорируется, только для отображения в клиентах |
Примеры:
```
# Минимальный — только адрес и пароль
hysteria2://mypassword@1.2.3.4:443
# Self-signed сертификат на сервере
hysteria2://mypassword@1.2.3.4:443?insecure=1
# С obfuscation salamander
hysteria2://mypassword@vps.example.com:443?obfs=salamander&obfs-password=obfsecret
# Полный вариант
hysteria2://mypassword@vps.example.com:443?insecure=0&obfs=salamander&obfs-password=obfsecret#MyVPS
```
---

View File

@@ -106,6 +106,13 @@ mediaserver_prowlarr_resources:
# ─── Hysteria2 sidecar (Prowlarr pod only) ────────────────────────────────────
# SOCKS5 proxy on 127.0.0.1:1080 — Prowlarr uses it to reach blocked trackers
mediaserver_hysteria2_enabled: true
# ── Способ 1: вставить URL целиком (из Shadowrocket / NekoBox / Hiddify) ──────
# Формат: hysteria2://PASSWORD@HOST:PORT?insecure=0&obfs=salamander&obfs-password=XXX
# Если задан — server/auth/insecure/obfs ниже вычисляются автоматически.
mediaserver_hysteria2_url: "{{ vault_hysteria2_url | default('') }}"
# ── Способ 2: указать параметры по отдельности ────────────────────────────────
# Server address — e.g. "example.com:443" or "1.2.3.4:443"
mediaserver_hysteria2_server: "{{ vault_hysteria2_server | default('') }}"
# Authentication password

View File

@@ -104,6 +104,60 @@
retries: 3
delay: 10
# ── Hysteria2 URL parsing (если задан vault_hysteria2_url) ───────────────────
- name: Parse Hysteria2 URL into components
ansible.builtin.command: >-
python3 -c "
import sys, json
from urllib.parse import urlparse, parse_qs, unquote
url = sys.argv[1]
p = urlparse(url)
qs = parse_qs(p.query, keep_blank_values=True)
result = {
'server': '{}:{}'.format(p.hostname, p.port),
'auth': unquote(p.username or ''),
'insecure': qs.get('insecure', ['0'])[0] == '1',
'obfs_type': qs.get('obfs', [''])[0],
'obfs_password': qs.get('obfs-password', [''])[0],
}
print(json.dumps(result))
" "{{ mediaserver_hysteria2_url }}"
register: _hy2_url_parsed
changed_when: false
delegate_to: localhost
become: false
run_once: true
when:
- mediaserver_prowlarr_enabled
- mediaserver_hysteria2_enabled
- mediaserver_hysteria2_url != ""
- name: Override Hysteria2 variables from URL
ansible.builtin.set_fact:
mediaserver_hysteria2_server: "{{ (_hy2_url_parsed.stdout | from_json).server }}"
mediaserver_hysteria2_auth: "{{ (_hy2_url_parsed.stdout | from_json).auth }}"
mediaserver_hysteria2_insecure: "{{ (_hy2_url_parsed.stdout | from_json).insecure }}"
mediaserver_hysteria2_obfs_type: "{{ (_hy2_url_parsed.stdout | from_json).obfs_type }}"
mediaserver_hysteria2_obfs_password: "{{ (_hy2_url_parsed.stdout | from_json).obfs_password }}"
run_once: true
when:
- mediaserver_prowlarr_enabled
- mediaserver_hysteria2_enabled
- mediaserver_hysteria2_url != ""
- _hy2_url_parsed.rc == 0
- name: Show parsed Hysteria2 config
ansible.builtin.debug:
msg:
- "Hysteria2 server: {{ mediaserver_hysteria2_server }}"
- "Hysteria2 insecure: {{ mediaserver_hysteria2_insecure }}"
- "Hysteria2 obfs: {{ mediaserver_hysteria2_obfs_type | default('none') }}"
run_once: true
when:
- mediaserver_prowlarr_enabled
- mediaserver_hysteria2_enabled
# ── Hysteria2 Secret (if enabled) ─────────────────────────────────────────────
- name: Template Hysteria2 Secret