feat: добавить аддон hysteria2-server + playbook.yml для всех аддонов
hysteria2-server: - Устанавливает Hysteria2 v2 на удалённый VPS (группа [hysteria2_server]) - TLS: selfsigned (IP, insecure=1) | acme (Let's Encrypt) | custom - Obfuscation salamander, masquerade, лимиты полосы - systemd-сервис, открытие firewall (ufw/firewalld) - Вывод готового URL hysteria2://... для vault_hysteria2_url - SSH с паролем: make addon-hysteria2-server ARGS="-k" (интерактивный ввод) playbook.yml: - addons/mediaserver/playbook.yml — hosts: k3s_master[0] - addons/hysteria2-server/playbook.yml — hosts: hysteria2_server Интеграция: - inventory/hosts.ini: группа [hysteria2_server] (закомментированный пример) - group_vars/all/addons.yml: addon_hysteria2_server - vault.yml.example: vault_hysteria2_server_password, vault_hysteria2_obfs_password - playbooks/addons.yml: оба аддона - Makefile: addon-hysteria2-server target
This commit is contained in:
6
Makefile
6
Makefile
@@ -58,7 +58,7 @@ DOCKER_RUN := docker run --rm -it \
|
||||
addon-harbor addon-gitea addon-owncloud addon-nextcloud \
|
||||
addon-csi-s3 addon-csi-ceph addon-csi-glusterfs addon-vaultwarden \
|
||||
addon-smtp-relay addon-vault addon-external-secrets \
|
||||
addon-jenkins addon-netbird addon-mediaserver \
|
||||
addon-jenkins addon-netbird addon-mediaserver addon-hysteria2-server \
|
||||
add-node remove-node \
|
||||
add-etcd-node remove-etcd-node \
|
||||
etcd-backup etcd-restore etcd-list-snapshots \
|
||||
@@ -412,6 +412,10 @@ addon-mediaserver: _check_env _check_image ## Установить MediaServer
|
||||
@printf "$(CYAN)Устанавливаю MediaServer стек...$(NC)\n"
|
||||
$(DOCKER_RUN) addon mediaserver $(ARGS)
|
||||
|
||||
addon-hysteria2-server: _check_env _check_image ## Установить Hysteria2 VPN сервер на удалённый VPS из группы [hysteria2_server] (ARGS="-k" для SSH пароля, ARGS="-k -K" для SSH+sudo)
|
||||
@printf "$(CYAN)Устанавливаю Hysteria2 сервер на удалённый VPS...$(NC)\n"
|
||||
$(DOCKER_RUN) addon hysteria2-server $(ARGS)
|
||||
|
||||
# Generic цель — любой аддон из addons/<name>/playbook.yml
|
||||
addon-%: _check_env _check_image
|
||||
@if [ ! -f "addons/$*/playbook.yml" ]; then \
|
||||
|
||||
266
addons/hysteria2-server/README.md
Normal file
266
addons/hysteria2-server/README.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# Hysteria2 Server
|
||||
|
||||
Устанавливает [Hysteria2](https://v2.hysteria.network/) VPN-сервер на удалённый VPS. На выходе даёт готовый URL для вставки в Shadowrocket, NekoBox, Hiddify или `vault_hysteria2_url` (Prowlarr sidecar).
|
||||
|
||||
## Что устанавливается
|
||||
|
||||
- Бинарник `hysteria` последней версии с GitHub
|
||||
- Системный пользователь `hysteria`
|
||||
- Конфиг в `/etc/hysteria/config.yaml`
|
||||
- systemd-сервис `hysteria2` (autostart)
|
||||
- Правило firewall (ufw / firewalld)
|
||||
- TLS: self-signed cert **или** Let's Encrypt (ACME) **или** свой сертификат
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Добавить VPS в inventory
|
||||
|
||||
```ini
|
||||
# inventory/hosts.ini
|
||||
[hysteria2_server]
|
||||
myvps ansible_host=1.2.3.4 ansible_user=root
|
||||
```
|
||||
|
||||
### 2. Vault секреты
|
||||
|
||||
```bash
|
||||
make vault-edit
|
||||
```
|
||||
|
||||
```yaml
|
||||
# group_vars/all/vault.yml
|
||||
vault_hysteria2_server_password: "my-secure-password-32chars+"
|
||||
vault_hysteria2_obfs_password: "obfs-secret" # если obfs включён
|
||||
```
|
||||
|
||||
### 3. Деплой
|
||||
|
||||
**С SSH-ключом** (рекомендуется):
|
||||
```bash
|
||||
make addon-hysteria2-server
|
||||
```
|
||||
|
||||
**С SSH-паролем** (ввод в терминале):
|
||||
```bash
|
||||
make addon-hysteria2-server ARGS="-k"
|
||||
```
|
||||
|
||||
**С SSH-паролем + sudo-паролем**:
|
||||
```bash
|
||||
make addon-hysteria2-server ARGS="-k -K"
|
||||
```
|
||||
|
||||
**На конкретный хост** (без inventory):
|
||||
```bash
|
||||
make addon-hysteria2-server ARGS="-i '1.2.3.4,' -u root -k"
|
||||
```
|
||||
|
||||
После деплоя Ansible выведет готовый URL:
|
||||
```
|
||||
vault_hysteria2_url: "hysteria2://password@1.2.3.4:443?insecure=1#MyVPS"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Конфигурация
|
||||
|
||||
### Режимы TLS
|
||||
|
||||
#### Self-signed (по умолчанию) — без домена, IP-only
|
||||
|
||||
```yaml
|
||||
# group_vars/all/main.yml
|
||||
hysteria2_server_tls_mode: "selfsigned"
|
||||
```
|
||||
|
||||
Клиент подключается с `insecure=1`. URL автоматически получает `?insecure=1`.
|
||||
|
||||
#### ACME — Let's Encrypt (нужен домен)
|
||||
|
||||
```yaml
|
||||
hysteria2_server_tls_mode: "acme"
|
||||
hysteria2_server_domain: "vpn.example.com"
|
||||
hysteria2_server_acme_email: "admin@example.com"
|
||||
```
|
||||
|
||||
Требования: порт 80 открыт, DNS A-запись указывает на VPS. Hysteria2 сам получает и обновляет сертификат.
|
||||
|
||||
#### Custom — свои cert/key файлы
|
||||
|
||||
```yaml
|
||||
hysteria2_server_tls_mode: "custom"
|
||||
hysteria2_server_tls_cert_path: "/etc/hysteria/server.crt"
|
||||
hysteria2_server_tls_key_path: "/etc/hysteria/server.key"
|
||||
```
|
||||
|
||||
Сертификаты должны уже лежать на сервере до запуска роли.
|
||||
|
||||
---
|
||||
|
||||
### Obfuscation (salamander)
|
||||
|
||||
Скрывает протокол от DPI — важно если Hysteria2 блокируется провайдером:
|
||||
|
||||
```yaml
|
||||
hysteria2_server_obfs_enabled: true
|
||||
```
|
||||
|
||||
```yaml
|
||||
# vault.yml
|
||||
vault_hysteria2_obfs_password: "random-obfs-phrase"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Лимиты полосы на клиента
|
||||
|
||||
```yaml
|
||||
hysteria2_server_up_mbps: 100 # исходящий с сервера (= входящий у клиента)
|
||||
hysteria2_server_down_mbps: 100 # входящий на сервер (= исходящий у клиента)
|
||||
```
|
||||
|
||||
`0` — без ограничений.
|
||||
|
||||
---
|
||||
|
||||
### Все переменные
|
||||
|
||||
```yaml
|
||||
hysteria2_server_version: "" # "" = автоопределение последней версии
|
||||
hysteria2_server_port: 443
|
||||
hysteria2_server_password: "{{ vault_hysteria2_server_password }}"
|
||||
|
||||
hysteria2_server_tls_mode: "selfsigned" # selfsigned | acme | custom
|
||||
hysteria2_server_domain: ""
|
||||
hysteria2_server_acme_email: ""
|
||||
hysteria2_server_tls_cert_path: "/etc/hysteria/server.crt"
|
||||
hysteria2_server_tls_key_path: "/etc/hysteria/server.key"
|
||||
|
||||
hysteria2_server_obfs_enabled: false
|
||||
hysteria2_server_obfs_password: "{{ vault_hysteria2_obfs_password | default('') }}"
|
||||
|
||||
hysteria2_server_masquerade_enabled: true
|
||||
hysteria2_server_masquerade_url: "https://bing.com/"
|
||||
|
||||
hysteria2_server_up_mbps: 0
|
||||
hysteria2_server_down_mbps: 0
|
||||
|
||||
hysteria2_server_name: "MyVPS" # метка в URL (для клиентов)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Подключение SSH
|
||||
|
||||
### Ключ (рекомендуется)
|
||||
|
||||
```bash
|
||||
# Скопировать ключ на VPS
|
||||
ssh-copy-id root@1.2.3.4
|
||||
|
||||
# Деплой
|
||||
make addon-hysteria2-server
|
||||
```
|
||||
|
||||
### Пароль
|
||||
|
||||
```bash
|
||||
# Ввод пароля в терминале:
|
||||
make addon-hysteria2-server ARGS="-k"
|
||||
```
|
||||
|
||||
Или хранить в vault (не рекомендуется для SSH):
|
||||
|
||||
```yaml
|
||||
# inventory/hosts.ini
|
||||
[hysteria2_server]
|
||||
myvps ansible_host=1.2.3.4 ansible_user=root ansible_ssh_pass="{{ vault_hysteria2_vps_ssh_password }}"
|
||||
```
|
||||
|
||||
### Нестандартный SSH порт
|
||||
|
||||
```ini
|
||||
# inventory/hosts.ini
|
||||
[hysteria2_server]
|
||||
myvps ansible_host=1.2.3.4 ansible_user=root ansible_port=2222
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Примеры inventory
|
||||
|
||||
### Один VPS, root + ключ
|
||||
|
||||
```ini
|
||||
[hysteria2_server]
|
||||
myvps ansible_host=1.2.3.4 ansible_user=root
|
||||
```
|
||||
|
||||
### Один VPS, обычный пользователь + sudo
|
||||
|
||||
```ini
|
||||
[hysteria2_server]
|
||||
myvps ansible_host=1.2.3.4 ansible_user=ubuntu
|
||||
```
|
||||
|
||||
```bash
|
||||
make addon-hysteria2-server ARGS="-K" # -K = prompt sudo password
|
||||
```
|
||||
|
||||
### Несколько серверов (мульти-регион)
|
||||
|
||||
```ini
|
||||
[hysteria2_server]
|
||||
vps-nl ansible_host=1.2.3.4 ansible_user=root
|
||||
vps-de ansible_host=5.6.7.8 ansible_user=root
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Что делать с URL после деплоя
|
||||
|
||||
Ansible выведет в конце:
|
||||
|
||||
```
|
||||
vault_hysteria2_url: "hysteria2://mypassword@1.2.3.4:443?insecure=1&obfs=salamander&obfs-password=secret#MyVPS"
|
||||
```
|
||||
|
||||
**Вариант 1 — вставить в vault для Prowlarr:**
|
||||
```yaml
|
||||
# group_vars/all/vault.yml
|
||||
vault_hysteria2_url: "hysteria2://mypassword@1.2.3.4:443?insecure=1#MyVPS"
|
||||
```
|
||||
Затем: `make addon-mediaserver`
|
||||
|
||||
**Вариант 2 — вставить в Shadowrocket / NekoBox / Hiddify:**
|
||||
Скопируй строку `hysteria2://...` и добавь как новый профиль в клиент.
|
||||
|
||||
---
|
||||
|
||||
## Управление сервисом
|
||||
|
||||
```bash
|
||||
# Статус
|
||||
ssh root@1.2.3.4 systemctl status hysteria2
|
||||
|
||||
# Логи в реальном времени
|
||||
ssh root@1.2.3.4 journalctl -u hysteria2 -f
|
||||
|
||||
# Перезапуск после изменения конфига
|
||||
ssh root@1.2.3.4 systemctl restart hysteria2
|
||||
|
||||
# Обновить до последней версии
|
||||
make addon-hysteria2-server
|
||||
```
|
||||
|
||||
## Обновление
|
||||
|
||||
```bash
|
||||
# Скачает последнюю версию и перезапустит сервис
|
||||
make addon-hysteria2-server
|
||||
```
|
||||
|
||||
Для фиксации версии:
|
||||
```yaml
|
||||
hysteria2_server_version: "app/v2.5.1"
|
||||
```
|
||||
7
addons/hysteria2-server/playbook.yml
Normal file
7
addons/hysteria2-server/playbook.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Install Hysteria2 VPN Server
|
||||
hosts: hysteria2_server
|
||||
gather_facts: true
|
||||
become: true
|
||||
roles:
|
||||
- role: "{{ playbook_dir }}/role"
|
||||
50
addons/hysteria2-server/role/defaults/main.yml
Normal file
50
addons/hysteria2-server/role/defaults/main.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
# ─── Hysteria2 Server ─────────────────────────────────────────────────────────
|
||||
# Устанавливает Hysteria2 на удалённый VPS как системный сервис
|
||||
|
||||
# Версия — пустая строка = авто-определение последней с GitHub
|
||||
hysteria2_server_version: ""
|
||||
|
||||
# Порт прослушивания
|
||||
hysteria2_server_port: 443
|
||||
|
||||
# Пароль аутентификации клиентов
|
||||
hysteria2_server_password: "{{ vault_hysteria2_server_password }}"
|
||||
|
||||
# ─── TLS ──────────────────────────────────────────────────────────────────────
|
||||
# Режим: acme | selfsigned | custom
|
||||
# acme — Let's Encrypt (нужен домен + порт 80 открыт)
|
||||
# selfsigned — самоподписанный сертификат (клиент: insecure=1)
|
||||
# custom — указать свои cert/key файлы
|
||||
hysteria2_server_tls_mode: "selfsigned"
|
||||
|
||||
# Для acme:
|
||||
hysteria2_server_domain: "" # домен, e.g. "vpn.example.com"
|
||||
hysteria2_server_acme_email: "" # e-mail для Let's Encrypt
|
||||
|
||||
# Для custom:
|
||||
hysteria2_server_tls_cert_path: "/etc/hysteria/server.crt"
|
||||
hysteria2_server_tls_key_path: "/etc/hysteria/server.key"
|
||||
|
||||
# ─── Obfuscation (salamander) ─────────────────────────────────────────────────
|
||||
# Скрывает протокол от DPI — рекомендуется для обхода блокировок
|
||||
hysteria2_server_obfs_enabled: false
|
||||
hysteria2_server_obfs_password: "{{ vault_hysteria2_obfs_password | default('') }}"
|
||||
|
||||
# ─── Masquerade ───────────────────────────────────────────────────────────────
|
||||
# Делает трафик похожим на обычный HTTPS (важно для DPI)
|
||||
hysteria2_server_masquerade_enabled: true
|
||||
hysteria2_server_masquerade_url: "https://bing.com/"
|
||||
|
||||
# ─── Лимиты полосы пропускания (на клиента) ───────────────────────────────────
|
||||
# 0 = без ограничений
|
||||
hysteria2_server_up_mbps: 0
|
||||
hysteria2_server_down_mbps: 0
|
||||
|
||||
# ─── Пути ─────────────────────────────────────────────────────────────────────
|
||||
hysteria2_server_install_dir: /usr/local/bin
|
||||
hysteria2_server_config_dir: /etc/hysteria
|
||||
hysteria2_server_log_dir: /var/log/hysteria
|
||||
|
||||
# ─── Имя сервера (для метки в URL) ────────────────────────────────────────────
|
||||
hysteria2_server_name: "MyVPS"
|
||||
11
addons/hysteria2-server/role/handlers/main.yml
Normal file
11
addons/hysteria2-server/role/handlers/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Reload systemd
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
become: true
|
||||
|
||||
- name: Restart hysteria2
|
||||
ansible.builtin.systemd:
|
||||
name: hysteria2
|
||||
state: restarted
|
||||
become: true
|
||||
264
addons/hysteria2-server/role/tasks/main.yml
Normal file
264
addons/hysteria2-server/role/tasks/main.yml
Normal file
@@ -0,0 +1,264 @@
|
||||
---
|
||||
# ── Проверка обязательных переменных ─────────────────────────────────────────
|
||||
|
||||
- name: Assert required variables
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- hysteria2_server_password != ""
|
||||
- hysteria2_server_password != "vault_hysteria2_server_password"
|
||||
fail_msg: |
|
||||
Необходимо задать vault_hysteria2_server_password в group_vars/all/vault.yml
|
||||
Пример: vault_hysteria2_server_password: "my-secure-password"
|
||||
run_once: true
|
||||
|
||||
- name: Assert ACME requires domain
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- hysteria2_server_domain != ""
|
||||
- hysteria2_server_acme_email != ""
|
||||
fail_msg: |
|
||||
Для tls_mode=acme обязательны:
|
||||
hysteria2_server_domain: "vpn.example.com"
|
||||
hysteria2_server_acme_email: "admin@example.com"
|
||||
when: hysteria2_server_tls_mode == "acme"
|
||||
run_once: true
|
||||
|
||||
# ── Определить архитектуру ───────────────────────────────────────────────────
|
||||
|
||||
- name: Set CPU architecture fact
|
||||
ansible.builtin.set_fact:
|
||||
_hy2_arch: "{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"
|
||||
|
||||
# ── Получить последнюю версию с GitHub ───────────────────────────────────────
|
||||
|
||||
- name: Get latest Hysteria2 release from GitHub
|
||||
ansible.builtin.uri:
|
||||
url: https://api.github.com/repos/apernet/hysteria/releases/latest
|
||||
return_content: true
|
||||
headers:
|
||||
Accept: "application/vnd.github.v3+json"
|
||||
register: _hy2_github_release
|
||||
when: hysteria2_server_version == ""
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
|
||||
- name: Set Hysteria2 version fact
|
||||
ansible.builtin.set_fact:
|
||||
_hy2_version: >-
|
||||
{{ (hysteria2_server_version != '')
|
||||
| ternary(hysteria2_server_version,
|
||||
_hy2_github_release.json.tag_name | default('app/latest')) }}
|
||||
run_once: true
|
||||
|
||||
- name: Show Hysteria2 version
|
||||
ansible.builtin.debug:
|
||||
msg: "Installing Hysteria2 {{ _hy2_version }} ({{ _hy2_arch }})"
|
||||
|
||||
# ── Установить зависимости ────────────────────────────────────────────────────
|
||||
|
||||
- name: Install dependencies
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- curl
|
||||
- openssl
|
||||
- ca-certificates
|
||||
state: present
|
||||
become: true
|
||||
|
||||
# ── Создать системного пользователя и директории ─────────────────────────────
|
||||
|
||||
- name: Create hysteria group
|
||||
ansible.builtin.group:
|
||||
name: hysteria
|
||||
system: true
|
||||
state: present
|
||||
become: true
|
||||
|
||||
- name: Create hysteria user
|
||||
ansible.builtin.user:
|
||||
name: hysteria
|
||||
group: hysteria
|
||||
system: true
|
||||
shell: /sbin/nologin
|
||||
home: /var/lib/hysteria
|
||||
create_home: false
|
||||
comment: "Hysteria2 VPN Server"
|
||||
become: true
|
||||
|
||||
- name: Create directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: hysteria
|
||||
group: hysteria
|
||||
mode: "0750"
|
||||
loop:
|
||||
- "{{ hysteria2_server_config_dir }}"
|
||||
- "{{ hysteria2_server_log_dir }}"
|
||||
- /var/lib/hysteria
|
||||
become: true
|
||||
|
||||
# ── Скачать и установить бинарник ────────────────────────────────────────────
|
||||
|
||||
- name: Set download URL
|
||||
ansible.builtin.set_fact:
|
||||
_hy2_download_url: >-
|
||||
https://github.com/apernet/hysteria/releases/download/{{ _hy2_version }}/hysteria-linux-{{ _hy2_arch }}
|
||||
|
||||
- name: Download Hysteria2 binary
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ _hy2_download_url }}"
|
||||
dest: "{{ hysteria2_server_install_dir }}/hysteria"
|
||||
mode: "0755"
|
||||
owner: root
|
||||
group: root
|
||||
become: true
|
||||
register: _hy2_binary_downloaded
|
||||
notify: Restart hysteria2
|
||||
|
||||
# ── TLS сертификат ───────────────────────────────────────────────────────────
|
||||
|
||||
- name: Generate self-signed TLS certificate
|
||||
ansible.builtin.command: >
|
||||
openssl req -x509 -newkey rsa:4096 -keyout {{ hysteria2_server_tls_key_path }}
|
||||
-out {{ hysteria2_server_tls_cert_path }} -sha256 -days 3650 -nodes
|
||||
-subj "/CN={{ ansible_default_ipv4.address }}"
|
||||
args:
|
||||
creates: "{{ hysteria2_server_tls_cert_path }}"
|
||||
become: true
|
||||
when: hysteria2_server_tls_mode == "selfsigned"
|
||||
notify: Restart hysteria2
|
||||
|
||||
- name: Set permissions on TLS files
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
owner: hysteria
|
||||
group: hysteria
|
||||
mode: "0600"
|
||||
loop:
|
||||
- "{{ hysteria2_server_tls_cert_path }}"
|
||||
- "{{ hysteria2_server_tls_key_path }}"
|
||||
become: true
|
||||
when: hysteria2_server_tls_mode in ["selfsigned", "custom"]
|
||||
|
||||
# ── Конфигурация ─────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Template Hysteria2 config
|
||||
ansible.builtin.template:
|
||||
src: config.yaml.j2
|
||||
dest: "{{ hysteria2_server_config_dir }}/config.yaml"
|
||||
owner: hysteria
|
||||
group: hysteria
|
||||
mode: "0640"
|
||||
become: true
|
||||
notify: Restart hysteria2
|
||||
|
||||
# ── systemd сервис ────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Template systemd service
|
||||
ansible.builtin.template:
|
||||
src: hysteria2.service.j2
|
||||
dest: /etc/systemd/system/hysteria2.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
become: true
|
||||
notify:
|
||||
- Reload systemd
|
||||
- Restart hysteria2
|
||||
|
||||
- name: Enable and start Hysteria2
|
||||
ansible.builtin.systemd:
|
||||
name: hysteria2
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
become: true
|
||||
|
||||
# ── Firewall ─────────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Check if ufw is active
|
||||
ansible.builtin.command: ufw status
|
||||
register: _ufw_status
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
become: true
|
||||
|
||||
- name: Allow Hysteria2 port in ufw (TCP + UDP)
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ hysteria2_server_port | string }}"
|
||||
proto: "{{ item }}"
|
||||
comment: "Hysteria2 VPN"
|
||||
loop:
|
||||
- tcp
|
||||
- udp
|
||||
become: true
|
||||
when: "'active' in (_ufw_status.stdout | default(''))"
|
||||
|
||||
- name: Check if firewalld is running
|
||||
ansible.builtin.command: firewall-cmd --state
|
||||
register: _firewalld_status
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
become: true
|
||||
|
||||
- name: Allow Hysteria2 port in firewalld
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ hysteria2_server_port }}/{{ item }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
immediate: true
|
||||
loop:
|
||||
- tcp
|
||||
- udp
|
||||
become: true
|
||||
when: "_firewalld_status.stdout | default('') == 'running'"
|
||||
|
||||
# ── Проверить что сервис запустился ──────────────────────────────────────────
|
||||
|
||||
- name: Wait for Hysteria2 to start listening
|
||||
ansible.builtin.wait_for:
|
||||
port: "{{ hysteria2_server_port }}"
|
||||
host: "{{ ansible_default_ipv4.address }}"
|
||||
timeout: 30
|
||||
when: hysteria2_server_tls_mode != "acme"
|
||||
|
||||
- name: Verify Hysteria2 service status
|
||||
ansible.builtin.command: systemctl status hysteria2 --no-pager
|
||||
register: _hy2_service_status
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
# ── Вывести итоговый URL для клиента ─────────────────────────────────────────
|
||||
|
||||
- name: Build client connection URL
|
||||
ansible.builtin.set_fact:
|
||||
_hy2_client_url: >-
|
||||
hysteria2://{{ hysteria2_server_password | urlencode
|
||||
}}@{{ ansible_default_ipv4.address }}:{{ hysteria2_server_port
|
||||
}}{% if hysteria2_server_tls_mode == "selfsigned" %}?insecure=1{% else %}?insecure=0{% endif
|
||||
%}{% if hysteria2_server_obfs_enabled and hysteria2_server_obfs_password != ""
|
||||
%}&obfs=salamander&obfs-password={{ hysteria2_server_obfs_password | urlencode }}{% endif
|
||||
%}#{{ hysteria2_server_name | urlencode }}
|
||||
|
||||
- name: "=== Hysteria2 Server Ready ==="
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "╔══════════════════════════════════════════════════════════════╗"
|
||||
- "║ Hysteria2 Server установлен ║"
|
||||
- "╚══════════════════════════════════════════════════════════════╝"
|
||||
- ""
|
||||
- " Сервер: {{ ansible_default_ipv4.address }}:{{ hysteria2_server_port }}"
|
||||
- " TLS: {{ hysteria2_server_tls_mode }}"
|
||||
- " Obfs: {{ 'salamander' if hysteria2_server_obfs_enabled else 'отключён' }}"
|
||||
- ""
|
||||
- " ── URL для клиента (Shadowrocket / NekoBox / Hiddify) ───────"
|
||||
- " {{ _hy2_client_url }}"
|
||||
- ""
|
||||
- " ── vault.yml для использования с Prowlarr ───────────────────"
|
||||
- " vault_hysteria2_url: \"{{ _hy2_client_url }}\""
|
||||
- ""
|
||||
- " Логи: journalctl -u hysteria2 -f"
|
||||
- " Статус: systemctl status hysteria2"
|
||||
43
addons/hysteria2-server/role/templates/config.yaml.j2
Normal file
43
addons/hysteria2-server/role/templates/config.yaml.j2
Normal file
@@ -0,0 +1,43 @@
|
||||
listen: :{{ hysteria2_server_port }}
|
||||
|
||||
{% if hysteria2_server_tls_mode == "acme" %}
|
||||
acme:
|
||||
domains:
|
||||
- {{ hysteria2_server_domain }}
|
||||
email: {{ hysteria2_server_acme_email }}
|
||||
|
||||
{% elif hysteria2_server_tls_mode == "selfsigned" or hysteria2_server_tls_mode == "custom" %}
|
||||
tls:
|
||||
cert: {{ hysteria2_server_tls_cert_path }}
|
||||
key: {{ hysteria2_server_tls_key_path }}
|
||||
|
||||
{% endif %}
|
||||
auth:
|
||||
type: password
|
||||
password: {{ hysteria2_server_password }}
|
||||
|
||||
{% if hysteria2_server_obfs_enabled and hysteria2_server_obfs_password != "" %}
|
||||
obfs:
|
||||
type: salamander
|
||||
salamander:
|
||||
password: {{ hysteria2_server_obfs_password }}
|
||||
|
||||
{% endif %}
|
||||
{% if hysteria2_server_masquerade_enabled %}
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
url: {{ hysteria2_server_masquerade_url }}
|
||||
rewriteHost: true
|
||||
|
||||
{% endif %}
|
||||
{% if hysteria2_server_up_mbps | int > 0 or hysteria2_server_down_mbps | int > 0 %}
|
||||
bandwidth:
|
||||
{% if hysteria2_server_up_mbps | int > 0 %}
|
||||
up: {{ hysteria2_server_up_mbps }} mbps
|
||||
{% endif %}
|
||||
{% if hysteria2_server_down_mbps | int > 0 %}
|
||||
down: {{ hysteria2_server_down_mbps }} mbps
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
21
addons/hysteria2-server/role/templates/hysteria2.service.j2
Normal file
21
addons/hysteria2-server/role/templates/hysteria2.service.j2
Normal file
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Hysteria2 VPN Server
|
||||
Documentation=https://v2.hysteria.network/
|
||||
After=network.target network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=hysteria
|
||||
Group=hysteria
|
||||
ExecStart={{ hysteria2_server_install_dir }}/hysteria server --config {{ hysteria2_server_config_dir }}/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
LimitNOFILE=1048576
|
||||
|
||||
# Логи
|
||||
StandardOutput=append:{{ hysteria2_server_log_dir }}/hysteria2.log
|
||||
StandardError=append:{{ hysteria2_server_log_dir }}/hysteria2.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
7
addons/mediaserver/playbook.yml
Normal file
7
addons/mediaserver/playbook.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Install MediaServer (Plex, *arr, Transmission, Prowlarr+Hysteria2, Samba)
|
||||
hosts: k3s_master[0]
|
||||
gather_facts: false
|
||||
become: true
|
||||
roles:
|
||||
- role: "{{ playbook_dir }}/role"
|
||||
@@ -39,6 +39,7 @@ addon_external_secrets: false # External Secrets Operator → Vault/AWS/GCP
|
||||
addon_jenkins: false # Jenkins CI/CD (Helm, dynamic k8s agents, JCasC)
|
||||
addon_netbird: false # NetBird VPN (управляющий сервер + subnet router + exit node)
|
||||
addon_mediaserver: false # MediaServer — Plex, *arr, Transmission, Prowlarr+Hysteria2, Samba
|
||||
addon_hysteria2_server: false # Hysteria2 VPN сервер на удалённый VPS (группа [hysteria2_server] в inventory)
|
||||
|
||||
# ─── NFS Server ───────────────────────────────────────────────────────────────
|
||||
nfs_exports:
|
||||
|
||||
@@ -105,13 +105,20 @@ vault_plex_claim_token: ""
|
||||
# Hysteria2 SOCKS5 прокси (sidecar в Prowlarr)
|
||||
#
|
||||
# Способ 1 — вставить URL целиком из Shadowrocket / NekoBox / Hiddify:
|
||||
# URL генерируется аддоном hysteria2-server автоматически (make addon-hysteria2-server)
|
||||
vault_hysteria2_url: ""
|
||||
# Пример: vault_hysteria2_url: "hysteria2://mypassword@vps.example.com:443?insecure=0&obfs=salamander&obfs-password=secret"
|
||||
# Пример: vault_hysteria2_url: "hysteria2://mypassword@vps.example.com:443?insecure=1&obfs=salamander&obfs-password=secret"
|
||||
#
|
||||
# Способ 2 — указать параметры по отдельности (если vault_hysteria2_url пустой):
|
||||
vault_hysteria2_server: "your-hysteria2-server.example.com:443" # host:port
|
||||
vault_hysteria2_auth: "your-hysteria2-password" # пароль аутентификации
|
||||
|
||||
# ─── Hysteria2 VPN сервер (аддон hysteria2-server) ────────────────────────────
|
||||
# Пароль для клиентов, подключающихся к VPS
|
||||
vault_hysteria2_server_password: "changeme-hysteria2-server"
|
||||
# Пароль obfuscation salamander (если hysteria2_server_obfs_enabled: true)
|
||||
vault_hysteria2_obfs_password: ""
|
||||
|
||||
# Samba LAN-шара
|
||||
vault_samba_password: "changeme-samba"
|
||||
|
||||
|
||||
@@ -51,3 +51,11 @@ master01
|
||||
# nas01 ansible_host=192.168.1.30
|
||||
# devbox ansible_host=192.168.1.31
|
||||
# proxy01 ansible_host=192.168.1.32
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Hysteria2 VPN сервер (удалённый VPS — НЕ часть k3s кластера)
|
||||
# Используется аддоном: make addon-hysteria2-server
|
||||
# Подключение: SSH ключ (рекомендуется) или make addon-hysteria2-server ARGS="-k"
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
[hysteria2_server]
|
||||
# myvps ansible_host=1.2.3.4 ansible_user=root
|
||||
|
||||
@@ -279,3 +279,11 @@
|
||||
when: addon_mediaserver | default(false) | bool
|
||||
roles:
|
||||
- role: "{{ playbook_dir }}/../addons/mediaserver/role"
|
||||
|
||||
- name: Install Hysteria2 VPN Server on remote VPS
|
||||
hosts: hysteria2_server
|
||||
gather_facts: true
|
||||
become: true
|
||||
when: addon_hysteria2_server | default(false) | bool
|
||||
roles:
|
||||
- role: "{{ playbook_dir }}/../addons/hysteria2-server/role"
|
||||
|
||||
Reference in New Issue
Block a user