Бизнес-логика шейпера. Применяет HTB-профили на FastDPI per-IP по данным из биллинга.
loshaper-api контейнер) → SSH к FastDPI (fdpi_ctrl). UI в LoNGFW /shaper/*.| Хост | 10.0.0.13 (контейнер loshaper-api) |
| Порт | 8090 |
| Auth | header X-Auth-Token (env LOSHAPER_API_TOKEN в /opt/LoNGFW/.env) |
| Build | applications/LoShaper/api/ (Flask), lib/ (classify/tariff/ssh-client) |
| DPI | 10.9.0.198 (через AWG, после 2026-04-30) |
| DPI SSH-key | volume ${DPI_SSH_KEY_PATH:-/root/.ssh/id_ed25519}:/root/.ssh/id_ed25519:ro |
| Audit log | volume /data/loshaper/audit.jsonl |
| Auto-apply | каждые 300с (AUTO_APPLY_INTERVAL_SEC), 4 worker'а защищены Redis-локом lock:loshaper:auto_apply |
| URL | метод | что |
|---|---|---|
/health |
GET | пинг |
/api/subscribers |
GET | абоненты с classification |
/api/profiles |
GET | существующие профили на DPI |
/api/bindings |
GET | текущие IP↔profile привязки на DPI |
/api/diff |
GET | разница actual vs target |
/api/apply |
POST | применить (load profile + bind/unbind) |
/api/bind |
POST | вручную привязать IP↔profile |
/api/log |
GET | audit-журнал |
applications/LoShaper/config.yml:
dpi:
host: 10.9.0.198
user: root
ssh_key: ~/.ssh/id_rsa
profiles_dir: /etc/dpi/profiles/loshaper
burst_percent: 25
upload_ratio: 0.5
tariff_overrides:
TARIFF_50M: { download_kbps: 51200, upload_kbps: 25600 }
...
disabled:
download_kbps: 256
upload_kbps: 256
subscriber_source:
type: api # или: file (mock JSON для разработки)
api_url: https://sorm.smit.4gain.pro/api/subscribers/
api_token: ...
priority_users.yml — объединено priority + super:
- contract: "20240422-000001"
ips: ["10.1.4.5"]
reason: "офис ЛотосПлюс"
# без profile = priority (VIP без шейпера, не биндится)
- contract: "20260101-000099"
ips: ["10.1.4.99"]
profile: "TARIFF_500M"
reason: "тестовый аккаунт"
# с profile = super (force-bind, перекрывает биллинг)
Для каждого IP: priority? → super? → disabled (negative balance)? → tariff? → static_ip → fallback.
⚠️ Сумма class.rate < root.rate — иначе FastDPI говорит "поведение не определено".
htb_root=rate <N>mbit
htb_class0=rate 40% ceil <N>mbit # web
htb_class1=rate 30% ceil <N>mbit # QUIC
htb_class2..7=rate 8bit ceil <N>mbit # default+torrent (борровит)
(симметрично htb_inbound_*)
# load profile (создать/обновить)
fdpi_ctrl load profile --policing /etc/dpi/profiles/loshaper/<NAME>.cfg --profile.name <NAME>
# bind IP↔profile (per-subscriber service 18)
fdpi_ctrl load --policing --profile.name <NAME> --ip <IP>
# del profile
fdpi_ctrl del profile --profile.name <NAME>
# unbind IP
fdpi_ctrl del --policing --ip <IP>
# list bindings (text format — последнее слово = profile_name)
fdpi_ctrl list all --policing
udr=1 в /etc/dpi/fastdpi.conf + restart fastdpi.dscp_enable=1 + /etc/dpi/protocols.dscp (минимум default cs0, собрать через lst2dscp).--profile.name X) — не сессионный service 18.static IP)./blocks пока эвристика dropped_packets ≤ 5 AND dropped_bytes < 10KB = блок.subscriber_source готов к type: billing_api, но API биллинга нет (используем MariaDB напрямую).applications/LoShaper/shaper.py — thin client REST API. Команды:
shaper.py show — текущие subscribers/profiles/bindingsshaper.py diff — diff actual vs targetshaper.py apply [--dry-run] — применитьshaper.py bind <ip> <profile> / unbind <ip> — manualshaper.py log — auditdocker logs loshaper-api, проверить SSH к DPI ssh root@10.9.0.198fdpi_ctrl list all --policing | grep <ip> на DPIls -la /etc/dpi/profiles/loshaper/ на DPI10.9.0.198.Changelog