In-decky-netns NFQUEUE rewriter (window/option-order/IP-ID) and raw-socket synthesizer for nmap probes Linux drops but the target OS answers (T2/T3), driven by os_fingerprint.OS_MANGLE. Packet-shaping logic is pure and unit-tested offline; scapy/netfilterqueue import lazily in the runtime loops. Entry: python -m decnet.cloak (run by the base container; CAP_NET_ADMIN).
54 lines
1.6 KiB
Python
54 lines
1.6 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
Cloak entrypoint — run inside the decky base container (CAP_NET_ADMIN).
|
|
|
|
python -m decnet.cloak
|
|
|
|
Config via env (set by the composer when nmap_os has a mangle profile):
|
|
DECNET_NMAP_OS nmap_os slug (e.g. "windows", "windows_server")
|
|
DECNET_OPEN_PORTS comma-separated TCP ports the decky serves (for T2/T3)
|
|
DECKY_IP this decky's IP (BPF scope for the responder)
|
|
|
|
Starts the mangler and responder, each in its own thread. A slug with no mangle
|
|
profile exits 0 immediately — harmless to launch unconditionally.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import threading
|
|
|
|
from decnet.cloak import mangler, responder
|
|
from decnet.logging import get_logger
|
|
from decnet.os_fingerprint import get_os_mangle
|
|
|
|
log = get_logger("cloak")
|
|
|
|
|
|
def _open_ports() -> frozenset[int]:
|
|
raw = os.environ.get("DECNET_OPEN_PORTS", "")
|
|
return frozenset(int(p) for p in raw.split(",") if p.strip().isdigit())
|
|
|
|
|
|
def main() -> int:
|
|
nmap_os = os.environ.get("DECNET_NMAP_OS", "linux")
|
|
if get_os_mangle(nmap_os) is None:
|
|
log.info("cloak: no mangle profile for %r — exiting", nmap_os)
|
|
return 0
|
|
|
|
threads = [
|
|
threading.Thread(target=mangler.run, args=(nmap_os,),
|
|
name="cloak-mangler", daemon=True),
|
|
threading.Thread(target=responder.run, args=(nmap_os, _open_ports()),
|
|
name="cloak-responder", daemon=True),
|
|
]
|
|
for t in threads:
|
|
t.start()
|
|
log.info("cloak: started for nmap_os=%r", nmap_os)
|
|
for t in threads:
|
|
t.join()
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|