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

Function do_network_identity

network_diagnostics.py:836–912  ·  view source on GitHub ↗

Best-effort identity of the network Ragnar is attached to: DNS search domain(s), nameservers, this host's name/FQDN, and the default gateway (with reverse-DNS). No single source is authoritative, so several are merged and the provenance is reported.

()

Source from the content-addressed store, hash-verified

834 baseline = _arp_baseline_load()
835 gws = baseline.setdefault('gateways', {})
836 base_mac = gws.get(gw)
837 if gw_mac and not base_mac and learn:
838 gws[gw] = gw_mac
839 _arp_baseline_save(baseline)
840 base_mac = gw_mac
841 learned = True
842
843 if not gw_mac:
844 verdict = 'unknown'
845 reasons.append(f'could not resolve the gateway {gw} MAC (no ARP reply)')
846 elif base_mac and gw_mac != base_mac:
847 verdict = 'spoofed'
848 reasons.append(f'gateway {gw} MAC changed from trusted {base_mac} to {gw_mac} '
849 '— classic ARP-spoofing / MITM signature')
850
851 # One MAC claiming many IPs (attacker impersonating multiple hosts). The
852 # gateway MAC is excluded — a router legitimately fronts its own address.
853 entries = _neigh_entries(iface)
854 mac_ips = {}
855 for ip, mac, _ in entries:
856 mac_ips.setdefault(mac, set()).add(ip)
857 impersonators = [{'mac': mac, 'ips': sorted(ips)}
858 for mac, ips in mac_ips.items()
859 if len(ips) >= _ARP_IMPERSONATOR_MIN_IPS and mac != gw_mac]
860 if impersonators:
861 if verdict == 'clean':
862 verdict = 'suspicious'
863 for imp in impersonators:
864 ips = imp['ips']
865 reasons.append(f"MAC {imp['mac']} answers for {len(ips)} IPs "
866 f"({', '.join(ips[:4])}{'…' if len(ips) > 4 else ''}) "
867 '— possible ARP spoofing')
868
869 return {'success': True, 'verdict': verdict, 'interface': iface,
870 'gateway': {'ip': gw, 'mac': gw_mac, 'baseline': base_mac,
871 'learned': learned},
872 'impersonators': impersonators,
873 'neighbor_count': len(entries),
874 'reasons': reasons}
875
876
877# --------------------------------------------------------------------------
878# MAC Watch — detection-only MAC-spoofing + randomization detector & tracker.
879#
880# Three jobs, all passive (reads the kernel neighbour table, optionally an
881# arp-scan sweep — no capture, and it never spoofs anything itself):
882# 1. Spoofing / cloning: a vendor OUI wearing the locally-administered bit
883# (disguised vendor), the same MAC bound to several IPs (a clone), and an
884# IP whose MAC changed identity over time (the past-spoofing signature).
885# 2. Randomization: privacy (locally-administered, vendor-less) MACs on the
886# segment, reported as an aggregate inventory rather than per-MAC noise so
887# a busy Wi-Fi segment full of iPhones doesn't drown a real spoof.
888# 3. Tracking: an IP that cycles through several randomized MACs over time is
889# one device rotating to hide — grouped into a track so it can be followed
890# across the addresses it hides behind.
891#
892# A small JSON store keeps first/last-seen, per-IP MAC history and change
893# events, so "current AND past" spoofing/rotation survives across checks and

Callers 1

net_identityFunction · 0.85

Calls 9

_read_resolv_confFunction · 0.85
_nmcli_global_valuesFunction · 0.85
_haveFunction · 0.85
_runFunction · 0.85
_default_gatewayFunction · 0.85
_reverse_dnsFunction · 0.85
_default_route_ifaceFunction · 0.85
_iface_vpn_infoFunction · 0.85
appendMethod · 0.80

Tested by

no test coverage detected