# argus-probe — агент ArgusNOC

Один агент для всіх перевірок, Linux і Windows з одного репозиторію (спільні analyzer/queue/api/main-цикл, платформозалежні лише виконавці, фаєрвол, sysinfo, служби, інсталятор). Два systemd-юніти (на Windows — дві служби, див. нижче):

| юніт | що робить |
|---|---|
| `argus-probe` | конфіг з центру, heartbeat 60 с, fping батчами кожні 10 с, mtr плановий (15 хв) і при зміні стану, аналіз порогів, диф маршрутів, черга SQLite, команди, iperf з busy-lock, nftables |
| `argus-agentd` | `:8710 POST /kick` (HMAC від центру), watchdog (heartbeat-файл >5 хв → restart), updater (реліз з центру → sha256/підпис → `update.sh`) |

## Встановлення (Debian 12 / 13, Ubuntu 22.04 / 24.04)

На центрі: `argusctl probe add ams1 NL Amsterdam` → `PROBE_TOKEN`.

```sh
# з архіву
scp argus-probe_v0.1.0.tar.gz root@ams1:/root/ && ssh root@ams1
tar xzf argus-probe_v0.1.0.tar.gz && cd argus-probe
sh install.sh --token argus_xxx [--center https://api.argusnoc.net] [--ssh-port 22]

# або (коли реліз опублікований на центрі) одним рядком:
curl -sL https://get.argusnoc.net | sh -s -- --token argus_xxx
```

Інсталятор: пакети (`fping mtr-tiny iperf3 nftables python3-venv`), `/opt/argus-probe`, venv, `secrets.env` (600), sysctl-тюнінг (BBR, fq, буфери 16 MB, `icmp_ratelimit=0`), nofile 65535, базовий nftables-рулсет, служби. Через кілька секунд у логу — `registered as ams1 (id N), K checks`.

