Zuletzt aktiv 1 month ago

gistfile1.txt Originalformat
1def accept_aggregate(file, net_file, clients_dir, since='',
2 filter_peer='', external_only='0'):
3 """
4 Aggregate accept events per peer — total bytes, packets, top destinations.
5 Used by wgctl activity to show accepted traffic alongside drops.
6
7 external_only='1': only show traffic to external IPs (non-private)
8 external_only='0': only show traffic to internal IPs (default)
9
10 Output:
11 peer|peer_name|bytes_in|bytes_out|packets_in|packets_out|conn_count
12 dest|peer_name|dst_ip|dst_port|proto|bytes_total|conn_count
13 """
14 from collections import defaultdict
15 from itertools import groupby
16
17 since_dt = parse_since(since) if since else None
18 show_external = str(external_only) == '1'
19
20 peer_stats = defaultdict(lambda: {
21 'bytes_in': 0, 'bytes_out': 0,
22 'packets_in': 0, 'packets_out': 0,
23 'conn_count': 0
24 })
25 # dest_stats = defaultdict(lambda: {'bytes': 0, 'count': 0})
26 dest_stats = defaultdict(lambda: {'bytes_orig': 0, 'bytes_reply': 0, 'count': 0})
27
28 try:
29 with open(file) as f:
30 for line in f:
31 try:
32 e = json.loads(line.strip())
33 peer = e.get('peer', '')
34 if not peer:
35 continue
36 if filter_peer and peer != filter_peer:
37 continue
38
39 # Filter by external/internal
40 is_external = e.get('external', False)
41 if show_external and not is_external:
42 continue
43 if not show_external and is_external:
44 continue
45
46 if since_dt:
47 ts_str = e.get('ts', '')
48 try:
49 from datetime import timezone
50 ev_dt = datetime.fromisoformat(
51 ts_str.replace('Z', '+00:00'))
52 if ev_dt < since_dt:
53 continue
54 except Exception:
55 pass
56
57 dst_ip = e.get('dst_ip', '')
58 dst_port = str(e.get('dst_port', ''))
59 proto = e.get('proto', '')
60 b_orig = e.get('bytes_orig', 0)
61 b_reply = e.get('bytes_reply', 0)
62 p_orig = e.get('packets_orig', 0)
63 p_reply = e.get('packets_reply', 0)
64
65 ps = peer_stats[peer]
66 ps['bytes_out'] += b_orig
67 ps['bytes_in'] += b_reply
68 ps['packets_out'] += p_orig
69 ps['packets_in'] += p_reply
70 ps['conn_count'] += 1
71
72 dest_key = (peer, dst_ip, dst_port, proto)
73 dest_stats[dest_key]['bytes_orig'] += b_orig
74 dest_stats[dest_key]['bytes_reply'] += b_reply
75 dest_stats[dest_key]['count'] += 1
76
77 except Exception:
78 pass
79 except Exception:
80 pass
81
82 # Output peer summaries
83 for peer, ps in sorted(peer_stats.items()):
84 print(f"peer|{peer}|{ps['bytes_in']}|{ps['bytes_out']}|"
85 f"{ps['packets_in']}|{ps['packets_out']}|{ps['conn_count']}")
86
87 # Output top 5 destinations per peer sorted by byte count
88 dest_items = sorted(
89 dest_stats.items(),
90 key=lambda x: (x[0][0], -x[1]['bytes'])
91 )
92 for peer, group in groupby(dest_items, key=lambda x: x[0][0]):
93 top = list(group)[:20]
94 for (p, dst_ip, dst_port, proto), stats in top:
95 print(f"dest|{p}|{dst_ip}|{dst_port}|{proto}|"
96 f"{stats['bytes_orig']}|{stats['bytes_reply']}|{stats['count']}")