MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / __init__

Method __init__

traffic_analyzer.py:279–357  ·  view source on GitHub ↗
(self, shared_data=None, interface: str = None)

Source from the content-addressed store, hash-verified

277
278 # Passive host discovery: periodically flush observed LAN hosts into the
279 # hosts DB so traffic-only hosts (firewalled, never scanned) get tracked.
280 PASSIVE_SYNC_INTERVAL = 30.0 # seconds between DB flushes
281 PASSIVE_MIN_PACKETS = 5 # min packets to upsert if no MAC yet
282 PASSIVE_MAX_LISTEN_PORTS = 100 # cap per host
283 PASSIVE_LAN_PREFIX = 24 # /24 around each known local/gateway IP
284
285 # Bounded state. Alerts and DNS queries are ring buffers already, but
286 # host_stats, connections and the beacon flow history gain an entry per new
287 # peer/flow seen and have no natural ceiling — on a box left capturing for a
288 # week they are the only thing that grows without limit. Cap them and evict
289 # the least-recently-seen entries.
290 #
291 # The caps are what makes this feature honest on a 512MB Pi Zero 2 W: at the
292 # low-memory numbers below the tracked state tops out around 3MB, on top of
293 # ~18MB for the analyzer itself and ~8MB for tcpdump.
294 STATE_PRUNE_INTERVAL = 60.0 # seconds between eviction sweeps
295 MAX_TRACKED_HOSTS = 4000
296 MAX_TRACKED_CONNECTIONS = 8000
297 MAX_TRACKED_FLOWS = 2000 # each holds a 64-sample ring buffer
298 LOW_MEMORY_RAM_GB = 1.0 # below this, use the divided caps
299 LOW_MEMORY_DIVISOR = 8
300
301 # Rate limiting
302 MAX_ALERTS_PER_MINUTE = 10
303 STATS_RETENTION_HOURS = 24
304
305 def __init__(self, shared_data=None, interface: str = None):
306 self.shared_data = shared_data
307 self.interface = interface or self._detect_interface()
308
309 self._running = False
310 self._capture_process: Optional[subprocess.Popen] = None
311 self._capture_thread: Optional[threading.Thread] = None
312 self._analysis_thread: Optional[threading.Thread] = None
313
314 self._packet_queue: queue.Queue = queue.Queue(maxsize=10000)
315 self._lock = threading.Lock()
316
317 # Local IP addresses to exclude from alerts (Ragnar's own IPs)
318 self._local_ips: set = self._detect_local_ips()
319
320 # Default gateway IPs: exempt from port-scan heuristic.
321 self._gateway_ips: set = self._detect_gateway_ips()
322
323 # LAN networks for passive host discovery (derived from local+gateway IPs).
324 self._lan_networks: List[ipaddress.IPv4Network] = self._derive_lan_networks()
325
326 # Passive discovery state:
327 # _mac_by_ip: IP -> MAC (from ARP replies)
328 # _listening_ports: IP -> set of service ports it appears to serve
329 # _hostname_by_ip: IP -> hostname (from observed DNS replies)
330 self._mac_by_ip: Dict[str, str] = {}
331 self._listening_ports: Dict[str, set] = {}
332 self._hostname_by_ip: Dict[str, str] = {}
333 self._last_passive_sync: float = time.time()
334
335 # Statistics storage
336 self.host_stats: Dict[str, HostTrafficStats] = {}

Callers

nothing calls this directly

Calls 7

_detect_interfaceMethod · 0.95
_detect_local_ipsMethod · 0.95
_detect_gateway_ipsMethod · 0.95
_derive_lan_networksMethod · 0.95
get_server_capabilitiesFunction · 0.90
warningMethod · 0.80
setFunction · 0.50

Tested by

no test coverage detected