# Anti-torrent connection-count guard Этот модуль — часть текущего production-контракта AWG2 Harness. Он вписывается в multi-orchestrator модель, потому что сервер выделенный, а бинарь уже владеет AWG2-owned network state вокруг Amnezia: `tc`, `ifb0`, lifecycle recovery и диагностика. ## 1. Цель Не детектить BitTorrent как протокол. Цель проще: ограничить количество одновременных conntrack flows на один VPN peer IP. Торрент-клиенты обычно пытаются держать сотни TCP/UDP peer-сессий, DHT/uTP/trackers. Лимит в диапазоне 100–250 одновременных flows заметно ухудшает P2P-поведение, но почти не затрагивает обычные сценарии при корректной настройке. Это мягкий технический барьер, а не abuse-система со страйками. ## 2. Важное исправление к простой команде Не использовать такую форму как production rule (это антипример; `200` здесь не default и не production-рекомендация): ```nft nft add rule inet filter forward ip saddr 10.8.1.0/24 ct count over 200 drop ``` Проблемы: 1. Это может стать общим лимитом для всей подсети, а не лимитом на каждого клиента. 2. Нет ownership: правило кладётся в generic `inet filter forward`, который может принадлежать не нашему пакету. 3. Неочевидно, в каком network namespace оно применяется. 4. Нет named counter и нормальной диагностики. Нужен per-source key через meter/set и отдельная таблица, которой владеет только AWG2 Harness. ## 3. Recommended nftables shape Правило должно применяться в том же network namespace, где живёт Amnezia AWG/WG interface и где уже применяются `tc`/`ifb0` rules. На практике это namespace контейнера Amnezia, полученный через `/proc//ns/net`. ```nft table inet awg2_harness { counter antitorrent_dropped_v4 {} chain forward_antitorrent { type filter hook forward priority filter; policy accept; ip saddr ct state new \ meter awg2_peer_connlimit_v4 { ip saddr ct count over } \ counter name antitorrent_dropped_v4 \ drop } } ``` Пример для текущей production-подсети: ```nft table inet awg2_harness { counter antitorrent_dropped_v4 {} chain forward_antitorrent { type filter hook forward priority filter; policy accept; ip saddr 10.8.1.0/24 ct state new \ meter awg2_peer_connlimit_v4 { ip saddr ct count over 100 } \ counter name antitorrent_dropped_v4 \ drop } } ``` `ct state new` важен: ограничиваются новые flow attempts сверх порога, а уже установленные flows не начинают внезапно дропаться только потому, что счётчик стал высоким. ## 4. Threshold Рекомендуемый стартовый production baseline: ```toml [anti_torrent] enabled = true max_connections_per_peer = 150 ``` Практические варианты: - `100` — более строгий режим. - `150` — текущий рекомендуемый стартовый baseline, мягче к обычному browsing/mobile traffic. - `200/250` — ещё более permissive варианты. - `70` — агрессивный режим только после наблюдения реального трафика. ## 5. Почему это должно быть в orchestrator Модуль должен жить в Rust-бинаре, а не отдельным ручным правилом, потому что orchestrator должен: - применять правило после container restart/update, когда network namespace изменился; - проверять actual state и чинить drift; - показывать status/counters; - не ломать unrelated nftables/Docker/Amnezia rules; - удалять или отключать только owned state при `enabled = false`. ## 6. Conntrack и производительность `ct count` использует conntrack. На текущем масштабе это нормально: даже 23 peers × 100 flows = около 2300 активных flows до ограничения. Это не выглядит опасно для production-хоста само по себе. Что надо мониторить: ```bash sysctl net.netfilter.nf_conntrack_count sysctl net.netfilter.nf_conntrack_max nft list table inet awg2_harness ``` Если `nf_conntrack_count` приближается к `nf_conntrack_max`, проблема уже системная: надо разбираться с timeout, abuse или capacity. Не надо автоматически увеличивать `nf_conntrack_max` из orchestrator без отдельного решения. ## 7. Acceptance criteria - В правильном Amnezia netns существует `table inet awg2_harness`. - В таблице есть `chain forward_antitorrent` с hook `forward`. - Правило ограничивает `ip saddr `. - Лимит применяется per source VPN IP, а не глобально на всю подсеть. - Drop counter растёт при превышении threshold. - Нормальные сценарии с числом flows ниже threshold не затрагиваются. - При restart контейнера правило пересоздаётся в новом netns. - При `anti_torrent.enabled = false` удаляется или отключается только AWG2-owned nftables state.