fix: harden production topology and runtime state

This commit is contained in:
2026-08-28 15:19:12 +05:00
parent 9dd4732655
commit 0c32c9abbe
26 changed files with 3276 additions and 2815 deletions
+11 -5
View File
@@ -55,13 +55,13 @@ ifb_name = "ifb0"
enabled = true
apply_on_daemon_start = true
ip_forward = true
tcp_bbr = "auto" # off | auto | require
default_qdisc = "fq" # none | fq | fq_codel
tcp_bbr = "off" # off | auto | require
default_qdisc = "fq" # none | fq
rmem_max = 67108864
wmem_max = 67108864
netdev_backlog_enabled = false
netdev_max_backlog = 10000
udp_rmem_min_enabled = true
udp_rmem_min_enabled = false
udp_rmem_min = 8192
[host_firewall]
@@ -103,6 +103,8 @@ swappiness = 1
`amnezia.peer_ipv4_cidr` — подсеть VPN peers. Production default — `10.8.1.0/24`; значение конфигурируемое.
Поддерживаемая server-side topology строго соответствует официальной self-hosted схеме Amnezia/AWG 3.1: у каждого peer либо нет маршрута (`(none)`), либо есть ровно один IPv4 host route `/32` внутри `amnezia.peer_ipv4_cidr`. IPv6, смешанные IPv4+IPv6, несколько маршрутов, более широкая маска и адрес вне подсети дают явную ошибку `unsupported topology` до изменения `tc` и anti-torrent state. Клиентские `0.0.0.0/0, ::/0` и внешний IPv6 Docker publish относятся к другим плоскостям и этим ограничением не запрещаются.
`amnezia.expected_host_udp_port` — ожидаемый published UDP host port Docker для AmneziaWG. Поле обязательное и используется диагностикой `status` для контракта `expected host port ↔ Docker binding ↔ awg/wg listen-port`. Оно не создаёт host INPUT allow-rule: трафик к published bridge container проходит через Docker `FORWARD`/NAT path, а не через host `INPUT`.
`traffic.peer_limit` — per-peer лимит в обе стороны. Текущий production default — `50mbit`.
@@ -121,15 +123,19 @@ swappiness = 1
- persistent-файл: `/etc/sysctl.d/90-awg2-harness-vpn.conf`;
- модуль `swap` отдельно управляет `/etc/sysctl.d/90-awg2-harness-swap.conf` (только `vm.swappiness`); прежний путь `/etc/sysctl.d/99-awg2-harness.conf` удаляется при первом запуске новой версии, если несёт старый маркер;
- дополнительный managed-файл `/etc/modules-load.d/90-awg2-harness-bbr.conf` создаётся только при фактически активном BBR и удаляется, когда BBR неактивен;
- дополнительный managed-файл `/etc/modules-load.d/90-awg2-harness-bbr.conf` создаётся только когда BBR выбран desired policy (`auto`/`require` и BBR доступен), и удаляется при `tcp_bbr = "off"` или недоступном `auto`;
- оба managed-файла несут в первой строке маркер `# Managed by awg2-harness sysctl_tuning`; файл без маркера не перезаписывается и не удаляется, вместо этого возвращается ошибка;
- `net.ipv4.tcp_congestion_control` и `net.core.default_qdisc` управляются только при активном BBR;
- `net.ipv4.tcp_congestion_control` и `net.core.default_qdisc` управляются только когда BBR желателен по policy; `default_qdisc` принимает только `none | fq` и не управляет per-peer `fq_codel`;
- runtime apply: только `sysctl -w` и только для drifted keys;
- на установке `.deb` модуль не применяется;
- на старте daemon модуль применяется, если `enabled=true` и `apply_on_daemon_start=true`;
- `tcp_bbr = auto` не валит запуск при недоступном BBR (warning), `require` — валит;
- для `sysctl_tuning`: `modprobe` обязателен только для `tcp_bbr = "require"`.
Production default — `tcp_bbr = "off"`: BBR влияет на локальные TCP sockets хоста, но не ускоряет UDP transport AWG и не является частью HTB peer limiter. `auto`/`require` остаются осознанным opt-in. Status разделяет три разных факта: `bbr_available`, `bbr_desired` и фактический `bbr_runtime_active`, вычисленный по текущему `net.ipv4.tcp_congestion_control`.
`udp_rmem_min_enabled = false` — production default, потому что `net.ipv4.udp_rmem_min` является per-network-namespace sysctl: запись на хосте не меняет UDP stack AWG-контейнера. Значение `udp_rmem_min = 8192` сохранено как opt-in для локальных UDP sockets хоста; отдельный container-side reconcile ради него не добавляется.
`netdev_backlog_enabled = false` — безопасный production default: harness не управляет `net.core.netdev_max_backlog`, пока оператор не включит это явно после измерений. Значение `netdev_max_backlog = 10000` используется только при `netdev_backlog_enabled = true`.
При обновлении с конфига, где backlog раньше был включён, переключение флага в `false` удаляет key из managed-файла, но не перезаписывает уже изменённое runtime-значение. До следующей перезагрузки его можно вернуть вручную к baseline дистрибутива. Перед осознанным включением backlog снимите pre/post-метрики `/proc/net/softnet_stat` (в том числе dropped/time_squeeze) и CPU/latency под реальной нагрузкой.