Двухуровневый QoS на mirkwood:
awg0/2/3 к exit-нодам) — HTB rate-limit от upstream policer.awg1 клиентский) — HTB → fq_codel leaf для честного шейпинга по тарифам.Жалобы muhutdinova: «VPN плохо работает весь день». Диагностика показала внешний rate-limiter (вероятно ТСПУ или upstream провайдер 4Gain), который массово дропает UDP при aggregated >300 Mbps.
845 → 65 Mbps, 60-285 тысяч retransmissions.AWG усугубляет через retransmit-loop: TCP внутри туннеля видит loss → retransmit → новые UDP пакеты → опять полицер → loop.
HTB rate-limit на каждом awg-интерфейсе обоих сторон туннеля:
| Сервер | Интерфейс | Cap |
|---|---|---|
| mirkwood | awg0 (→ nugush) | 300 Mbps |
| mirkwood | awg2 (→ syun) | 300 Mbps |
| mirkwood | awg3 (→ sakmara) | 300 Mbps |
| nugush | awg3 (→ mirkwood) | 300 Mbps |
| syun | awg1 (→ mirkwood) | 300 Mbps |
| sakmara | awg0 (→ mirkwood) | 150 Mbps (его DC даёт реально ~340 Mbps, не гигабит) |
Структура qdisc: htb root → htb class → fq_codel leaf. HTB не пускает поток в опасную зону через queueing (без drops); fq_codel внутри — честное распределение между потоками.
contrib/bin/awg-qos.sh — bash, hostname-aware, override через /etc/awg-qos.conf (формат: awg0:300 per line)contrib/systemd/awg-qos.service — oneshot, RemainAfterExit/etc/systemd/system/amneziawg-awgX.service.d/qos.conf с ExecStartPost=/usr/local/bin/awg-qos.shcontrib/ansible/roles/central-server/templates/systemd/awg-qos.service.j2 + tasks/systemd-timers.ymlБез drop-in systemctl restart amneziawg-awgX слетает HTB и не восстанавливается (oneshot awg-qos.service в active (exited) не реагирует на restart интерфейса).
На CentOS Stream 9 / RHEL tc идёт отдельным пакетом iproute-tc. Не входит в базовую установку. Перед деплоем HTB:
dnf install iproute-tc
Также на бюджетных DC (sakmara) AWG kernel module DKMS не собирается — нужно компилировать из исходников и собирать wireguard-tools из git. Делается ролью exit-server в AmneziaWGServer.
Файл: Interfaces/Firewall/shaper.py
TOTAL_BANDWIDTH = '1gbit' (хардкод, TODO T6 — вынести в config.yml для серверов >1Gbps)FQCODEL_LIMIT = 4096 (раньше было 1024 — давало drops при >100 Mbps; повысили 2026-04-21)r2q = 10 (HTB rate-to-quantum)htb {speed_rx} ceil 2*speed_rx burst 256k → fq_codel limit 4096 target 5ms interval 100msifb0)Per-user leaf qdisc на awg1 заменён с SFQ → fq_codel:
Точки замены: egress + ingress IFB в shaper.py.
В 99-awg.conf (через ansible sysctl.yml):
tcp_fastopen = 3 — экономит 1 RTT (клиент+сервер)tcp_notsent_lowat = 16384 — уменьшает bufferbloat, BBR rate estimation точнееtcp_max_syn_backlog = 4096 (было 512)nf_conntrack_max = 1000000tcp_tw_reuse = 1, ip_local_port_range = 1024 65535, netdev_budget = 600При жалобе на скорость:
iperf3 или через support-ticket автодиагностику.tc -s qdisc show dev awgX — overlimits / dropped счётчики.cat /proc/net/snmp | grep -A1 Tcp: — RetransSegs.ss -tin — конкретные сессии с retrans/cwnd/rtt.route.conf (рядом с qos.conf, в одной dir amneziawg-awgX.service.d/)Changelog