Add LAN-broadcast lockdown, per-rotation MAC, leak audit panel
Tier-1 paranoid hardening: privacy_lan.py disables LLMNR/NetBIOS/mDNS with reversible snapshot; service rotates MAC on every chain rotation when enabled; leak_audit.py probes every leak surface (IP, DNS, IPv6, WPAD, GPO, ProxySettingsPerUser, LAN broadcast, VPN, WebRTC) and renders pass/fail in Privacy tab. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -30,6 +30,11 @@ from .firewall import disengage as fw_disengage, engage as fw_engage, is_admin
|
||||
from .gost_util import build_gost_cmd, ensure_gost, popen_no_window, read_gost_log_tail, terminate_process
|
||||
from .leak_detect import is_chain_leak, leak_reason
|
||||
from .mac_spoof import restore_macs, spoof_all_physical
|
||||
from .privacy_lan import (
|
||||
LanSnapshot,
|
||||
engage_lan_lockdown,
|
||||
restore_lan,
|
||||
)
|
||||
from .sysproxy import (
|
||||
clear_system_proxy,
|
||||
detect_policy_overrides,
|
||||
@@ -76,6 +81,7 @@ class ChainService:
|
||||
self._hostname_original: str | None = None
|
||||
self._ipv6_adapters: list[str] = []
|
||||
self._webrtc_was_applied: bool = False
|
||||
self._lan_snap: LanSnapshot | None = None
|
||||
|
||||
def _manual_exit_url(self) -> str | None:
|
||||
u = normalize_proxy_url(self._settings.manual_exit_proxy)
|
||||
@@ -167,6 +173,14 @@ class ChainService:
|
||||
elif s.harden_webrtc_enabled:
|
||||
self._notify({"type": "log", "text": "WebRTC hardening enabled but not Admin — skipped."})
|
||||
|
||||
if s.lan_lockdown_enabled and is_admin():
|
||||
snap, logs = engage_lan_lockdown()
|
||||
self._lan_snap = snap
|
||||
for ln in logs:
|
||||
self._notify({"type": "log", "text": f"LAN: {ln}"})
|
||||
elif s.lan_lockdown_enabled:
|
||||
self._notify({"type": "log", "text": "LAN lockdown enabled but not Admin — skipped."})
|
||||
|
||||
def _restore_privacy(self) -> None:
|
||||
if self._mac_originals:
|
||||
for ln in restore_macs(self._mac_originals):
|
||||
@@ -184,6 +198,10 @@ class ChainService:
|
||||
apply_webrtc_hardening(False)
|
||||
self._webrtc_was_applied = False
|
||||
self._notify({"type": "log", "text": "WebRTC policy restored."})
|
||||
if self._lan_snap is not None and is_admin():
|
||||
for ln in restore_lan(self._lan_snap):
|
||||
self._notify({"type": "log", "text": f"LAN: {ln}"})
|
||||
self._lan_snap = None
|
||||
|
||||
def _run_thread(self) -> None:
|
||||
try:
|
||||
@@ -390,6 +408,17 @@ class ChainService:
|
||||
ok, msg = flush_dns_cache()
|
||||
if ok:
|
||||
log.debug("DNS cache flushed before chain run")
|
||||
# Per-rotation MAC re-randomization (only if mac_spoof is also on, since
|
||||
# without spoof there's no original snapshot we own to mutate).
|
||||
if (
|
||||
self._settings.mac_rotate_on_chain_rotate
|
||||
and self._settings.mac_spoof_enabled
|
||||
and is_admin()
|
||||
and self._mac_originals
|
||||
):
|
||||
_, logs = spoof_all_physical(self._mac_originals)
|
||||
for ln in logs:
|
||||
self._notify({"type": "log", "text": f"MAC rotate: {ln}"})
|
||||
listen = self._settings.listen_addr()
|
||||
cmd = build_gost_cmd(gost, listen, chain)
|
||||
self._notify({
|
||||
|
||||
Reference in New Issue
Block a user