Initial commit: DECNET honeypot/deception network framework
Core CLI, service plugins (SSH/SMB/FTP/HTTP/RDP), Docker Compose orchestration, MACVLAN networking, and Logstash log forwarding. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
68
decnet/ini_loader.py
Normal file
68
decnet/ini_loader.py
Normal file
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
Parse DECNET INI deployment config files.
|
||||
|
||||
Format:
|
||||
[general]
|
||||
net=192.168.1.0/24
|
||||
gw=192.168.1.1
|
||||
interface=wlp6s0
|
||||
log_target=192.168.1.5:5140 # optional
|
||||
|
||||
[hostname-1]
|
||||
ip=192.168.1.82 # optional
|
||||
services=ssh,smb # optional; falls back to --randomize-services
|
||||
|
||||
[hostname-2]
|
||||
services=ssh
|
||||
|
||||
[hostname-3]
|
||||
ip=192.168.1.32
|
||||
"""
|
||||
|
||||
import configparser
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass
|
||||
class DeckySpec:
|
||||
name: str
|
||||
ip: str | None = None
|
||||
services: list[str] | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class IniConfig:
|
||||
subnet: str | None = None
|
||||
gateway: str | None = None
|
||||
interface: str | None = None
|
||||
log_target: str | None = None
|
||||
deckies: list[DeckySpec] = field(default_factory=list)
|
||||
|
||||
|
||||
def load_ini(path: str | Path) -> IniConfig:
|
||||
"""Parse a DECNET INI file and return an IniConfig."""
|
||||
cp = configparser.ConfigParser()
|
||||
read = cp.read(str(path))
|
||||
if not read:
|
||||
raise FileNotFoundError(f"Config file not found: {path}")
|
||||
|
||||
cfg = IniConfig()
|
||||
|
||||
if cp.has_section("general"):
|
||||
g = cp["general"]
|
||||
cfg.subnet = g.get("net")
|
||||
cfg.gateway = g.get("gw")
|
||||
cfg.interface = g.get("interface")
|
||||
cfg.log_target = g.get("log_target") or g.get("log-target")
|
||||
|
||||
for section in cp.sections():
|
||||
if section == "general":
|
||||
continue
|
||||
s = cp[section]
|
||||
ip = s.get("ip")
|
||||
svc_raw = s.get("services")
|
||||
services = [sv.strip() for sv in svc_raw.split(",")] if svc_raw else None
|
||||
cfg.deckies.append(DeckySpec(name=section, ip=ip, services=services))
|
||||
|
||||
return cfg
|
||||
Reference in New Issue
Block a user