Проба сама визначає, чи є **робочий** IPv6: глобальна адреса (Teredo/6to4 не рахуються) плюс пінг до `2606:4700:4700::1111` / `2001:4860:4860::8888`. Без нього v6-цілі пропускаються, центр отримує `has_ipv6=false` у кожному heartbeat. Перевірка IPv6, NAT і публічних/локальних адрес повторюється кожні 5 хв; при зміні (з'явився/зник v6, змінився NAT, динамічна зовнішня адреса, VPN) проба логує `network changed`, шле подію `network_changed {ipv4, ipv6, local_ipv4, nat, has_ipv6, what}`, перестворює HTTP-клієнт (keep-alive після зміни адреси мертві) і реєструється заново, щоб центр оновив адресу для kick/канарок/GeoIP і перепризначив цілі. Токен до IP не прив'язаний — зміна зовнішньої адреси за NAT сама по собі нічого не ламає. Адреса без зв'язності (RA є, аплінк без v6) не вмикає v6 — інакше всі v6-цілі показали б 100% втрат.

## Фаєрвол

`/etc/nftables.conf` генерує агент повністю (не редагувати вручну): loopback, established, ICMP/ICMPv6, SSH (`ssh_port` з `config.yaml`), `:8710` лише з наборів `center_v4/v6`, `:5201` лише з `peers_v4/v6`, UDP 33434–33534 для traceroute, решта вхідного — drop, вихід відкритий. Набори приходять з центру (`config.yaml center.ipv4/ipv6` + `argusctl fw set argus_peers 4 ...`). Помилка застосування → відкат до попереднього файлу і повідомлення в лог. `firewall_managed: false` вимикає керування.

## Файли

```
/opt/argus-probe
├─ probe/           main, api (клієнт центру), analyzer, queue, sysinfo (nft, diag), runners/ping, runners/mtr
├─ agentd/          kick, watchdog, updater
├─ config.yaml      centers[], local_port, ssh_port, firewall_managed, bin
├─ secrets.env      PROBE_TOKEN
├─ data/            config.json (кеш конфігу), state.json (маршрути, резолви), queue.sqlite, heartbeat, busy.lock, asn.dat
├─ logs/            probe.log, agentd.log (ротація)
└─ update.sh        ./update.sh [ver|--check|--force]
```

## Windows (10/11, Server 2016+, x64)

Клієнту — **`argus-probe-setup_v0.2.16.exe`** (майстер: організація / ім'я / центр, прапорці фаєрвол / Defender / трей) або один рядок у PowerShell від адміністратора:

```powershell
irm https://get.argusnoc.net/win | iex
```

Мова майстра обирається на першому екрані (English / Українська / Русский; авто: uk для української системи, інакше en). Організація, ім'я проби і центр запам'ятовуються (`HKLM\Software\ArgusNOC`, `ProgramData\ArgusNOC\install.json`) і підставляються при повторній інсталяції навіть після повного видалення.
Тихий режим exe для масового розгортання: `argus-probe-setup_v0.2.16.exe /S /ORG=kopiyka [/NAME=x] [/CENTER=https://…] [/NOFIREWALL] [/DEFENDER] [/NOTRAY] [/LANG=uk|ru|en]`.
Після встановлення програма «ArgusNOC Probe» є в «Програми та компоненти» (повне видалення: служби, правила, код; дані — за запитом), у меню Пуск — «ArgusNOC Tray».

Проба сама реєструється на центрі (стан `pending`) — адмін підтверджує її в панелі (Probes → Pending). Токен вводити не треба. Опційно: `& ([scriptblock]::Create((irm https://get.argusnoc.net/win))) -Org kopiyka -Name office-kyiv -NoFirewall -DefenderExclusion` або `$env:ARGUS_ORG='kopiyka'` перед запуском.

| що | де |
|---|---|
| код + embeddable Python | `C:\Program Files\ArgusNOC\{probe,agentd,win,python}` |
| дані, лог, токен | `C:\ProgramData\ArgusNOC\{data,logs,secrets.env}` (лише SYSTEM/Administrators) |
| служби | `ArgusNOC Probe` (ArgusProbe), `ArgusNOC Agent` (ArgusAgentd): LocalSystem, Automatic, recovery restart×3, працюють без входу користувача |
| фаєрвол | правила `ArgusNOC: kick / icmp v4 / icmp v6 / iperf tcp / iperf udp` (лише свої, `firewall_managed: false` вимикає) |
| Event Log | Application, джерело `ArgusNOC` (100 старт/стоп/краш, 200 видалена на центрі, 300/301 оновлення, 400 немає мережі) |
| оновлення | автоматично з центру; вручну `& "C:\Program Files\ArgusNOC\win\update.ps1" [-Version X] [-Force] [-Zip path]` |
| видалення | «Програми та компоненти» → ArgusNOC Probe (або `uninstall.exe /S [/KEEPDATA]`, або `& "C:\Program Files\ArgusNOC\win\uninstall.ps1" [-KeepData] [-Notify]`) |
| трей | іконка в сесії користувача (без прав адміністратора): стан служби і проби (зелена / сіра / жовта), версія, «Запустити/Зупинити пробу», «Перевірити оновлення» — через UAC; **подвійний клік — вікно керування** зі станом, кнопками і переглядом логів (probe.log/agentd.log/Event Log); автозапуск для всіх користувачів, ярлик у меню Пуск |

**За NAT** (типово для Windows в офісі): усе спілкування з центром — вихідне HTTPS, вхідних портів не потрібно. Проба шле `nat: true`, `ipv4/ipv6: null` (публічну адресу центр бере з самого запиту), `local_ipv4` для довідки; agentd не піднімає kick-слухач (`kick_listen: auto`), команди центру приходять із наступним heartbeat (≤ `intervals.heartbeat`, 60 с). ICMP-відповіді і Time Exceeded для traceroute NAT пропускає як для звичайного `tracert`. Такий пробі центр не повинен призначати роль канарки чи iperf-піра.

ICMP на Windows — власний движок на raw-сокетах (без fping/mtr; потрібен LocalSystem), traceroute — той самий сокет, вихід у форматі `mtr --json`. `iperf` на Windows не підтримується (команда повертає `ok:false`). Деталі для розробників — `win/README.md`.

## Діагностика

```sh
tail -f /opt/argus-probe/logs/probe.log
journalctl -u argus-probe -u argus-agentd -n 50
nft list ruleset
# з центру:
argusctl probe cmd ams1 diag            # повний звіт → probe_diag
argusctl probe cmd ams1 run_check '{"type":"mtr","address":"1.1.1.1","family":6}'
argusctl probe cmd ams1 reload_config
argusctl probe cmd ams1 restart
```

## Як рахуються події (на пробі)

- Цикл 10 с, `fping -C 3` → min/avg/max/jitter/loss на ціль; ~1500 адрес на пробу при 500 pps; при перевищенні цикл подовжується і центр отримує `capacity_warning`.
- Базова лінія — медіана avg RTT за годину (лише з «добрих» циклів). Поганий цикл: `loss ≥ 20%` або `RTT > max(median×1.5, median+20 ms)`. 3 погані поспіль → `degraded`, 5 добрих → `recovered`. При обох переходах — mtr, який іде в інцидент.
- Маршрут: плановий mtr; порівняння по ASN-ланцюжку (коли є `asn.dat`, етап 3), інакше по IP хопів без `???`. Новий маршрут має підтвердитись **двома** вимірами поспіль — захист від ECMP-шуму.
- Самотест: канарки (інші проби, дає центр) усі мовчать 3 цикли, або ≥50% цілей degraded одночасно → `self_degraded`; центр глушить події цієї проби і пише адміну.
- Центр недоступний → метрики/події в `data/queue.sqlite` (події з пріоритетом), ліміти `max_age_h=48`, `max_mb=200`; після відновлення черга зливається на наступному heartbeat.
