# plugins/syslog/network.py """Whether a sender's address is really the sender's (#6003). A source is told apart by the address its lines come from. Docker can hide that address: a port published through Swarm's ingress (the default) hands every packet to Steward from an address on the ingress network, so every device reads as one sender. Such an address lies on one of the container's own networks. The page says so beside it and how to fix it: publish the port in host mode.""" from __future__ import annotations import ipaddress import socket import struct from functools import lru_cache ROUTES = "/proc/net/route" def subnets_from(route_table: str) -> list[ipaddress.IPv4Network]: """The networks a host is directly on, from /proc/net/route's text: each route with no gateway, the default route left out.""" out = [] for line in route_table.splitlines()[1:]: fields = line.split() if len(fields) < 8: continue try: dest, gateway, mask = (int(fields[i], 16) for i in (1, 2, 7)) except ValueError: continue if dest == 0 or gateway != 0: continue address = socket.inet_ntoa(struct.pack(" tuple[ipaddress.IPv4Network, ...]: """This container's own networks, read once; none off Linux.""" try: with open(ROUTES) as f: return tuple(subnets_from(f.read())) except OSError: return () def on_own_network(address: str, subnets=None) -> bool: """Whether a sender's address is on one of Steward's own networks: most likely Docker standing in for the real sender.""" try: ip = ipaddress.ip_address(address) except ValueError: return False return any(ip in net for net in (own_subnets() if subnets is None else subnets))