fix28: обновлена production-документация и упаковка docs в deb
This commit is contained in:
@@ -1,69 +1,285 @@
|
||||
# AWG2 Harness
|
||||
|
||||
`AWG2 Harness` — host-side multi-orchestrator на Rust для production-сервера с AmneziaWG/AWG 2.0.
|
||||
`AWG2 Harness` — host-side orchestrator для выделенного Debian-хоста с self-hosted AmneziaWG. Пакет управляет инфраструктурным состоянием вокруг Amnezia: per-peer traffic shaping, IFB ingress shaping, nftables host firewall, anti-torrent connection guard, managed swap, диагностикой drift и плановым reboot.
|
||||
|
||||
Это не просто перенос bash-скриптов на Rust. Целевая система должна воспроизвести и затем постоянно удерживать всё состояние, которое сейчас создаёт `Amnezia limits (old bash)`: discovery контейнера и интерфейса, список peers, per-peer traffic shaping в обе стороны, `tc` topology, `ifb0`, auto-healing после рестартов, диагностику, плановый reboot и swap setup, а также опциональный nftables anti-torrent guard через per-peer connection-count limit.
|
||||
Проект разрабатывался и проверялся под AmneziaWG/AWG 2.0 и совместимый legacy-сценарий AmneziaWG/AWG 1.5. Он не заменяет AmneziaVPN, не генерирует ключи клиентов и не меняет продуктовую логику Amnezia. Amnezia сначала ставится официальным способом, после этого устанавливается AWG2 Harness.
|
||||
|
||||
Сервер выделенный: Debian 13 amd64, SSH заранее настроен, рядом нет соседних сервисов, после установки Amnezia доставляется наш бинарь. Поэтому бинарь имеет право и обязан полностью управлять нужными правилами хоста и network namespace Amnezia, а не быть пассивной обёрткой, которая боится менять состояние системы. При этом он не форкает Amnezia и не меняет её продуктовую логику; он управляет инфраструктурным состоянием вокруг неё.
|
||||
|
||||
Текущий репозиторий:
|
||||
## Что ставит пакет
|
||||
|
||||
```text
|
||||
AWG2_harness/
|
||||
├── Amnezia limits (old bash)/ # production reference behavior
|
||||
├── reboot_module/ # production auxiliary binary: awg2-reboot-scheduler
|
||||
├── traffic_core/ # целевая зона для Rust traffic/orchestrator логики
|
||||
└── docs/ # документация по миграции, архитектуре и эксплуатации
|
||||
/usr/sbin/awg2-harness # основной orchestrator
|
||||
/usr/sbin/awg2-reboot-scheduler # отдельный reboot scheduler
|
||||
/lib/systemd/system/awg2-harness.service
|
||||
/lib/systemd/system/awg2-reboot-scheduler.service
|
||||
```
|
||||
|
||||
Production reboot path — внешний scheduler service [`awg2-reboot-scheduler.service`](awg2-reboot-scheduler.service).
|
||||
`awg2-harness.service` запускает `ensure-swap` перед стартом daemon, затем в фоне держит drift recovery. Daemon слушает Docker events и дополнительно делает периодический reconcile. `awg2-reboot-scheduler.service` отдельно читает общий config, выбирает случайное время в заданном UTC-окне и запрашивает reboot через `systemctl --no-block reboot`.
|
||||
|
||||
Важно: `Amnezia limits (old bash)` используется как эталон production-поведения, а `reboot_module` ставится как второй production-бинарь.
|
||||
Пакет **не** устанавливает Docker, **не** устанавливает AmneziaVPN, **не** включает сервисы автоматически и **не** создаёт боевой `/etc/awg2-harness/config.toml`. Это сделано намеренно: SSH, Amnezia и боевой config должны быть подготовлены оператором до включения firewall/reconcile.
|
||||
|
||||
## Production deployment model
|
||||
## Репозиторий
|
||||
|
||||
AWG2 Harness собирается на отдельной Debian 13 amd64 build-machine.
|
||||
```text
|
||||
awg2_harness/
|
||||
├── Amnezia limits (old bash)/ # исторический reference старой bash-схемы
|
||||
├── reboot_module/ # исходники awg2-reboot-scheduler
|
||||
├── traffic_core/ # исходники awg2-harness
|
||||
├── tools/ # build/package tooling
|
||||
├── docs/ # эксплуатационная документация
|
||||
├── config.example.toml # пример боевого конфига
|
||||
├── awg2-harness.service # основной systemd unit
|
||||
└── awg2-reboot-scheduler.service # reboot scheduler unit
|
||||
```
|
||||
|
||||
Production Amnezia-хост **не должен** требовать Rust, cargo, clippy, source tree и legacy bash-скрипты. На production-хост переносится готовый Debian-пакет и вручную подготовленный `/etc/awg2-harness/config.toml`.
|
||||
`Amnezia limits (old bash)` оставлен как historical reference, а не как runtime-зависимость. На production-хосте после перехода на `.deb` source tree и старые bash-скрипты не нужны.
|
||||
|
||||
Build machine:
|
||||
## Runtime-план production-развёртывания
|
||||
|
||||
Ниже целевой порядок установки. Его смысл простой: сначала безопасный SSH, потом официальная Amnezia, потом AWG2 Harness.
|
||||
|
||||
### 1. Подготовить Debian-хост
|
||||
|
||||
Целевая платформа проекта — Debian 13 amd64 на KVM/полноценной VM или dedicated host. Для Amnezia upstream также указывает Debian 12/13 и Ubuntu 22.04/24.04 как официально поддерживаемые OS, x86-64/amd64, публичный IPv4, SSH-доступ и Docker-based self-hosted deployment через приложение AmneziaVPN.
|
||||
|
||||
Минимальный baseline перед установкой Amnezia:
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt install -y openssh-server ca-certificates curl
|
||||
```
|
||||
|
||||
### 2. Настроить SSH до установки Amnezia
|
||||
|
||||
Production-пример использует порт `2323` и вход только по ключу. Сначала убедитесь, что публичный ключ уже добавлен в `~root/.ssh/authorized_keys` или в ключевой файл нужного sudo-пользователя.
|
||||
|
||||
```bash
|
||||
install -d -m 0700 /root/.ssh
|
||||
nano /root/.ssh/authorized_keys
|
||||
chmod 0600 /root/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
Затем включите отдельный drop-in для порта и key-only login:
|
||||
|
||||
```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'
|
||||
```
|
||||
|
||||
Критично: не закрывайте старую SSH-сессию, пока не проверили новый вход с другого терминала:
|
||||
|
||||
```bash
|
||||
ssh -p 2323 root@<server-ip>
|
||||
```
|
||||
|
||||
Если сервер уже переведён на 2323 случайно и нужно временно вернуть 22 для тестов, поменяйте `Port 2323` на `Port 22`, выполните `sshd -t`, `systemctl reload ssh` и проверьте `ss -ltnp | grep ':22'`.
|
||||
|
||||
### 3. Установить AmneziaVPN официальным способом
|
||||
|
||||
AWG2 Harness не устанавливает Amnezia. Используйте официальный self-hosted flow AmneziaVPN:
|
||||
|
||||
1. Установите актуальное приложение AmneziaVPN на рабочую машину.
|
||||
2. В приложении выберите self-hosted server.
|
||||
3. Укажите публичный IPv4 сервера, SSH-порт, SSH-пользователя и приватный ключ.
|
||||
4. Установите AmneziaWG/AWG. Для AWG 2.0 нужен актуальный AmneziaVPN, где протокол AmneziaWG 2.0 доступен в списке протоколов.
|
||||
5. После установки убедитесь, что контейнер поднят и UDP-порт опубликован.
|
||||
|
||||
Проверка на сервере:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Ожидаемые имена контейнера по умолчанию: `amnezia-awg2` или `amnezia-awg`. Ожидаемый интерфейс внутри container netns: обычно `awg0`, fallback-кандидаты описаны в `config.example.toml`.
|
||||
|
||||
### 4. Собрать пакет на build-machine
|
||||
|
||||
На production-хосте не нужны Rust, cargo и source tree. Сборка делается отдельно.
|
||||
|
||||
```bash
|
||||
cd awg2_harness
|
||||
./tools/build.sh --prepare-build-env --bootstrap-rust --yes
|
||||
./tools/build.sh --package
|
||||
./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
|
||||
```
|
||||
|
||||
Копирование на production host:
|
||||
`--version` можно не указывать, если версия в `traffic_core/Cargo.toml` уже соответствует release. Если version override указан, он меняет версию Debian-пакета, а не версию crate в `Cargo.toml`.
|
||||
|
||||
### 5. Перенести `.deb` и config на production
|
||||
|
||||
```bash
|
||||
scp dist/awg2-harness_*_amd64.deb root@vpn-host:/root/
|
||||
scp config.toml root@vpn-host:/root/awg2-harness.config.toml
|
||||
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
|
||||
```
|
||||
|
||||
Production host:
|
||||
Перед установкой отредактируйте `/root/awg2-harness.config.toml`: SSH-порт должен совпадать с реальным sshd, `amnezia_port` — с опубликованным UDP-портом контейнера, `peer_ipv4_cidr` — с подсетью клиентов Amnezia.
|
||||
|
||||
### 6. Установить пакет и config
|
||||
|
||||
```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
|
||||
awg2-harness validate-config --config /etc/awg2-harness/config.toml
|
||||
awg2-harness validate-runtime --config /etc/awg2-harness/config.toml
|
||||
awg2-harness apply-limits --config /etc/awg2-harness/config.toml
|
||||
awg2-harness apply-firewall --config /etc/awg2-harness/config.toml
|
||||
awg2-harness status --config /etc/awg2-harness/config.toml
|
||||
systemctl enable --now awg2-harness.service
|
||||
systemctl enable --now awg2-reboot-scheduler.service
|
||||
```
|
||||
|
||||
В production запускаются оба сервиса: [`awg2-harness.service`](awg2-harness.service) и [`awg2-reboot-scheduler.service`](awg2-reboot-scheduler.service).
|
||||
Пакет ставит пример config в `/usr/share/doc/awg2-harness/repo/config.example.toml`, но не копирует его в `/etc` автоматически.
|
||||
|
||||
Основная документация:
|
||||
### 7. Ручная preflight-проверка
|
||||
|
||||
- [`docs/MIGRATION.md`](docs/MIGRATION.md) — исправленная миграционная стратегия bash → Rust multi-orchestrator.
|
||||
- [`docs/OLD_BASH_BEHAVIOR.md`](docs/OLD_BASH_BEHAVIOR.md) — зафиксированное поведение старой bash-системы по файлам.
|
||||
- [`docs/IMPLEMENTATION_SPEC.md`](docs/IMPLEMENTATION_SPEC.md) — целевая архитектура бинаря и state reconciliation.
|
||||
- [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) — единый `config.toml` без эксплуатационного мусора.
|
||||
- [`docs/INSTALLATION.md`](docs/INSTALLATION.md) — установка на Debian 13 amd64.
|
||||
```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
|
||||
```
|
||||
|
||||
Ожидаемый healthy state:
|
||||
|
||||
```text
|
||||
System:
|
||||
service: inactive # до enable --now нормально
|
||||
Traffic actual:
|
||||
drift: no
|
||||
Host firewall:
|
||||
drift: no
|
||||
Anti-torrent:
|
||||
drift: no
|
||||
Swap:
|
||||
drift: no
|
||||
```
|
||||
|
||||
Если peers ещё нет, `apply-limits` корректно напишет `no peers found, skip tc apply`. Это не ошибка: traffic topology строится, когда есть хотя бы один peer allowed IP в целевой подсети.
|
||||
|
||||
### 8. Включить systemd services
|
||||
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
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
|
||||
```
|
||||
|
||||
После 30–60 секунд:
|
||||
|
||||
```bash
|
||||
awg2-harness --config /etc/awg2-harness/config.toml status
|
||||
```
|
||||
|
||||
Healthy daemon показывает `service: active`, `traffic=ok`, `firewall=ok`, `swap=ok` в recent events и пустой `last_error`.
|
||||
|
||||
### 9. Проверить после reboot
|
||||
|
||||
```bash
|
||||
reboot
|
||||
```
|
||||
|
||||
После возврата:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Дополнительно можно проверить фактическую `tc` topology внутри network namespace Amnezia:
|
||||
|
||||
```bash
|
||||
C="$(docker ps --format '{{.Names}}' | grep -E '^(amnezia-awg2|amnezia-awg)$' | head -n1)"
|
||||
PID="$(docker inspect -f '{{.State.Pid}}' "$C")"
|
||||
|
||||
nsenter -t "$PID" -n -- tc class show dev awg0
|
||||
nsenter -t "$PID" -n -- tc class show dev ifb0
|
||||
nsenter -t "$PID" -n -- nft list table inet awg2_harness
|
||||
nft list table inet awg2_host_firewall
|
||||
```
|
||||
|
||||
Для default config на одном peer ожидаются классы `1:10` и `2:10` с `rate 50Mbit ceil 50Mbit`, root classes `1:1` и `2:1` с `500Mbit`, host firewall table `inet awg2_host_firewall` и anti-torrent table `inet awg2_harness` внутри Amnezia netns.
|
||||
|
||||
## CLI команды
|
||||
|
||||
Все команды принимают `--config`. Если параметр не указан, используется `/etc/awg2-harness/config.toml`.
|
||||
|
||||
```bash
|
||||
awg2-harness --config /etc/awg2-harness/config.toml <command>
|
||||
```
|
||||
|
||||
`validate-config` проверяет TOML и смысловые ограничения: пустые списки, формат rate (`50mbit`, `500mbit`), CIDR, reboot window, swap path, SSH/Amnezia ports, protocol list.
|
||||
|
||||
`validate-runtime` проверяет host tools, которые реально нужны выбранным модулям: `tc`, `ip`, `wg`, `docker`, `modprobe`, `nsenter`, а также `nft`, `systemctl`, swap tooling при включённых firewall/reboot/swap.
|
||||
|
||||
`ensure-swap` приводит swap к desired state: создаёт/проверяет swapfile, включает его с заданным priority, применяет `vm.swappiness`, делает swap state exclusive и переписывает swap entries в `/etc/fstab` под управляемый swapfile.
|
||||
|
||||
`apply-firewall` делает два reconcile: host INPUT firewall в таблице `inet awg2_host_firewall` и anti-torrent guard в выбранном namespace. Команда не управляет Docker NAT и host `FORWARD`.
|
||||
|
||||
`apply-limits` находит Amnezia container, заходит в его network namespace, читает peers через `wg`, строит per-peer HTB/fq_codel классы на AWG/WG интерфейсе и IFB ingress path. Если drift не найден, пишет `traffic rules up-to-date, skip apply`.
|
||||
|
||||
`status` печатает фактическую диагностику: сервис, контейнер, netns, интерфейс, peers, WireGuard runtime, traffic desired/actual, host firewall drift, Docker/Amnezia port path, anti-torrent counters, swap state, conntrack, recent events и planned reboot.
|
||||
|
||||
`daemon` — режим для systemd. На старте делает startup reconcile, затем слушает Docker events и периодически сверяет traffic/swap/firewall. Вручную обычно не запускается, кроме отладки.
|
||||
|
||||
`awg2-reboot-scheduler --config /etc/awg2-harness/config.toml` читает только секцию `[reboot]`, пишет план в `/run/awg2-harness/reboot.plan` и ждёт назначенного UTC-времени.
|
||||
|
||||
## Что происходит под капотом
|
||||
|
||||
Traffic shaping реализован через `tc` в network namespace контейнера Amnezia. На egress используется root qdisc `htb 1:` на AWG/WG интерфейсе, root class `1:1`, per-peer classes `1:<id>` и `fq_codel` под каждым peer class. На ingress ставится `ingress ffff:` на AWG/WG интерфейс, входящие пакеты перенаправляются через `mirred` в `ifb0`, а там строится отдельная HTB topology `2:` с такими же per-peer лимитами.
|
||||
|
||||
Peer discovery берётся из WireGuard/AmneziaWG allowed IPs, а не из handshake state. Поэтому offline peer с `allowed ips: 10.8.1.1/32` тоже получает лимит заранее.
|
||||
|
||||
Host firewall — отдельная AWG2-owned таблица `inet awg2_host_firewall`. Она открывает loopback, established/related, SSH-порт из конфига, Amnezia-порт по указанным протоколам и optionally ICMP/ICMPv6. Docker-managed `FORWARD` и NAT не трогаются.
|
||||
|
||||
Anti-torrent guard — отдельная AWG2-owned таблица `inet awg2_harness` обычно внутри Amnezia netns. Правило ограничивает число новых conntrack flows per source VPN IP. Это не DPI и не распознавание BitTorrent-протокола; это грубый, дешёвый guard против сотен одновременных P2P-соединений.
|
||||
|
||||
Swap module намеренно строгий: если `swap.enabled=true`, desired state — один управляемый swapfile. Старые swap entries удаляются из `/etc/fstab`, block-device swap выключается, но block device не удаляется.
|
||||
|
||||
## Production-границы ответственности
|
||||
|
||||
AWG2 Harness владеет только собственным state:
|
||||
|
||||
- `tc` topology на Amnezia interface и configured `ifb_name`;
|
||||
- nft table `inet awg2_host_firewall` в host namespace;
|
||||
- nft table `inet awg2_harness` для anti-torrent;
|
||||
- `/run/awg2-harness/*` runtime state;
|
||||
- managed swapfile и swap entries, если `swap.enabled=true`.
|
||||
|
||||
AWG2 Harness не владеет:
|
||||
|
||||
- установкой AmneziaVPN;
|
||||
- Docker daemon lifecycle;
|
||||
- Docker NAT/FORWARD chains;
|
||||
- генерацией client configs/keys;
|
||||
- политикой пользователя внутри Amnezia app;
|
||||
- сторонними firewall-таблицами.
|
||||
|
||||
## Документация
|
||||
|
||||
- [`docs/INSTALLATION.md`](docs/INSTALLATION.md) — установка и preflight.
|
||||
- [`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) — простая анти-торрент защита через nftables `ct count`.
|
||||
- [`docs/ANTI_TORRENT.md`](docs/ANTI_TORRENT.md) — connection-count guard.
|
||||
- [`tools/README.md`](tools/README.md) — сборка и упаковка.
|
||||
- [`reboot_module/README.md`](reboot_module/README.md) — внешний reboot scheduler.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
- [ ] Хост — Debian 13 amd64.
|
||||
- [ ] Сервер выделенный, без соседних сервисов.
|
||||
- [ ] AmneziaWG/AWG 2.0 установлена официальным способом.
|
||||
- [ ] AmneziaWG/AWG 2.0 или AmneziaWG/AWG 1.5 установлена официальным способом.
|
||||
- [ ] Контейнер `amnezia-awg2` или `amnezia-awg` запущен.
|
||||
- [ ] `docker ps` видит контейнер.
|
||||
- [ ] Можно получить PID контейнера.
|
||||
@@ -102,7 +102,7 @@
|
||||
- [ ] Есть chain `forward_antitorrent` с hook `forward` и policy `accept`.
|
||||
- [ ] Правило ограничивает `ip saddr <peer_ipv4_cidr>`, default `10.8.1.0/24`.
|
||||
- [ ] Лимит считается per source VPN IP через meter/set, а не глобально по всей подсети.
|
||||
- [ ] Порог совпадает с `anti_torrent.max_connections_per_peer`, default `100`.
|
||||
- [ ] Порог совпадает с `anti_torrent.max_connections_per_peer`; текущий пример config использует `150`, более строгий вариант — `100`.
|
||||
- [ ] Drop counter виден в `status`.
|
||||
- [ ] На first-run без table `awg2-harness apply-firewall` создаёт `table inet awg2_harness`, а не падает.
|
||||
- [ ] При превышении порога новые flows дропаются, established flows ниже порога не ломаются.
|
||||
|
||||
@@ -65,18 +65,18 @@ table inet awg2_harness {
|
||||
|
||||
## 4. Threshold
|
||||
|
||||
Рекомендуемый default:
|
||||
Рекомендуемый стартовый production baseline:
|
||||
|
||||
```toml
|
||||
[anti_torrent]
|
||||
enabled = true
|
||||
max_connections_per_peer = 100
|
||||
max_connections_per_peer = 150
|
||||
```
|
||||
|
||||
Практические варианты:
|
||||
|
||||
- `100` — production default, более строгий режим.
|
||||
- `150` — мягче, если есть жалобы на false positives.
|
||||
- `100` — более строгий режим.
|
||||
- `150` — текущий рекомендуемый стартовый baseline, мягче к обычному browsing/mobile traffic.
|
||||
- `200/250` — ещё более permissive варианты.
|
||||
- `70` — агрессивный режим только после наблюдения реального трафика.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Конфигурация AWG2 Harness
|
||||
|
||||
Конфиг живёт в `/etc/awg2-harness/config.toml`. Он общий для всего пакета и должен содержать только эксплуатационно значимые параметры.
|
||||
AWG2 Harness разрабатывался для self-hosted AmneziaWG/AWG 2.0 и совместимого legacy-сценария AmneziaWG/AWG 1.5. Конфиг живёт в `/etc/awg2-harness/config.toml`. Он общий для всего пакета и должен содержать только эксплуатационно значимые параметры.
|
||||
|
||||
## Рекомендуемый `config.toml`
|
||||
|
||||
@@ -30,7 +30,7 @@ default_input_policy = "drop"
|
||||
|
||||
[anti_torrent]
|
||||
enabled = true
|
||||
max_connections_per_peer = 100
|
||||
max_connections_per_peer = 150
|
||||
peer_ipv4_cidr = "10.8.1.0/24"
|
||||
apply_in_amnezia_netns = true
|
||||
|
||||
@@ -75,7 +75,7 @@ swappiness = 1
|
||||
|
||||
`host_firewall.enabled` — включает host-level INPUT firewall в отдельной AWG2-owned таблице `inet awg2_host_firewall`.
|
||||
|
||||
`host_firewall.ssh_port` — SSH порт хоста, который обязательно должен быть открыт. Production default: `2323`.
|
||||
`host_firewall.ssh_port` — SSH порт хоста, который обязательно должен быть открыт. Production default/example: `2323`. Значение обязано совпадать с реально слушающим sshd портом до применения `apply-firewall`.
|
||||
|
||||
`host_firewall.amnezia_port` — внешний UDP/TCP порт Amnezia, который AWG2 открывает в host `INPUT` (в зависимости от `host_firewall.amnezia_protocols`). Значение должно совпадать с портом, указанным в панели/инсталляторе AmneziaWG. В старых инсталляциях это мог быть `44344`, в новой целевой конфигурации default — `443`.
|
||||
|
||||
@@ -91,7 +91,7 @@ swappiness = 1
|
||||
|
||||
`host_firewall.default_input_policy` — политика INPUT chain (`drop` или `accept`). Для production рекомендуется `drop`.
|
||||
|
||||
`anti_torrent.max_connections_per_peer` — максимум одновременных conntrack flows на один VPN peer IP. Default `100`; `250` — более мягкий вариант.
|
||||
`anti_torrent.max_connections_per_peer` — максимум одновременных conntrack flows на один VPN peer IP. Текущий пример использует `150`: это мягче, чем строгий `100`, и обычно безопаснее как первый production baseline. `100` можно использовать как более жёсткий режим; `200/250` — более permissive варианты.
|
||||
|
||||
`anti_torrent.peer_ipv4_cidr` — подсеть, на которую распространяется правило. Обычно должна совпадать с `amnezia.peer_ipv4_cidr`.
|
||||
|
||||
|
||||
+131
-27
@@ -1,78 +1,182 @@
|
||||
# Installation
|
||||
|
||||
Этот документ описывает production-порядок установки AWG2 Harness. Подробный runtime-план с SSH hardening и Amnezia preflight находится в корневом [`README.md`](../README.md).
|
||||
|
||||
## Deployment contract
|
||||
|
||||
- Build выполняется на отдельной Debian 13 amd64 build-machine.
|
||||
- Production-хост получает готовый Debian-пакет.
|
||||
- На production-хосте не требуются Rust/cargo/source tree.
|
||||
- Amnezia должна быть уже установлена и работать через Docker.
|
||||
- Production-конфиг создаётся вручную; [`config.example.toml`](../config.example.toml) не копируется автоматически как боевой конфиг.
|
||||
- Целевой 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
|
||||
### A1. Подготовить build environment
|
||||
|
||||
```bash
|
||||
cd awg2_harness
|
||||
chmod +x tools/build.sh
|
||||
./tools/build.sh --prepare-build-env --bootstrap-rust --yes
|
||||
```
|
||||
|
||||
### A2. Build и тесты
|
||||
### 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. Сборка пакета
|
||||
### A3. Собрать Debian-пакет
|
||||
|
||||
```bash
|
||||
./tools/build.sh --package
|
||||
./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
|
||||
```
|
||||
|
||||
## B. Transfer artifacts
|
||||
`--version` можно опустить, если версия в `traffic_core/Cargo.toml` уже равна release version. Version override влияет только на metadata `.deb`.
|
||||
|
||||
## B. Подготовить production-хост
|
||||
|
||||
### B1. SSH
|
||||
|
||||
Production-пример:
|
||||
|
||||
```bash
|
||||
scp dist/awg2-harness_*_amd64.deb root@vpn-host:/root/
|
||||
scp config.toml root@vpn-host:/root/awg2-harness.config.toml
|
||||
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'
|
||||
```
|
||||
|
||||
## C. Production host
|
||||
|
||||
### C1. Install package
|
||||
Обязательно проверьте вход с нового терминала:
|
||||
|
||||
```bash
|
||||
ssh -p 2323 root@<server-ip>
|
||||
```
|
||||
|
||||
### B2. Amnezia
|
||||
|
||||
Установите AmneziaWG/AWG через официальное приложение AmneziaVPN в режиме self-hosted server. Вводите в приложении тот SSH host/port/user/private key, который реально работает после B1.
|
||||
|
||||
Проверка после установки:
|
||||
|
||||
```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`.
|
||||
|
||||
## C. Transfer artifacts
|
||||
|
||||
```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.
|
||||
|
||||
## D. Production install
|
||||
|
||||
```bash
|
||||
cd /root
|
||||
sha256sum -c SHA256SUMS
|
||||
apt install ./awg2-harness_*_amd64.deb
|
||||
```
|
||||
|
||||
### C2. Install config
|
||||
|
||||
```bash
|
||||
install -d -m 0755 /etc/awg2-harness
|
||||
install -m 0644 /root/awg2-harness.config.toml /etc/awg2-harness/config.toml
|
||||
systemctl daemon-reload
|
||||
```
|
||||
|
||||
### C3. Validate and apply
|
||||
## 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-limits
|
||||
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
|
||||
```
|
||||
|
||||
When `swap.enabled=true`, AWG2 Harness will disable all other active swap entries and rewrite `/etc/fstab` swap entries to a single managed swapfile.
|
||||
Expected healthy result:
|
||||
|
||||
### C4. Enable services
|
||||
```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
|
||||
```
|
||||
|
||||
## D. Manual source-tree install (staging/debug only)
|
||||
After 30–60 seconds:
|
||||
|
||||
Режим [`./tools/build.sh --install`](../tools/build.sh) предназначен для staging/debug с checkout-репозиторием.
|
||||
```bash
|
||||
awg2-harness --config /etc/awg2-harness/config.toml status
|
||||
```
|
||||
|
||||
Это **не** основной production deployment path.
|
||||
## 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.
|
||||
|
||||
+1
-1
@@ -199,7 +199,7 @@ default_input_policy = "drop"
|
||||
|
||||
[anti_torrent]
|
||||
enabled = true
|
||||
max_connections_per_peer = 100
|
||||
max_connections_per_peer = 150
|
||||
peer_ipv4_cidr = "10.8.1.0/24"
|
||||
apply_in_amnezia_netns = true
|
||||
|
||||
|
||||
+15
-7
@@ -2,10 +2,18 @@
|
||||
|
||||
Рекомендуемый порядок чтения:
|
||||
|
||||
1. [`OLD_BASH_BEHAVIOR.md`](OLD_BASH_BEHAVIOR.md) — что реально делает старая production bash-система.
|
||||
2. [`MIGRATION.md`](MIGRATION.md) — corrected migration scope: Rust multi-orchestrator, а не механический bash port.
|
||||
3. [`IMPLEMENTATION_SPEC.md`](IMPLEMENTATION_SPEC.md) — целевая архитектура и state reconciliation.
|
||||
4. [`CONFIGURATION.md`](CONFIGURATION.md) — единый конфиг.
|
||||
5. [`ANTI_TORRENT.md`](ANTI_TORRENT.md) — опциональный nftables guard против high-peer-count P2P.
|
||||
6. [`INSTALLATION.md`](INSTALLATION.md) — установка на Debian 13 amd64.
|
||||
7. [`ACCEPTANCE_CHECKLIST.md`](ACCEPTANCE_CHECKLIST.md) — критерии production-ready.
|
||||
1. [`../README.md`](../README.md) — общий runtime-план: SSH, официальная Amnezia, установка пакета, preflight, reboot validation и CLI.
|
||||
2. [`INSTALLATION.md`](INSTALLATION.md) — сжатый production install flow.
|
||||
3. [`CONFIGURATION.md`](CONFIGURATION.md) — параметры `/etc/awg2-harness/config.toml`.
|
||||
4. [`ACCEPTANCE_CHECKLIST.md`](ACCEPTANCE_CHECKLIST.md) — checklist перед production-ready статусом.
|
||||
5. [`ANTI_TORRENT.md`](ANTI_TORRENT.md) — nftables connection-count guard.
|
||||
6. [`IMPLEMENTATION_SPEC.md`](IMPLEMENTATION_SPEC.md) — архитектура и state reconciliation.
|
||||
7. [`OLD_BASH_BEHAVIOR.md`](OLD_BASH_BEHAVIOR.md) — что делала старая bash-система.
|
||||
8. [`MIGRATION.md`](MIGRATION.md) — контекст миграции с bash на Rust multi-orchestrator.
|
||||
|
||||
Отдельно:
|
||||
|
||||
- [`../tools/README.md`](../tools/README.md) — сборка и упаковка `.deb`.
|
||||
- [`../reboot_module/README.md`](../reboot_module/README.md) — внешний reboot scheduler.
|
||||
|
||||
Практический порядок для оператора: сначала выполнить root README, затем свериться с acceptance checklist. Остальные документы нужны для понимания design intent и отладки.
|
||||
|
||||
+33
-16
@@ -1,23 +1,40 @@
|
||||
# awg2-reboot-scheduler
|
||||
|
||||
`awg2-reboot-scheduler` — production auxiliary binary в составе пакета AWG2 Harness.
|
||||
`awg2-reboot-scheduler` — отдельный production-бинарь в составе пакета AWG2 Harness. Его задача узкая: один раз на старте прочитать секцию `[reboot]` из общего `/etc/awg2-harness/config.toml`, выбрать случайный момент внутри заданного UTC-окна, записать план в `/run/awg2-harness/reboot.plan` и в назначенное время запросить reboot через `systemctl --no-block reboot`.
|
||||
|
||||
Он читает общий конфиг [`/etc/awg2-harness/config.toml`](../config.example.toml), выбирает случайный момент в окне reboot и запрашивает перезагрузку через `systemctl --no-block reboot`.
|
||||
Он вынесен отдельно от основного `awg2-harness daemon`, чтобы плановый reboot не зависел от traffic/firewall reconciliation loop.
|
||||
|
||||
## Production model
|
||||
## Runtime paths
|
||||
|
||||
- binary: `/usr/sbin/awg2-reboot-scheduler`
|
||||
- unit: [`/lib/systemd/system/awg2-reboot-scheduler.service`](../awg2-reboot-scheduler.service)
|
||||
- config: `/etc/awg2-harness/config.toml`
|
||||
- runtime plan file: `/run/awg2-harness/reboot.plan`
|
||||
|
||||
Сервис ставится и управляется общим packaging flow [`tools/build.sh`](../tools/build.sh), вручную в `/opt/...` ничего не раскладывается.
|
||||
|
||||
## Проверка на host
|
||||
|
||||
```bash
|
||||
awg2-reboot-scheduler --config /etc/awg2-harness/config.toml
|
||||
systemctl status awg2-reboot-scheduler
|
||||
journalctl -u awg2-reboot-scheduler -f
|
||||
```text
|
||||
binary: /usr/sbin/awg2-reboot-scheduler
|
||||
unit: /lib/systemd/system/awg2-reboot-scheduler.service
|
||||
config: /etc/awg2-harness/config.toml
|
||||
plan file: /run/awg2-harness/reboot.plan
|
||||
```
|
||||
|
||||
## Конфигурация
|
||||
|
||||
```toml
|
||||
[reboot]
|
||||
enabled = true
|
||||
window_start_utc = "01:00"
|
||||
window_end_utc = "02:00"
|
||||
```
|
||||
|
||||
Если `enabled = false`, процесс печатает `disabled by config` и завершается без reboot.
|
||||
|
||||
## Проверка на production host
|
||||
|
||||
```bash
|
||||
systemctl status awg2-reboot-scheduler.service --no-pager -l
|
||||
journalctl -u awg2-reboot-scheduler.service --since '10 minutes ago' --no-pager
|
||||
cat /run/awg2-harness/reboot.plan
|
||||
awg2-harness --config /etc/awg2-harness/config.toml status
|
||||
```
|
||||
|
||||
## Ручной запуск для диагностики
|
||||
|
||||
```bash
|
||||
/usr/sbin/awg2-reboot-scheduler --config /etc/awg2-harness/config.toml
|
||||
```
|
||||
|
||||
+40
-50
@@ -1,72 +1,62 @@
|
||||
# AWG2 Harness builder
|
||||
|
||||
Основной скрипт: [`build.sh`](build.sh).
|
||||
Целевой crate: [`traffic_core`](../traffic_core/Cargo.toml).
|
||||
Unit: [`awg2-harness.service`](../awg2-harness.service).
|
||||
Пример конфига: [`config.example.toml`](../config.example.toml).
|
||||
`tools/build.sh` — единый build/package helper для AWG2 Harness. Он предназначен в первую очередь для build-machine. Production-хост обычно получает только готовый `.deb` и `/etc/awg2-harness/config.toml`.
|
||||
|
||||
## Supported host
|
||||
Скрипт собирает workspace из двух бинарей:
|
||||
|
||||
- Debian/Ubuntu (apt-based)
|
||||
- amd64/x86_64
|
||||
```text
|
||||
traffic_core -> awg2-harness
|
||||
reboot_module -> awg2-reboot-scheduler
|
||||
```
|
||||
|
||||
## Purpose
|
||||
И при `--package` создаёт Debian-пакет `dist/awg2-harness_<version>_amd64.deb` с checksum-файлом `dist/SHA256SUMS`.
|
||||
|
||||
Скрипт используется на build-machine для проверки, сборки и упаковки AWG2 Harness.
|
||||
## Поддерживаемая build-среда
|
||||
|
||||
## Default mode
|
||||
- Debian/Ubuntu с `apt`.
|
||||
- amd64/x86_64.
|
||||
- Rust toolchain из `rust-toolchain.toml` (`1.95.0` в текущем дереве).
|
||||
- `Cargo.lock` обязателен: build gate работает в `--locked` режиме.
|
||||
|
||||
## Быстрый production build
|
||||
|
||||
```bash
|
||||
cd awg2_harness
|
||||
chmod +x tools/build.sh
|
||||
./tools/build.sh --prepare-build-env --bootstrap-rust --yes
|
||||
./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
|
||||
```
|
||||
|
||||
## Что делает default запуск
|
||||
|
||||
```bash
|
||||
./tools/build.sh
|
||||
```
|
||||
|
||||
Дефолтный запуск **не изменяет систему**. Он:
|
||||
Если не указан ни один action flag, включается `--build`.
|
||||
|
||||
- проверяет prereqs;
|
||||
- запускает `fmt/clippy/test/build` в locked-режиме;
|
||||
- печатает `file`, `ldd`, `sha256` для собранного бинаря.
|
||||
|
||||
## Flags
|
||||
|
||||
- `--prepare-build-env` — установить недостающие build-пакеты;
|
||||
- `--prepare-runtime-env` — установить недостающие runtime-пакеты;
|
||||
- `--bootstrap-rust` — установить rustup и pinned toolchain;
|
||||
- `--build` — запустить build gate явно;
|
||||
- `--package` — собрать Debian-пакет в `dist/`;
|
||||
- `--dist-dir <path>` — директория для release artifacts;
|
||||
- `--version <version>` — переопределить версию пакета;
|
||||
- `--install` — установить бинарь + systemd unit (без enable/start);
|
||||
- `--enable` — `systemctl enable --now awg2-harness.service`;
|
||||
- `--yes` — подтверждение системных изменений (apt/rustup);
|
||||
- `--skip-fmt` — пропустить `cargo fmt --check`;
|
||||
- `--help` — справка.
|
||||
|
||||
## Build machine flow
|
||||
## Проверка пакета перед переносом
|
||||
|
||||
```bash
|
||||
./tools/build.sh --prepare-build-env --bootstrap-rust --yes
|
||||
./tools/build.sh --build
|
||||
./tools/build.sh --package
|
||||
sha256sum -c dist/SHA256SUMS
|
||||
dpkg-deb -I dist/awg2-harness_<version>_amd64.deb
|
||||
dpkg-deb -c dist/awg2-harness_<version>_amd64.deb | sort
|
||||
```
|
||||
|
||||
## Production host flow
|
||||
|
||||
В нормальном production deployment **не нужно** клонировать репозиторий на целевой хост.
|
||||
Ставится сгенерированный пакет:
|
||||
## Production transfer
|
||||
|
||||
```bash
|
||||
apt install ./awg2-harness_*_amd64.deb
|
||||
scp -P 2323 dist/awg2-harness_<version>_amd64.deb root@<server-ip>:/root/
|
||||
scp -P 2323 dist/SHA256SUMS root@<server-ip>:/root/
|
||||
```
|
||||
|
||||
## Manual source-tree install
|
||||
## Что скрипт намеренно не делает
|
||||
|
||||
`--install` и `--enable` оставлены для staging/debug из checked-out source tree.
|
||||
|
||||
Это **не рекомендуемый** production path.
|
||||
|
||||
## What the script intentionally does not do
|
||||
|
||||
- не устанавливает Docker автоматически;
|
||||
- не генерирует production config из example;
|
||||
- не включает сервис без явного `--enable`;
|
||||
- не управляет установкой AmneziaWG.
|
||||
- не устанавливает AmneziaVPN;
|
||||
- не генерирует client keys/configs;
|
||||
- не копирует `config.example.toml` в `/etc/awg2-harness/config.toml`;
|
||||
- не включает services без `--enable`;
|
||||
- не управляет SSH hardening.
|
||||
|
||||
+6
-3
@@ -329,6 +329,7 @@ package_deb() {
|
||||
install -d -m 0755 "$staging/usr/share/doc/awg2-harness/repo"
|
||||
install -d -m 0755 "$staging/usr/share/doc/awg2-harness/repo/docs"
|
||||
install -d -m 0755 "$staging/usr/share/doc/awg2-harness/repo/tools"
|
||||
install -d -m 0755 "$staging/usr/share/doc/awg2-harness/repo/reboot_module"
|
||||
|
||||
install -m 0755 "$TARGET_BIN" "$staging/usr/sbin/awg2-harness"
|
||||
install -m 0755 "$REBOOT_BIN" "$staging/usr/sbin/awg2-reboot-scheduler"
|
||||
@@ -336,10 +337,12 @@ package_deb() {
|
||||
install -m 0644 "$ROOT_DIR/awg2-reboot-scheduler.service" "$staging/lib/systemd/system/awg2-reboot-scheduler.service"
|
||||
install -m 0644 "$ROOT_DIR/config.example.toml" "$staging/usr/share/doc/awg2-harness/repo/config.example.toml"
|
||||
install -m 0644 "$ROOT_DIR/README.md" "$staging/usr/share/doc/awg2-harness/repo/README.md"
|
||||
install -m 0644 "$ROOT_DIR/docs/INSTALLATION.md" "$staging/usr/share/doc/awg2-harness/repo/docs/INSTALLATION.md"
|
||||
install -m 0644 "$ROOT_DIR/docs/CONFIGURATION.md" "$staging/usr/share/doc/awg2-harness/repo/docs/CONFIGURATION.md"
|
||||
install -m 0644 "$ROOT_DIR/docs/ACCEPTANCE_CHECKLIST.md" "$staging/usr/share/doc/awg2-harness/repo/docs/ACCEPTANCE_CHECKLIST.md"
|
||||
local doc
|
||||
for doc in "$ROOT_DIR"/docs/*.md; do
|
||||
install -m 0644 "$doc" "$staging/usr/share/doc/awg2-harness/repo/docs/$(basename "$doc")"
|
||||
done
|
||||
install -m 0644 "$ROOT_DIR/tools/README.md" "$staging/usr/share/doc/awg2-harness/repo/tools/README.md"
|
||||
install -m 0644 "$ROOT_DIR/reboot_module/README.md" "$staging/usr/share/doc/awg2-harness/repo/reboot_module/README.md"
|
||||
|
||||
cat >"$staging/DEBIAN/control" <<EOF
|
||||
Package: awg2-harness
|
||||
|
||||
Reference in New Issue
Block a user