chore: enforce strict typing and internal naming conventions across web components
This commit is contained in:
103
GEMINI.md
Normal file
103
GEMINI.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
# DECNET (Deception Network) Project Context
|
||||||
|
|
||||||
|
DECNET is a high-fidelity honeypot framework designed to deploy heterogeneous fleets of fake machines (called **deckies**) that appear as real hosts on a local network.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
- **Core Purpose:** To lure, profile, and log attacker interactions within a controlled, deceptive environment.
|
||||||
|
- **Key Technology:** Linux-native container networking (MACVLAN/IPvlan) combined with Docker to give each decoy its own MAC address, IP, and realistic TCP/IP stack behavior.
|
||||||
|
- **Main Components:**
|
||||||
|
- **Deckies:** Group of containers sharing a network namespace (one base container + multiple service containers).
|
||||||
|
- **Archetypes:** Pre-defined machine profiles (e.g., `windows-workstation`, `linux-server`) that bundle services and OS fingerprints.
|
||||||
|
- **Services:** Modular honeypot plugins (SSH, SMB, RDP, etc.) built as `BaseService` subclasses.
|
||||||
|
- **OS Fingerprinting:** Sysctl-based TCP/IP stack tuning to spoof OS detection (nmap).
|
||||||
|
- **Logging Pipeline:** RFC 5424 syslog forwarding to an isolated SIEM/ELK stack.
|
||||||
|
|
||||||
|
## Technical Stack
|
||||||
|
|
||||||
|
- **Language:** Python 3.11+
|
||||||
|
- **CLI Framework:** [Typer](https://typer.tiangolo.com/)
|
||||||
|
- **Data Validation:** [Pydantic v2](https://docs.pydantic.dev/)
|
||||||
|
- **Orchestration:** Docker Engine 24+ (via Docker SDK for Python)
|
||||||
|
- **Networking:** MACVLAN (default) or IPvlan L2 (for WiFi/restricted environments).
|
||||||
|
- **Testing:** Pytest (100% pass requirement).
|
||||||
|
- **Formatting/Linting:** Ruff, Bandit (SAST), pip-audit.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```text
|
||||||
|
Host NIC (eth0)
|
||||||
|
└── MACVLAN Bridge
|
||||||
|
├── Decky-01 (192.168.1.10) -> [Base] + [SSH] + [HTTP]
|
||||||
|
├── Decky-02 (192.168.1.11) -> [Base] + [SMB] + [RDP]
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Base Container:** Owns the IP/MAC, sets `sysctls` for OS spoofing, and runs `sleep infinity`.
|
||||||
|
- **Service Containers:** Use `network_mode: service:<base>` to share the identity and networking of the base container.
|
||||||
|
- **Isolation:** Decoy traffic is strictly separated from the logging network.
|
||||||
|
|
||||||
|
## Key Commands
|
||||||
|
|
||||||
|
### Development & Maintenance
|
||||||
|
- **Install (Dev):**
|
||||||
|
- `rm .venv -rf`
|
||||||
|
- `python3 -m venv .venv`
|
||||||
|
- `source .venv/bin/activate`
|
||||||
|
- `pip install -e .`
|
||||||
|
- **Run Tests:** `pytest` (Run before any commit)
|
||||||
|
- **Linting:** `ruff check .`
|
||||||
|
- **Security Scan:** `bandit -r decnet/`
|
||||||
|
- **Web Git:** git.resacachile.cl (Gitea)
|
||||||
|
|
||||||
|
### CLI Usage
|
||||||
|
- **List Services:** `decnet services`
|
||||||
|
- **List Archetypes:** `decnet archetypes`
|
||||||
|
- **Dry Run (Compose Gen):** `decnet deploy --deckies 3 --randomize-services --dry-run`
|
||||||
|
- **Deploy (Full):** `sudo .venv/bin/decnet deploy --interface eth0 --deckies 5 --randomize-services`
|
||||||
|
- **Status:** `decnet status`
|
||||||
|
- **Teardown:** `sudo .venv/bin/decnet teardown --all`
|
||||||
|
|
||||||
|
## Development Conventions
|
||||||
|
|
||||||
|
- **Code Style:**
|
||||||
|
- Strict adherence to Ruff/PEP8.
|
||||||
|
- **Always use typed variables**. If any non-types variables are found, they must be corrected.
|
||||||
|
- The correct way is `x: int = 1`, never `x : int = 1`.
|
||||||
|
- If assignment is present, always use a space between the type and the equal sign `x: int = 1`.
|
||||||
|
- **Never** use lowercase L (l), uppercase o (O) or uppercase i (i) in single-character names.
|
||||||
|
- **Internal vars are to be declared with an underscore** (_internal_variable_name).
|
||||||
|
- **Internal to internal vars are to be declared with double underscore** (__internal_variable_name).
|
||||||
|
- Always use snake_case for code.
|
||||||
|
- Always use PascalCase for classes and generics.
|
||||||
|
- **Testing:** New features MUST include a `pytest` case. 100% test pass rate is mandatory before merging.
|
||||||
|
- **Plugin System:**
|
||||||
|
- New services go in `decnet/services/<name>.py`.
|
||||||
|
- Subclass `decnet.services.base.BaseService`.
|
||||||
|
- The registry uses auto-discovery; no manual registration required.
|
||||||
|
- **Configuration:**
|
||||||
|
- Use Pydantic models in `decnet/config.py` for any new settings.
|
||||||
|
- INI file parsing is handled in `decnet/ini_loader.py`.
|
||||||
|
- **State Management:**
|
||||||
|
- Runtime state is persisted in `decnet-state.json`.
|
||||||
|
- Do not modify this file manually.
|
||||||
|
- **General Development Guidelines**:
|
||||||
|
- **Never** commit broken code.
|
||||||
|
- **No matter how small** the changes, they must be committed.
|
||||||
|
- **If new features are addedd** new tests must be added, too.
|
||||||
|
- **Never present broken code to the user**. Test, validate, then present.
|
||||||
|
- **Extensive testing** for every function must be created.
|
||||||
|
- **Always develop in the `dev` branch, never in `main`.**
|
||||||
|
- **Test in the `testing` branch.**
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
- `decnet/`: Main source code.
|
||||||
|
- `services/`: Honeypot service implementations.
|
||||||
|
- `logging/`: Syslog formatting and forwarding logic.
|
||||||
|
- `correlation/`: (In Progress) Logic for grouping attacker events.
|
||||||
|
- `templates/`: Dockerfiles and entrypoint scripts for services.
|
||||||
|
- `tests/`: Pytest suite.
|
||||||
|
- `pyproject.toml`: Dependency and entry point definitions.
|
||||||
|
- `CLAUDE.md`: Claude-specific environment guidance.
|
||||||
|
- `DEVELOPMENT.md`: Roadmap and TODOs.
|
||||||
31
decnet.json
Normal file
31
decnet.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{"timestamp": "2026-04-07 19:48:29", "decky": "decky-webmail", "service": "smtp", "event_type": "startup", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:48:29.520153+00:00 decky-webmail smtp - startup - SMTP server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 19:48:29", "decky": "decky-webmail", "service": "imap", "event_type": "startup", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:48:29.525953+00:00 decky-webmail imap - startup - IMAP server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 19:48:29", "decky": "decky-webmail", "service": "pop3", "event_type": "startup", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:48:29.531525+00:00 decky-webmail pop3 - startup - POP3 server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 19:48:29", "decky": "decky-webmail", "service": "http", "event_type": "startup", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:48:29.562070+00:00 decky-webmail http - startup - HTTP server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:05", "decky": "decky-webmail", "service": "pop3", "event_type": "connect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:05.202133+00:00 decky-webmail pop3 - connect [decnet@55555 src=\"192.168.1.5\" src_port=\"56394\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:05", "decky": "decky-webmail", "service": "smtp", "event_type": "connect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:05.202095+00:00 decky-webmail smtp - connect [decnet@55555 src=\"192.168.1.5\" src_port=\"44836\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:05", "decky": "decky-webmail", "service": "imap", "event_type": "connect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:05.202120+00:00 decky-webmail imap - connect [decnet@55555 src=\"192.168.1.5\" src_port=\"49892\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:05", "decky": "decky-webmail", "service": "smtp", "event_type": "disconnect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:05.204537+00:00 decky-webmail smtp - disconnect [decnet@55555 src=\"192.168.1.5\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:11", "decky": "decky-webmail", "service": "imap", "event_type": "command", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:11.208384+00:00 decky-webmail imap - command [decnet@55555 src=\"192.168.1.5\" cmd=\"GET / HTTP/1.0\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:11", "decky": "decky-webmail", "service": "pop3", "event_type": "command", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:11.208384+00:00 decky-webmail pop3 - command [decnet@55555 src=\"192.168.1.5\" cmd=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:11", "decky": "decky-webmail", "service": "pop3", "event_type": "command", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:11.208646+00:00 decky-webmail pop3 - command [decnet@55555 src=\"192.168.1.5\" cmd=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:11", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:11.208787+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/\" remote_addr=\"192.168.1.5\" headers=\"{}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:16", "decky": "decky-webmail", "service": "pop3", "event_type": "disconnect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:16.213731+00:00 decky-webmail pop3 - disconnect [decnet@55555 src=\"192.168.1.5\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:16", "decky": "decky-webmail", "service": "imap", "event_type": "disconnect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:16.213827+00:00 decky-webmail imap - disconnect [decnet@55555 src=\"192.168.1.5\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:16", "decky": "decky-webmail", "service": "pop3", "event_type": "connect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:16.214094+00:00 decky-webmail pop3 - connect [decnet@55555 src=\"192.168.1.5\" src_port=\"51296\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:16", "decky": "decky-webmail", "service": "imap", "event_type": "connect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:16.214133+00:00 decky-webmail imap - connect [decnet@55555 src=\"192.168.1.5\" src_port=\"50426\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:16", "decky": "decky-webmail", "service": "pop3", "event_type": "command", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:16.214228+00:00 decky-webmail pop3 - command [decnet@55555 src=\"192.168.1.5\" cmd=\"OPTIONS / HTTP/1.0\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:16", "decky": "decky-webmail", "service": "pop3", "event_type": "command", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:16.214301+00:00 decky-webmail pop3 - command [decnet@55555 src=\"192.168.1.5\" cmd=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "imap", "event_type": "disconnect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:21.219340+00:00 decky-webmail imap - disconnect [decnet@55555 src=\"192.168.1.5\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "pop3", "event_type": "disconnect", "attacker_ip": "192.168.1.5", "raw_line": "<134>1 2026-04-07T19:53:21.219334+00:00 decky-webmail pop3 - disconnect [decnet@55555 src=\"192.168.1.5\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.222956+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/\" remote_addr=\"192.168.1.5\" headers=\"{}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.223266+00:00 decky-webmail http - request [decnet@55555 method=\"POST\" path=\"/sdk\" remote_addr=\"192.168.1.5\" headers=\"{'Host': '192.168.1.110', 'Connection': 'close', 'Content-Length': '441', 'User-Agent': 'Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)'}\" body=\"<soap:Envelope xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\"><soap:Header><operationID>00000001-00000001</operationID></soap:Header><soap:Body><RetrieveServiceContent xmlns=\\\"urn:internalvim25\\\"><_this xsi:type=\\\"ManagedObjectReference\\\" type=\\\"ServiceInstance\\\">ServiceInstance</_this></RetrieveServiceContent></soap:Body></soap:Envelope>\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.223437+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/nmaplowercheck1775591601\" remote_addr=\"192.168.1.5\" headers=\"{'Host': '192.168.1.110', 'Connection': 'close', 'User-Agent': 'Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)'}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.224651+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/NmapUpperCheck1775591601\" remote_addr=\"192.168.1.5\" headers=\"{'Host': '192.168.1.110', 'Connection': 'close', 'User-Agent': 'Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)'}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.225177+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/Nmap/folder/check1775591601\" remote_addr=\"192.168.1.5\" headers=\"{'Host': '192.168.1.110', 'Connection': 'close', 'User-Agent': 'Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)'}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.225909+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/\" remote_addr=\"192.168.1.5\" headers=\"{}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 19:53:21", "decky": "decky-webmail", "service": "http", "event_type": "request", "attacker_ip": "Unknown", "raw_line": "<134>1 2026-04-07T19:53:21.226287+00:00 decky-webmail http - request [decnet@55555 method=\"GET\" path=\"/\" remote_addr=\"192.168.1.5\" headers=\"{'Host': '192.168.1.110'}\" body=\"\"]"}
|
||||||
|
{"timestamp": "2026-04-07 20:24:03", "decky": "decky-webmail", "service": "smtp", "event_type": "startup", "attacker_ip": "Unknown", "fields": "{}", "msg": "SMTP server starting as decky-webmail", "raw_line": "<134>1 2026-04-07T20:24:03.279897+00:00 decky-webmail smtp - startup - SMTP server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 20:24:03", "decky": "decky-webmail", "service": "imap", "event_type": "startup", "attacker_ip": "Unknown", "fields": "{}", "msg": "IMAP server starting as decky-webmail", "raw_line": "<134>1 2026-04-07T20:24:03.279954+00:00 decky-webmail imap - startup - IMAP server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 20:24:03", "decky": "decky-webmail", "service": "pop3", "event_type": "startup", "attacker_ip": "Unknown", "fields": "{}", "msg": "POP3 server starting as decky-webmail", "raw_line": "<134>1 2026-04-07T20:24:03.283256+00:00 decky-webmail pop3 - startup - POP3 server starting as decky-webmail"}
|
||||||
|
{"timestamp": "2026-04-07 20:24:03", "decky": "decky-webmail", "service": "http", "event_type": "startup", "attacker_ip": "Unknown", "fields": "{}", "msg": "HTTP server starting as decky-webmail", "raw_line": "<134>1 2026-04-07T20:24:03.297543+00:00 decky-webmail http - startup - HTTP server starting as decky-webmail"}
|
||||||
66
decnet.log
66
decnet.log
@@ -157,3 +157,69 @@
|
|||||||
<134>1 2026-04-04T07:41:33.751197+00:00 decky-webmail pop3 - command [decnet@55555 src="192.168.1.5" cmd=" | |||||||