Block BitTorrent on the server

- awg-ctrl: optional nft table awg_torrent (GET/PUT /api/torrent, off by
  default). A connection is judged by its first packets, like Xray's
  sniffing: DHT, UDP trackers, uTP SYN, and with @ih support the plain
  TCP handshake and HTTP announce. A match marks the connection in
  conntrack and drops it whole; without @ih only the UDP part is used
- devices that tried are kept in a 10-minute set and flagged as
  "torrent" in user and device stats; with shaping on they sit in the
  background class while the flag lasts
- metrics: awg_torrent_block_enabled/active, awg_torrent_blocked_total,
  awg_torrent_devices and per-peer awg_peer_torrent
- panel: "Торренты" section in server settings, "торренты" chip on users
  and devices; Save sends only what changed
This commit is contained in:
2026-10-17 23:35:30 +03:00
parent cf6af5ce0a
commit c73da602d6
16 changed files with 575 additions and 55 deletions
+11
View File
@@ -19,6 +19,7 @@ export interface User {
rx?: number;
tx?: number;
priority?: Priority; // нет у awg-ctrl старше деления канала
torrent?: boolean; // пытался качать торренты за последние 10 минут (при включённой блокировке)
}
export interface ServerInfo {
name: string;
@@ -79,6 +80,16 @@ export interface ShapingStatus {
rateUp: number;
}
// Блокировка BitTorrent (GET/PUT /api/torrent на awg-ctrl сервера).
export interface TorrentStatus {
settings: { enabled: boolean };
active: boolean; // nft-таблица реально стоит
tcp: boolean; // проверяется и TCP-рукопожатие (нужен свежий nftables)
hits: number; // заблокированных попыток с последнего применения
seen: { ip: string; name: string }[]; // кто пытался за последние 10 минут
error?: string;
}
// Сравнение версий вида 0.3.3 (хвост после «-» не учитывается): <0 — a старше b.
export function cmpVersion(a: string, b: string): number {
const pa = a.split('-')[0].split('.').map(Number), pb = b.split('-')[0].split('.').map(Number);