Repository navigation
Description
Симптом
На боевой ноде na-diagnose выдаёт предупреждение о приближении к per-IP лимиту коннектов, которого в реальности нет:
▲ макс. конн. с одного IP = 6790 при CONN_LIMIT=8192 (≥80%) — за CGNAT возможны дропы, подними CONN_LIMIT
Разбор источников на той же ноде:
| Пир | Коннектов | Что это |
|---|---|---|
127.0.0.1 |
7007 | keepalive nginx ↔ xray внутри бокса (каждая пара считается дважды — оба конца в выводе ss) |
| выход-нода флота | 882 | исходящие соединения плеча |
| РФ-вход флота | 644 | входящие, но адрес в whitelist_v4 |
То есть предупреждение целиком собрано из трафика, к которому правило ct count неприменимо.
Причина
scripts/diagnose.sh:507-515:
CLIM=$(nft list chain inet na_filter input | grep -oE 'ct count over [0-9]+' | head -1 | grep -oE '[0-9]+')
MAXIP=$(ss -tnH state established | awk '{print $NF}' | sed -E 's/:[0-9]+$//; ...' | sort | uniq -c | sort -rn | head -1 | awk '{print $1+0}')ss -tnH state established отдаёт все established-сокеты — входящие и исходящие, по всем портам, включая loopback; $NF — адрес пира. Датчик сравнивает это число с CONN_LIMIT.
А само правило (scripts/protect.sh:538-543) заметно уже:
tcp dport ${p} ct state new meter cc4_${p} { ip saddr ct count over ${CONN_LIMIT} } drop
— только ct state new, только на портах из TCP_PORTS, только по ip saddr. И стоит оно в цепочке после двух безусловных accept (живой ruleset, na_filter input):
iif "lo" accept # ← loopback не доходит до лимита
ct state established,related accept
ct state invalid drop
ip saddr @whitelist_v4 accept # ← вайтлист не доходит до лимита
...
Итог: числитель и знаменатель меряют разные вещи. Loopback и вайтлист физически не могут упереться в ct count, исходящие соединения — тем более.
Почему это стоит чинить
Ложная тревога подталкивает ровно к вредному действию — поднять CONN_LIMIT, то есть ослабить защиту от exhaustion, ради проблемы, которой нет. На нодах с внутренним nginx-фолбэком (selfsteal, xHTTP-плечи) loopback-пар всегда тысячи, так что предупреждение там будет гореть постоянно, обесценивая секцию.
Предложение
Считать метрику по тому же срезу, что и правило:
- Исключить
127.0.0.0/8и::1. - Исключить членов
whitelist_v4/whitelist_v6(они уже читаются рядом, в проверке дрейфа —scripts/diagnose.sh:495-506). - Считать только входящие на порты из
TCP_PORTS— напримерss -tnH state established '( sport = :443 or sport = :8445 )'по фактуtcp_ports=изprotect.installed, группируя по адресу пира.
Как вариант — брать число прямо из conntrack по тем же критериям (conntrack -L -p tcp --dport <p> --state ESTABLISHED), но фильтрация вывода ss дешевле и не тянет зависимость.
Окружение
node-accelerator 4.0.0 (по исходникам v4.0.1 код не менялся), Debian 12/13, XanMod 6.18.47, FW_MODE=strict, CONN_LIMIT=8192, нода с selfsteal-nginx + xHTTP-плечом.
Activity
jestivald commentedon Sep 2, 2026
Исправлено в v4.1 (PR #42, merge 427b13f): https://github.com/jestivald/node-accelerator/releases/tag/v4.1 — разбор в CHANGELOG, секция v4.1.
diagnose: датчики меряют тот же срез, что и правила + честный --json …
merge v4.1-diagnose: #27 #30 #31 #32 #34 #35 #37 #38 #39 — датчики ме…