Dernière activité 1 month ago

nuno a révisé ce gist 1 month ago. Aller à la révision

1 file changed, 110 insertions

gistfile1.txt(fichier créé)

@@ -0,0 +1,110 @@
1 + def activity_aggregate(fw_file, wg_file, wg_interface, net_file,
2 + clients_dir, meta_dir, hours, filter_peer,
3 + filter_service_ip):
4 + """
5 + Aggregate activity data for wgctl activity.
6 + Output:
7 + peer|name|rx_bytes|tx_bytes|drop_count
8 + service|peer_name|dest_display|drop_count
9 + """
10 + hours = int(hours) if hours else 24
11 + cutoff = None
12 + if hours > 0:
13 + cutoff = datetime.now(timezone.utc) - timedelta(hours=hours)
14 +
15 + # Preload lookups once
16 + ip_to_peer = build_ip_to_name(clients_dir)
17 + pubkey_to_peer = build_pubkey_to_name(clients_dir)
18 + net_data = load_net_data(net_file)
19 +
20 + def _reverse(dest_ip, dest_port, proto):
21 + return reverse_lookup(net_data, dest_ip, dest_port, proto)
22 +
23 + # WireGuard transfer totals
24 + peer_rx = defaultdict(int)
25 + peer_tx = defaultdict(int)
26 + try:
27 + result = subprocess.run(
28 + ['wg', 'show', wg_interface, 'transfer'],
29 + capture_output=True, text=True
30 + )
31 + for line in result.stdout.strip().splitlines():
32 + parts = line.split()
33 + if len(parts) >= 3:
34 + pubkey, rx, tx = parts[0], int(parts[1]), int(parts[2])
35 + peer = pubkey_to_peer.get(pubkey)
36 + if peer:
37 + peer_rx[peer] += rx
38 + peer_tx[peer] += tx
39 + except Exception:
40 + pass
41 +
42 + # Parse fw_events for drops
43 + peer_drops = defaultdict(int)
44 + service_drops = defaultdict(lambda: defaultdict(int))
45 +
46 + if os.path.exists(fw_file):
47 + try:
48 + with open(fw_file) as f:
49 + for line in f:
50 + line = line.strip()
51 + if not line:
52 + continue
53 + try:
54 + ev = json.loads(line)
55 + if cutoff:
56 + ts_str = ev.get('timestamp', '')
57 + try:
58 + ts = datetime.fromisoformat(ts_str)
59 + if ts.tzinfo is None:
60 + ts = ts.replace(tzinfo=timezone.utc)
61 + if ts < cutoff:
62 + continue
63 + except Exception:
64 + pass
65 +
66 + src_ip = ev.get('src_ip', '')
67 + if not src_ip:
68 + continue
69 +
70 + dest_ip = ev.get('dest_ip', '')
71 + dest_port = str(ev.get('dest_port', ''))
72 + proto_num = ev.get('ip.protocol', 0)
73 + proto = PROTO_MAP.get(int(proto_num), str(proto_num))
74 +
75 + peer = ip_to_peer.get(src_ip)
76 + if not peer:
77 + continue
78 + if filter_peer and peer != filter_peer:
79 + continue
80 + if filter_service_ip and dest_ip != filter_service_ip:
81 + continue
82 +
83 + svc_name = _reverse(dest_ip, dest_port, proto)
84 + dest_display = make_dest_display(dest_ip, dest_port, proto, svc_name)
85 +
86 + peer_drops[peer] += 1
87 + service_drops[peer][dest_display] += 1
88 +
89 + except Exception:
90 + continue
91 + except Exception:
92 + pass
93 +
94 + # Collect peers with any activity
95 + all_peers = set()
96 + all_peers.update(k for k in peer_rx if peer_rx[k] > 0)
97 + all_peers.update(k for k in peer_tx if peer_tx[k] > 0)
98 + all_peers.update(peer_drops.keys())
99 + if filter_peer:
100 + all_peers = {p for p in all_peers if p == filter_peer}
101 +
102 + for peer in sorted(all_peers):
103 + rx = peer_rx.get(peer, 0)
104 + tx = peer_tx.get(peer, 0)
105 + drops = peer_drops.get(peer, 0)
106 + print(f"peer|{peer}|{rx}|{tx}|{drops}")
107 +
108 + svc_map = service_drops.get(peer, {})
109 + for dest_display, count in sorted(svc_map.items(), key=lambda x: -x[1]):
110 + print(f"service|{peer}|{dest_display}|{count}")
Plus récent Plus ancien