diff --git a/README.md b/README.md index 0255b1b..79bc7e1 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,20 @@ apt install -y openssh-server ca-certificates curl ### 2. Настроить SSH до установки Amnezia -Production-пример использует порт `2323` и вход только по ключу. Сначала убедитесь, что публичный ключ уже добавлен в `~root/.ssh/authorized_keys` или в ключевой файл нужного sudo-пользователя. +Production-пример использует порт `2323` и вход только по ключу. -Для SSH через Amnezia используйте ключ в стандартном OpenSSH public key формате (строка вида `ssh-rsa AAAA... comment` в `authorized_keys`). Практически это означает, что Amnezia ожидает именно публичный ключ в формате OpenSSH authorized_keys. +Сгенерируйте отдельную пару ключей для Amnezia на Windows (RSA PEM-формат): + +```cmd +ssh-keygen -t rsa -b 4096 -m PEM -f %USERPROFILE%\.ssh\amnezia_key +``` + +Дальше контракт строго такой: + +- на сервер добавляется **публичный** ключ: содержимое `%USERPROFILE%\.ssh\amnezia_key.pub` в `/root/.ssh/authorized_keys`; +- в приложении AmneziaVPN в поле **Password or SSH private key** вставляется **приватный** ключ: содержимое `%USERPROFILE%\.ssh\amnezia_key` (без `.pub`). + +Критично: `.pub` никогда не вставляется в AmneziaVPN как private key. ```bash install -d -m 0700 /root/.ssh @@ -77,7 +88,24 @@ ss -ltnp | grep ':2323' Критично: не закрывайте старую SSH-сессию, пока не проверили новый вход с другого терминала: ```bash -ssh -p 2323 root@ +ssh -i ~/.ssh/amnezia_key -p 2323 root@ +``` + +Windows-проверки: + +```cmd +type %USERPROFILE%\.ssh\amnezia_key.pub +type %USERPROFILE%\.ssh\amnezia_key +ssh -i %USERPROFILE%\.ssh\amnezia_key -p 2323 root@ +``` + +Поля в интерфейсе AmneziaVPN: + +```text +Server IP address [:port] :2323 +SSH Username root +Password or SSH private key содержимое %USERPROFILE%\.ssh\amnezia_key +На сервер содержимое %USERPROFILE%\.ssh\amnezia_key.pub в /root/.ssh/authorized_keys ``` Если сервер уже переведён на 2323 случайно и нужно временно вернуть 22 для тестов, поменяйте `Port 2323` на `Port 22`, выполните `sshd -t`, `systemctl reload ssh` и проверьте `ss -ltnp | grep ':22'`. @@ -121,6 +149,10 @@ dpkg-deb -c dist/awg2-harness_0.1.6_amd64.deb | sort ### 5. Перенести `.deb` и config на production +Есть два production-сценария установки. + +#### Вариант A: config передаётся вместе с `.deb` + ```bash scp -P 2323 dist/awg2-harness_*_amd64.deb root@:/root/ scp -P 2323 dist/SHA256SUMS root@:/root/ @@ -129,8 +161,17 @@ scp -P 2323 config.example.toml root@:/root/awg2-harness.config.toml Перед установкой отредактируйте `/root/awg2-harness.config.toml`: SSH-порт должен совпадать с реальным sshd, `amnezia_port` — с опубликованным UDP-портом контейнера, `peer_ipv4_cidr` — с подсетью клиентов Amnezia. +#### Вариант B (основной): config создаётся после установки пакета + +```bash +scp -P 2323 dist/awg2-harness_*_amd64.deb root@:/root/ +scp -P 2323 dist/SHA256SUMS root@:/root/ +``` + ### 6. Установить пакет и config +Вариант A: + ```bash cd /root sha256sum -c SHA256SUMS @@ -141,6 +182,23 @@ install -m 0644 /root/awg2-harness.config.toml /etc/awg2-harness/config.toml Пакет ставит пример config в `/usr/share/doc/awg2-harness/repo/config.example.toml`, но не копирует его в `/etc` автоматически. +Вариант B (основной): + +```bash +cd /root +sha256sum -c SHA256SUMS +apt install ./awg2-harness_*_amd64.deb +install -d -m 0755 /etc/awg2-harness +cp /usr/share/doc/awg2-harness/repo/config.example.toml /etc/awg2-harness/config.toml +nano /etc/awg2-harness/config.toml +``` + +В варианте B после `cp` обязательно проверьте перед первым `apply-firewall`: + +- `host_firewall.ssh_port` совпадает с реальным sshd-портом; +- `host_firewall.amnezia_port` совпадает с published Docker UDP port; +- `amnezia.peer_ipv4_cidr` и `anti_torrent.peer_ipv4_cidr` совпадают с реальной peer-подсетью. + ### 7. Ручная preflight-проверка ```bash @@ -280,5 +338,6 @@ AWG2 Harness не владеет: - [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) — параметры `config.toml`. - [`docs/ACCEPTANCE_CHECKLIST.md`](docs/ACCEPTANCE_CHECKLIST.md) — production checklist. - [`docs/ANTI_TORRENT.md`](docs/ANTI_TORRENT.md) — connection-count guard. +- [`docs/PRODUCTION_EXAMPLE.md`](docs/PRODUCTION_EXAMPLE.md) — эталонный production-пример. - [`tools/README.md`](tools/README.md) — сборка и упаковка. - [`reboot_module/README.md`](reboot_module/README.md) — внешний reboot scheduler. diff --git a/config.example.toml b/config.example.toml index ff7c560..eca0426 100644 --- a/config.example.toml +++ b/config.example.toml @@ -2,6 +2,11 @@ container_names = ["amnezia-awg2", "amnezia-awg"] interface_candidates = ["awg0", "wg0", "amnezia0", "tun0"] interface_patterns = ["awg*", "wg*", "amnezia*", "tun*"] +# VPN peer subnet. +# Verify with: +# C="$(docker ps --format '{{.Names}}' | grep -E '^(amnezia-awg2|amnezia-awg)$' | head -n1)" +# docker exec "$C" ip -4 addr +# docker exec "$C" wg show peer_ipv4_cidr = "10.8.1.0/24" [traffic] @@ -15,7 +20,10 @@ ifb_name = "ifb0" [host_firewall] enabled = true +# Must match the real sshd port before apply-firewall. ssh_port = 2323 +# Must match the published Docker/Amnezia UDP port. +# Verify with: docker port amnezia-awg2 2>/dev/null || docker port amnezia-awg amnezia_port = 443 amnezia_protocols = ["udp"] allow_icmp = true @@ -24,6 +32,7 @@ default_input_policy = "drop" [anti_torrent] enabled = true max_connections_per_peer = 150 +# Usually the same subnet as [amnezia].peer_ipv4_cidr. peer_ipv4_cidr = "10.8.1.0/24" apply_in_amnezia_netns = true diff --git a/docs/ACCEPTANCE_CHECKLIST.md b/docs/ACCEPTANCE_CHECKLIST.md index c82fbef..4c72ab5 100644 --- a/docs/ACCEPTANCE_CHECKLIST.md +++ b/docs/ACCEPTANCE_CHECKLIST.md @@ -135,6 +135,15 @@ - [ ] После ручной установки config `awg2-harness validate-config` проходит. - [ ] Сервис стартует только после явного `systemctl enable --now awg2-harness.service`. +## K2. Documentation / install UX + +- [ ] README не утверждает, что AmneziaVPN ожидает public key. +- [ ] Документация явно разделяет private key для AmneziaVPN и public key для `authorized_keys`. +- [ ] Есть пример заполнения AmneziaVPN fields: `Server IP address [:port]`, `SSH Username`, `Password or SSH private key`. +- [ ] Описаны Windows пути `%USERPROFILE%\.ssh\amnezia_key` и `%USERPROFILE%\.ssh\amnezia_key.pub`. +- [ ] Описан runtime config bootstrap из `/usr/share/doc/awg2-harness/repo/config.example.toml`. +- [ ] Clean install подтверждает, что `/etc/awg2-harness/config.toml` не создаётся автоматически. + ## L. Host firewall (ports/SSH safety) - [ ] `awg2-harness validate-config` падает, если отсутствует секция `[host_firewall]`. diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 6d43f80..7ff7d80 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -2,6 +2,35 @@ AWG2 Harness разрабатывался для self-hosted AmneziaWG/AWG 2.0 и совместимого legacy-сценария AmneziaWG/AWG 1.5. Конфиг живёт в `/etc/awg2-harness/config.toml`. Он общий для всего пакета и должен содержать только эксплуатационно значимые параметры. +## Создание runtime config + +Пакет намеренно **не** создаёт `/etc/awg2-harness/config.toml` автоматически. Это снижает риск случайно применить firewall с неверным SSH-портом или неверным Amnezia-портом. + +После установки `.deb` создайте runtime config вручную: + +```bash +install -d -m 0755 /etc/awg2-harness +cp /usr/share/doc/awg2-harness/repo/config.example.toml /etc/awg2-harness/config.toml +nano /etc/awg2-harness/config.toml +``` + +Перед первым `apply-firewall`/`apply-limits` оператор обязан сверить: + +- `host_firewall.ssh_port` — должен совпадать с реально слушающим `sshd` портом; +- `host_firewall.amnezia_port` — должен совпадать с published Docker/Amnezia UDP port; +- `amnezia.peer_ipv4_cidr` — должен совпадать с реальной peer-подсетью; +- `anti_torrent.peer_ipv4_cidr` — обычно тот же CIDR. + +Discovery-команды: + +```bash +docker port amnezia-awg2 2>/dev/null || docker port amnezia-awg + +C="$(docker ps --format '{{.Names}}' | grep -E '^(amnezia-awg2|amnezia-awg)$' | head -n1)" +docker exec "$C" ip -4 addr +docker exec "$C" wg show +``` + ## Рекомендуемый `config.toml` ```toml diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 972ce99..97a1409 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -51,6 +51,27 @@ dpkg-deb -c dist/awg2-harness_0.1.6_amd64.deb | sort ### B1. SSH +Сначала сгенерируйте отдельную пару ключей для Amnezia на Windows (RSA PEM): + +```cmd +ssh-keygen -t rsa -b 4096 -m PEM -f %USERPROFILE%\.ssh\amnezia_key +``` + +Дальше разделяйте ключи строго: + +- на сервер в `/root/.ssh/authorized_keys` кладётся содержимое `%USERPROFILE%\.ssh\amnezia_key.pub`; +- в AmneziaVPN в поле `Password or SSH private key` вставляется содержимое `%USERPROFILE%\.ssh\amnezia_key` (без `.pub`). + +`.pub` нельзя вставлять в поле private key в AmneziaVPN. + +Установка `.pub` на сервер: + +```bash +install -d -m 0700 /root/.ssh +nano /root/.ssh/authorized_keys +chmod 0600 /root/.ssh/authorized_keys +``` + Production-пример: ```bash @@ -69,13 +90,37 @@ ss -ltnp | grep ':2323' Обязательно проверьте вход с нового терминала: -```bash -ssh -p 2323 root@ +```cmd +ssh -i %USERPROFILE%\.ssh\amnezia_key -p 2323 root@ +``` + +Проверить содержимое ключей в Windows: + +```cmd +type %USERPROFILE%\.ssh\amnezia_key.pub +type %USERPROFILE%\.ssh\amnezia_key ``` ### B2. Amnezia -Установите AmneziaWG/AWG через официальное приложение AmneziaVPN в режиме self-hosted server. Вводите в приложении тот SSH host/port/user/private key, который реально работает после B1. +Установите AmneziaWG/AWG через официальное приложение AmneziaVPN в режиме self-hosted server. + +Заполнение полей в интерфейсе AmneziaVPN: + +```text +Configure your server: + +Server IP address [:port]: +:2323 + +SSH Username: +root + +Password or SSH private key: +полное содержимое приватного ключа %USERPROFILE%\.ssh\amnezia_key +``` + +Важно: в это поле не вставляется `.pub`. Файл `.pub` нужен только для `/root/.ssh/authorized_keys` на сервере. Проверка после установки: @@ -91,6 +136,10 @@ docker exec "$C" wg show ## C. Transfer artifacts +Ниже два production-сценария установки. + +### C1. Вариант A: config передаётся вместе с `.deb` + ```bash scp -P 2323 dist/awg2-harness_*_amd64.deb root@:/root/ scp -P 2323 dist/SHA256SUMS root@:/root/ @@ -105,8 +154,17 @@ scp -P 2323 config.example.toml root@:/root/awg2-harness.config.toml - `[anti_torrent].peer_ipv4_cidr` обычно равен `[amnezia].peer_ipv4_cidr`; - `peer_limit` и `root_rate` отражают нужную traffic policy. +### C2. Вариант B (основной): config создаётся на production после установки + +```bash +scp -P 2323 dist/awg2-harness_*_amd64.deb root@:/root/ +scp -P 2323 dist/SHA256SUMS root@:/root/ +``` + ## D. Production install +### D1. Вариант A + ```bash cd /root sha256sum -c SHA256SUMS @@ -116,6 +174,25 @@ install -m 0644 /root/awg2-harness.config.toml /etc/awg2-harness/config.toml systemctl daemon-reload ``` +### D2. Вариант B (основной) + +```bash +cd /root +sha256sum -c SHA256SUMS +apt install ./awg2-harness_*_amd64.deb +install -d -m 0755 /etc/awg2-harness +cp /usr/share/doc/awg2-harness/repo/config.example.toml /etc/awg2-harness/config.toml +nano /etc/awg2-harness/config.toml +systemctl daemon-reload +``` + +Перед первым `apply-firewall` обязательно перепроверьте: + +- `[host_firewall].ssh_port` совпадает с реально слушающим `sshd` портом; +- `[host_firewall].amnezia_port` совпадает с published Docker UDP port; +- `[amnezia].peer_ipv4_cidr` совпадает с peer-подсетью; +- `[anti_torrent].peer_ipv4_cidr` обычно тот же CIDR. + ## E. Preflight before enable ```bash diff --git a/docs/PRODUCTION_EXAMPLE.md b/docs/PRODUCTION_EXAMPLE.md new file mode 100644 index 0000000..9e4a1c8 --- /dev/null +++ b/docs/PRODUCTION_EXAMPLE.md @@ -0,0 +1,48 @@ +# Production example (reference) + +Этот пример фиксирует эталонный production-state после успешной установки и preflight. Значения обезличены и предназначены как reference для smoke-проверки. + +```text +SSH: + host: + port: 2323 + user: root + +Amnezia: + container: amnezia-awg2 + interface: awg0 + published UDP: 443 + peer CIDR: 10.8.1.0/24 + +Expected status: + service: active + traffic drift: no + host firewall drift: no + anti-torrent drift: no + swap drift: no +``` + +Проверка ключевых сигналов: + +```bash +systemctl status awg2-harness.service --no-pager -l +systemctl status awg2-reboot-scheduler.service --no-pager -l +awg2-harness --config /etc/awg2-harness/config.toml status +``` + +Проверка Docker/Amnezia runtime: + +```bash +docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' +C="$(docker ps --format '{{.Names}}' | grep -E '^(amnezia-awg2|amnezia-awg)$' | head -n1)" +docker port "$C" +docker exec "$C" wg show +``` + +Проверка, что runtime config создан вручную (ожидаемое поведение): + +```bash +test -f /etc/awg2-harness/config.toml && echo "runtime config present" +``` + +Если файл отсутствует после `apt install`, это корректно: создайте его вручную из `/usr/share/doc/awg2-harness/repo/config.example.toml`. diff --git a/tools/README.md b/tools/README.md index 3326320..5a0515f 100644 --- a/tools/README.md +++ b/tools/README.md @@ -53,6 +53,25 @@ scp -P 2323 dist/awg2-harness__amd64.deb root@:/root/ scp -P 2323 dist/SHA256SUMS root@:/root/ ``` +## Runtime config bootstrap на production + +`--package` кладёт `config.example.toml` только в: + +```text +/usr/share/doc/awg2-harness/repo/config.example.toml +``` + +Боевой `/etc/awg2-harness/config.toml` создаётся вручную после установки пакета: + +```bash +apt install ./awg2-harness__amd64.deb +install -d -m 0755 /etc/awg2-harness +cp /usr/share/doc/awg2-harness/repo/config.example.toml /etc/awg2-harness/config.toml +nano /etc/awg2-harness/config.toml +``` + +Перед первым `apply-firewall` обязательно сверяйте `ssh_port`, `amnezia_port` и `peer_ipv4_cidr` с реальным состоянием хоста и Amnezia. + ## Что скрипт намеренно не делает - не устанавливает AmneziaVPN; diff --git a/tools/build.sh b/tools/build.sh index 790ce10..e5491a3 100644 --- a/tools/build.sh +++ b/tools/build.sh @@ -370,6 +370,16 @@ if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload || true fi +echo "AWG2 Harness installed." +echo "Runtime config is not created automatically by design." +echo "Create /etc/awg2-harness/config.toml manually before enabling services:" +echo " install -d -m 0755 /etc/awg2-harness" +echo " cp /usr/share/doc/awg2-harness/repo/config.example.toml /etc/awg2-harness/config.toml" +echo " nano /etc/awg2-harness/config.toml" +echo "Then validate and enable services:" +echo " awg2-harness --config /etc/awg2-harness/config.toml validate-config" +echo " systemctl enable --now awg2-harness.service awg2-reboot-scheduler.service" + exit 0 EOF