302 lines
9.8 KiB
Markdown
302 lines
9.8 KiB
Markdown
# Installation
|
||
|
||
Этот документ описывает production-порядок установки AWG2 Harness. Подробный runtime-план с SSH hardening и Amnezia preflight находится в корневом [`README.md`](../README.md).
|
||
|
||
## Deployment contract
|
||
|
||
- Целевой production-хост: Debian 13 amd64.
|
||
- Amnezia ставится до AWG2 Harness официальным self-hosted способом через приложение AmneziaVPN.
|
||
- Проект рассчитан на AmneziaWG/AWG 2.0 и compatible legacy-сценарий AmneziaWG/AWG 1.5.
|
||
- SSH должен быть заранее настроен. Production-пример: порт `2323`, вход по ключу, password login disabled.
|
||
- Production-хост получает готовый Debian-пакет; Rust/cargo/source tree на нём не требуются.
|
||
- `/etc/awg2-harness/config.toml` создаётся вручную. `config.example.toml` не копируется автоматически как боевой config.
|
||
- Пакет не устанавливает Docker/Amnezia и не включает services автоматически.
|
||
|
||
## A. Build machine
|
||
|
||
### A1. Подготовить build environment
|
||
|
||
```bash
|
||
cd awg2_harness
|
||
chmod +x tools/build.sh
|
||
./tools/build.sh --prepare-build-env --bootstrap-rust --yes
|
||
```
|
||
|
||
### A2. Проверить код
|
||
|
||
```bash
|
||
cargo fmt --manifest-path Cargo.toml --all --check
|
||
cargo clippy --locked --workspace --all-targets --manifest-path Cargo.toml -- -D warnings
|
||
cargo test --locked --workspace --release --manifest-path Cargo.toml
|
||
```
|
||
|
||
То же самое выполняет build helper:
|
||
|
||
```bash
|
||
./tools/build.sh --build
|
||
```
|
||
|
||
### A3. Собрать Debian-пакет
|
||
|
||
```bash
|
||
./tools/build.sh --package --version 0.1.6
|
||
sha256sum -c dist/SHA256SUMS
|
||
dpkg-deb -I dist/awg2-harness_0.1.6_amd64.deb
|
||
dpkg-deb -c dist/awg2-harness_0.1.6_amd64.deb | sort
|
||
```
|
||
|
||
`--version` можно опустить, если версия в `traffic_core/Cargo.toml` уже равна release version. Version override влияет только на metadata `.deb`.
|
||
|
||
## B. Подготовить production-хост
|
||
|
||
### 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
|
||
install -d -m 0755 /etc/ssh/sshd_config.d
|
||
cat >/etc/ssh/sshd_config.d/99-awg2-production.conf <<'EOF'
|
||
Port 2323
|
||
PermitRootLogin prohibit-password
|
||
PasswordAuthentication no
|
||
KbdInteractiveAuthentication no
|
||
PubkeyAuthentication yes
|
||
EOF
|
||
sshd -t
|
||
systemctl reload ssh 2>/dev/null || systemctl reload sshd
|
||
ss -ltnp | grep ':2323'
|
||
```
|
||
|
||
Обязательно проверьте вход с нового терминала:
|
||
|
||
```cmd
|
||
ssh -i %USERPROFILE%\.ssh\amnezia_key -p 2323 root@<server-ip>
|
||
```
|
||
|
||
Проверить содержимое ключей в Windows:
|
||
|
||
```cmd
|
||
type %USERPROFILE%\.ssh\amnezia_key.pub
|
||
type %USERPROFILE%\.ssh\amnezia_key
|
||
```
|
||
|
||
### B2. Amnezia
|
||
|
||
Установите AmneziaWG/AWG через официальное приложение AmneziaVPN в режиме self-hosted server.
|
||
|
||
Заполнение полей в интерфейсе AmneziaVPN:
|
||
|
||
```text
|
||
Configure your server:
|
||
|
||
Server IP address [:port]:
|
||
<server-ip>:2323
|
||
|
||
SSH Username:
|
||
root
|
||
|
||
Password or SSH private key:
|
||
полное содержимое приватного ключа %USERPROFILE%\.ssh\amnezia_key
|
||
```
|
||
|
||
Важно: в это поле не вставляется `.pub`. Файл `.pub` нужен только для `/root/.ssh/authorized_keys` на сервере.
|
||
|
||
Проверка после установки:
|
||
|
||
```bash
|
||
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
|
||
C="$(docker ps --format '{{.Names}}' | grep -E '^(amnezia-awg2|amnezia-awg)$' | head -n1)"
|
||
echo "container=$C"
|
||
docker port "$C"
|
||
docker exec "$C" wg show
|
||
```
|
||
|
||
Если контейнер называется иначе или интерфейс не `awg0`, отразите это в `/etc/awg2-harness/config.toml`.
|
||
|
||
### B3. Установить AmneziaDNS
|
||
|
||
Установите AmneziaDNS из desktop-приложения AmneziaVPN:
|
||
|
||
```text
|
||
Servers → <server> → Services → AmneziaDNS → Install
|
||
```
|
||
|
||
Затем включите его для подключения:
|
||
|
||
```text
|
||
Settings → Connection → DNS servers → Use AmneziaDNS
|
||
```
|
||
|
||
Ожидаемое состояние Docker:
|
||
|
||
```bash
|
||
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
|
||
```
|
||
|
||
Ожидаемая строка для DNS-контейнера:
|
||
|
||
```text
|
||
amnezia-dns amnezia-dns Up ... (healthy) 53/tcp, 53/udp
|
||
```
|
||
|
||
Проверка публикации портов:
|
||
|
||
```bash
|
||
docker inspect -f 'ports={{json .NetworkSettings.Ports}}' amnezia-dns
|
||
docker inspect -f 'networks={{range $n,$v := .NetworkSettings.Networks}}{{printf "%s=%s " $n $v.IPAddress}}{{end}}' amnezia-dns
|
||
docker inspect -f 'networks={{range $n,$v := .NetworkSettings.Networks}}{{printf "%s=%s " $n $v.IPAddress}}{{end}}' amnezia-awg2
|
||
```
|
||
|
||
Ожидаемый результат по портам:
|
||
|
||
```text
|
||
ports={"53/tcp":null,"53/udp":null}
|
||
```
|
||
|
||
Это означает, что DNS не опубликован на публичном host-интерфейсе и остаётся доступным только через VPN/Docker path.
|
||
|
||
## C. Transfer artifacts
|
||
|
||
Ниже два production-сценария установки.
|
||
|
||
### C1. Вариант A: config передаётся вместе с `.deb`
|
||
|
||
```bash
|
||
scp -P 2323 dist/awg2-harness_*_amd64.deb root@<server-ip>:/root/
|
||
scp -P 2323 dist/SHA256SUMS root@<server-ip>:/root/
|
||
scp -P 2323 config.example.toml root@<server-ip>:/root/awg2-harness.config.toml
|
||
```
|
||
|
||
Перед установкой отредактируйте `/root/awg2-harness.config.toml`. Минимально проверьте:
|
||
|
||
- `[host_firewall].ssh_port` совпадает с реальным SSH-портом (`2323` в production-примере);
|
||
- `[host_firewall].amnezia_port` совпадает с published UDP port Amnezia;
|
||
- `[amnezia].peer_ipv4_cidr` совпадает с подсетью clients;
|
||
- `[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@<server-ip>:/root/
|
||
scp -P 2323 dist/SHA256SUMS root@<server-ip>:/root/
|
||
```
|
||
|
||
## D. Production install
|
||
|
||
### D1. Вариант A
|
||
|
||
```bash
|
||
cd /root
|
||
sha256sum -c SHA256SUMS
|
||
apt install ./awg2-harness_*_amd64.deb
|
||
install -d -m 0755 /etc/awg2-harness
|
||
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
|
||
awg2-harness --config /etc/awg2-harness/config.toml validate-config
|
||
awg2-harness --config /etc/awg2-harness/config.toml validate-runtime
|
||
awg2-harness --config /etc/awg2-harness/config.toml ensure-swap
|
||
awg2-harness --config /etc/awg2-harness/config.toml apply-firewall
|
||
awg2-harness --config /etc/awg2-harness/config.toml apply-limits
|
||
awg2-harness --config /etc/awg2-harness/config.toml status
|
||
```
|
||
|
||
Expected healthy result:
|
||
|
||
```text
|
||
Traffic actual:
|
||
drift: no
|
||
Host firewall:
|
||
drift: no
|
||
Anti-torrent:
|
||
drift: no
|
||
Swap:
|
||
drift: no
|
||
```
|
||
|
||
If there are no peers yet, `apply-limits` may print `no peers found, skip tc apply`. That is healthy for an empty server.
|
||
|
||
When `swap.enabled=true`, AWG2 Harness intentionally makes swap exclusive: one managed swapfile, one fstab swap entry, configured swappiness.
|
||
|
||
## F. Enable services
|
||
|
||
```bash
|
||
systemctl enable --now awg2-harness.service
|
||
systemctl enable --now awg2-reboot-scheduler.service
|
||
|
||
systemctl status awg2-harness.service --no-pager -l
|
||
systemctl status awg2-reboot-scheduler.service --no-pager -l
|
||
journalctl -u awg2-harness.service --since '5 minutes ago' --no-pager
|
||
journalctl -u awg2-reboot-scheduler.service --since '5 minutes ago' --no-pager
|
||
```
|
||
|
||
After 30–60 seconds:
|
||
|
||
```bash
|
||
awg2-harness --config /etc/awg2-harness/config.toml status
|
||
```
|
||
|
||
## G. Reboot validation
|
||
|
||
```bash
|
||
reboot
|
||
```
|
||
|
||
After reconnect:
|
||
|
||
```bash
|
||
systemctl status docker --no-pager -l
|
||
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
|
||
```
|
||
|
||
## H. Manual source-tree install
|
||
|
||
`./tools/build.sh --install` and `./tools/build.sh --enable` exist for staging/debug. They are not the recommended production path. Use `.deb` on production.
|