24e0d98425
feat: add service filter to attacker profiles
...
API now accepts ?service=https to filter attackers by targeted service.
Service badges are clickable in both the attacker list and detail views,
navigating to a filtered view. Active filter shows as a dismissable tag.
2026-04-14 01:35:12 -04:00
ea340065c6
feat: JA4/JA4S/JA4L fingerprints, TLS session resumption, certificate extraction
...
Extend the passive TLS sniffer with next-gen attacker fingerprinting:
- JA4 (ClientHello) and JA4S (ServerHello) computation with
supported_versions, signature_algorithms, and ALPN parsing
- JA4L latency measurement via TCP SYN→SYN-ACK RTT tracking
- TLS session resumption detection (session tickets, PSK, 0-RTT early data)
- Certificate extraction for TLS ≤1.2 with minimal DER/ASN.1 parser
(subject CN, issuer, SANs, validity period, self-signed flag)
- Ingester bounty extraction for all new fingerprint types
- 116 tests covering all new functionality (1255 total passing)
2026-04-13 23:20:37 -04:00
a022b4fed6
feat: attacker profiles — UUID model, API routes, list/detail frontend
...
Migrate Attacker model from IP-based to UUID-based primary key with
auto-migration for old schema. Add GET /attackers (paginated, search,
sort) and GET /attackers/{uuid} API routes. Rewrite Attackers.tsx as
a card grid with full threat info and create AttackerDetail.tsx as a
dedicated detail page with back navigation, stats, commands table,
and fingerprints.
2026-04-13 22:35:13 -04:00
3dc5b509f6
feat: Phase 1 — JA3/JA3S sniffer, Attacker model, profile worker
...
Add passive TLS fingerprinting via a sniffer container on the MACVLAN
interface, plus the Attacker table and periodic rebuild worker that
correlates per-IP profiles from Log + Bounty + CorrelationEngine.
- templates/sniffer/: Scapy sniffer with pure-Python TLS parser;
emits tls_client_hello / tls_session RFC 5424 lines with ja3, ja3s,
sni, alpn, raw_ciphers, raw_extensions; GREASE filtered per RFC 8701
- decnet/services/sniffer.py: service plugin (no ports, NET_RAW/NET_ADMIN)
- decnet/web/db/models.py: Attacker SQLModel table + AttackersResponse
- decnet/web/db/repository.py: 5 new abstract methods
- decnet/web/db/sqlite/repository.py: implement all 5 (upsert, pagination,
sort by recent/active/traversals, bounty grouping)
- decnet/web/attacker_worker.py: 30s periodic rebuild via CorrelationEngine;
extracts commands from log fields, merges fingerprint bounties
- decnet/web/api.py: wire attacker_profile_worker into lifespan
- decnet/web/ingester.py: extract JA3 bounty (fingerprint_type=ja3)
- development/DEVELOPMENT.md: full attacker intelligence collection roadmap
- pyproject.toml: scapy>=2.6.1 added to dev deps
- tests: test_sniffer_ja3.py (40+ vectors), test_attacker_worker.py,
test_base_repo.py / test_web_api.py updated for new surface
2026-04-13 20:22:08 -04:00
c9be447a38
fix: set busy_timeout and WAL pragmas on every async SQLite connection
2026-04-13 19:17:53 -04:00
57d395d6d7
fix: auth redirect, SSE reconnect, stats polling removal, active decky count, schemathesis health check
CI / Lint (ruff) (push) Successful in 18s
CI / SAST (bandit) (push) Successful in 19s
CI / Dependency audit (pip-audit) (push) Failing after 27s
CI / Test (Standard) (3.11) (push) Has been skipped
CI / Test (Standard) (3.12) (push) Has been skipped
CI / Test (Live) (3.11) (push) Has been skipped
CI / Test (Fuzz) (3.11) (push) Has been skipped
CI / Merge dev → testing (push) Has been skipped
CI / Prepare Merge to Main (push) Has been skipped
CI / Finalize Merge to Main (push) Has been skipped
2026-04-13 18:33:32 -04:00
435c004760
feat: extract HTTP User-Agent and VNC client version as fingerprint bounties
CI / Lint (ruff) (push) Successful in 11s
CI / SAST (bandit) (push) Successful in 14s
CI / Dependency audit (pip-audit) (push) Successful in 24s
CI / Test (Standard) (3.11) (push) Successful in 2m2s
CI / Test (Standard) (3.12) (push) Successful in 2m5s
CI / Test (Live) (3.11) (push) Successful in 56s
CI / Test (Fuzz) (3.11) (push) Failing after 6m25s
CI / Merge dev → testing (push) Has been skipped
CI / Prepare Merge to Main (push) Has been skipped
CI / Finalize Merge to Main (push) Has been skipped
2026-04-13 08:14:38 -04:00
3d01ca2c2a
fix: resolve ruff lint errors (unused import, E402 import order)
CI / Lint (ruff) (push) Successful in 12s
CI / SAST (bandit) (push) Successful in 14s
CI / Dependency audit (pip-audit) (push) Successful in 27s
CI / Test (Standard) (3.11) (push) Successful in 2m7s
CI / Test (Standard) (3.12) (push) Successful in 2m8s
CI / Test (Live) (3.11) (push) Successful in 58s
CI / Merge dev → testing (push) Has been cancelled
CI / Prepare Merge to Main (push) Has been cancelled
CI / Finalize Merge to Main (push) Has been cancelled
CI / Test (Fuzz) (3.11) (push) Has been cancelled
2026-04-13 07:58:13 -04:00
035499f255
feat: add component-aware RFC 5424 application logging system
...
- Modify Rfc5424Formatter to read decnet_component from LogRecord
and use it as RFC 5424 APP-NAME field (falls back to 'decnet')
- Add get_logger(component) factory in decnet/logging/__init__.py
with _ComponentFilter that injects decnet_component on each record
- Wire all five layers to their component tag:
cli -> 'cli', engine -> 'engine', api -> 'api' (api.py, ingester,
routers), mutator -> 'mutator', collector -> 'collector'
- Add structured INFO/DEBUG/WARNING/ERROR log calls throughout each
layer per the defined vocabulary; DEBUG calls are suppressed unless
DECNET_DEVELOPER=true
- Add tests/test_logging.py covering factory, filter, formatter
component-awareness, fallback behaviour, and level gating
2026-04-13 07:39:01 -04:00
f2cc585d72
fix: align tests with model validation and API error reporting
2026-04-13 01:43:52 -04:00
03f5a7826f
Fix: resolved sqlite concurrency errors (table users already exists) by moving DDL to explicit async initialize() and implementing lazy singleton dependency.
2026-04-12 08:01:21 -04:00
b2e4706a14
Refactor: implemented Repository Factory and Async Mutator Engine. Decoupled storage logic and enforced Dependency Injection across CLI and Web API. Updated documentation.
CI / Lint (ruff) (push) Successful in 12s
CI / SAST (bandit) (push) Successful in 13s
CI / Dependency audit (pip-audit) (push) Successful in 22s
CI / Test (Standard) (3.11) (push) Failing after 54s
CI / Test (Standard) (3.12) (push) Successful in 1m35s
CI / Test (Live) (3.11) (push) Has been skipped
CI / Test (Fuzz) (3.11) (push) Has been skipped
CI / Merge dev → testing (push) Has been skipped
CI / Prepare Merge to Main (push) Has been skipped
CI / Finalize Merge to Main (push) Has been skipped
2026-04-12 07:48:17 -04:00
f78104e1c8
fix: resolve all ruff lint errors and SQLite UNIQUE constraint issue
...
Ruff fixes (20 errors → 0):
- F401: Remove unused imports (DeckyConfig, random_hostname, IniConfig,
COMPOSE_FILE, sys, patch) across cli.py, mutator/engine.py,
templates/ftp, templates/rdp, test_mysql.py, test_postgres.py
- F541: Remove extraneous f-prefixes on strings with no placeholders
in templates/imap, test_ftp_live, test_http_live
- E741: Rename ambiguous variable 'l' to descriptive names (line, entry,
part) across conftest.py, test_ftp_live, test_http_live,
test_mongodb_live, test_pop3, test_ssh
SQLite fix:
- Change _initialize_sync() admin seeding from SELECT-then-INSERT to
INSERT OR IGNORE, preventing IntegrityError when admin user already
exists from a previous run
2026-04-12 02:17:50 -04:00
c384a3103a
refactor: separate engine, collector, mutator, and fleet into independent subpackages
...
- decnet/engine/ — container lifecycle (deploy, teardown, status); _kill_api removed
- decnet/collector/ — Docker log streaming (moved from web/collector.py)
- decnet/mutator/ — mutation engine (no longer imports from cli or duplicates deployer code)
- decnet/fleet.py — shared decky-building logic extracted from cli.py
Cross-contamination eliminated:
- web router no longer imports from decnet.cli
- mutator no longer imports from decnet.cli
- cli no longer imports from decnet.web
- _kill_api() moved to cli (process management, not engine concern)
- _compose_with_retry duplicate removed from mutator
2026-04-12 00:26:22 -04:00
babad5ce65
refactor(collector): use state file for container detection, drop label heuristics
...
_load_service_container_names() reads decnet-state.json and builds the
exact set of expected container names ({decky}-{service}). is_service_container()
and is_service_event() do a direct set lookup — no regex, no label
inspection, no heuristics.
2026-04-11 03:58:52 -04:00
7abae5571a
fix(collector): fix container detection and auto-start on deploy
...
Two bugs caused the log file to never be written:
1. is_service_container() used regex '^decky-\d+-\w' which only matched
the old decky-01-smtp naming style. Actual containers are named
omega-decky-smtp, relay-decky-smtp, etc. Fixed by using Docker Compose
labels instead: com.docker.compose.project=decnet + non-empty
depends_on discriminates service containers from base (sleep infinity)
containers reliably regardless of decky naming convention.
Added is_service_event() for the Docker events path.
2. The collector was only started when --api was used. Added a 'collect'
CLI subcommand (decnet collect --log-file <path>) and wired it into
deploy as an auto-started background process when --api is not in use.
Default log path: /var/log/decnet/decnet.log
2026-04-11 03:56:53 -04:00
08242a4d84
Implement ICS/SCADA and IMAP Bait features
2026-04-10 01:50:08 -04:00
25ba3fb56a
feat: replace bind-mount log pipeline with Docker log streaming
...
Services now print RFC 5424 to stdout; Docker captures via json-file driver.
A new host-side collector (decnet.web.collector) streams docker logs from all
running decky service containers and writes RFC 5424 + parsed JSON to the host
log file. The existing ingester continues to tail the .json file unchanged.
rsyslog can consume the .log file independently — no DECNET involvement needed.
Removes: bind-mount volume injection, _LOG_NETWORK bridge, log_target config
field and --log-target CLI flag, TCP syslog forwarding from service templates.
2026-04-10 00:14:14 -04:00
14f7a535db
fix: use model_dump(mode='json') to serialize datetime fields; fixes SSE stream silently dying post-ORM migration
2026-04-09 19:29:27 -04:00
cea6279a08
fix: add Last-Event-ID to CORS allow_headers to unblock SSE reconnects
2026-04-09 19:26:24 -04:00
6b8392102e
fix: emit stats/histogram snapshot on SSE connect; remove polling api.get('/stats') from Dashboard
2026-04-09 19:23:24 -04:00
d2a569496d
fix: add get_stream_user dependency for SSE endpoint; allow query-string token for EventSource
2026-04-09 19:20:38 -04:00
016115a523
fix: clear all addressable technical debt (DEBT-005 through DEBT-025)
...
Security:
- DEBT-008: remove query-string token auth; header-only Bearer now enforced
- DEBT-013: add regex constraint ^[a-z0-9\-]{1,64}$ on decky_name path param
- DEBT-015: stop leaking raw exception detail to API clients; log server-side
- DEBT-016: validate search (max_length=512) and datetime params with regex
Reliability:
- DEBT-014: wrap SSE event_generator in try/except; yield error frame on failure
- DEBT-017: emit log.warning/error on DB init retry; silent failures now visible
Observability / Docs:
- DEBT-020: add 401/422 response declarations to all route decorators
Infrastructure:
- DEBT-018: add HEALTHCHECK to all 24 template Dockerfiles
- DEBT-019: add USER decnet + setcap cap_net_bind_service to all 24 Dockerfiles
- DEBT-024: bump Redis template version 7.0.12 → 7.2.7
Config:
- DEBT-012: validate DECNET_API_PORT and DECNET_WEB_PORT range (1-65535)
Code quality:
- DEBT-010: delete 22 duplicate decnet_logging.py copies; deployer injects canonical
- DEBT-022: closed as false positive (print only in module docstring)
- DEBT-009: closed as false positive (templates already use structured syslog_line)
Build:
- DEBT-025: generate requirements.lock via pip freeze
Testing:
- DEBT-005/006/007: comprehensive test suite added across tests/api/
- conftest: in-memory SQLite + StaticPool + monkeypatched session_factory
- fuzz mark added; default run excludes fuzz; -n logical parallelism
DEBT.md updated: 23/25 items closed; DEBT-011 (Alembic) and DEBT-023 (digest pinning) remain
2026-04-09 19:02:51 -04:00
0166d0d559
fix: clean up db layer — model_dump, timezone-aware timestamps, unified histogram, async load_state
2026-04-09 18:46:35 -04:00
de84cc664f
refactor: migrate database to SQLModel and implement modular DB structure
2026-04-09 16:43:30 -04:00
b6b046c90b
fix: harden startup security — require strong secrets, restrict CORS
...
- decnet/env.py: DECNET_JWT_SECRET and DECNET_ADMIN_PASSWORD are now
required env vars; startup raises ValueError if unset or set to a
known-bad default ("admin", "password", etc.)
- decnet/env.py: add DECNET_CORS_ORIGINS (comma-separated, defaults to
http://localhost:8080 ) replacing the previous allow_origins=["*"]
- decnet/web/api.py: use DECNET_CORS_ORIGINS and tighten allow_methods
and allow_headers to explicit lists
- tests/conftest.py: set required env vars at module level so test
collection works without real credentials
- tests/test_web_api.py, test_web_api_fuzz.py: use DECNET_ADMIN_PASSWORD
from env instead of hardcoded "admin"
Closes DEBT-001, DEBT-002, DEBT-004
2026-04-09 12:13:22 -04:00
29a2cf2738
refactor: modularize API routes into separate files and clean up dependencies
2026-04-09 11:58:57 -04:00
551664bc43
fix: stabilize test suite by ensuring proper test DB isolation and initialization
2026-04-09 02:31:14 -04:00
a3b92d4dd6
docs: tag API endpoints for better organization
2026-04-09 01:58:54 -04:00
30edf9a55d
feat: add DECNET_DEVELOPER toggle for API documentation
2026-04-09 01:55:31 -04:00
69626d705d
feat: implement Bounty Vault for captured credentials and artifacts
2026-04-09 01:52:50 -04:00
0f86f883fe
fix: resolve remaining bandit warnings and stabilize lifespan
2026-04-09 01:35:08 -04:00
13f3d15a36
fix: stabilize tests with synchronous DB init and handle Bandit security findings
2026-04-09 01:33:15 -04:00
8c7ec2953e
fix: handle bcrypt 72-byte limit and increase JWT secret length
2026-04-09 01:11:32 -04:00
6c2478ede3
fix: restore missing API endpoints, fix chart rendering, and update date filter formatting
2026-04-08 21:25:59 -04:00
532a4e2dc5
fix: resolve SSE CORS issues and fix date filter format mismatch
2026-04-08 21:15:26 -04:00
ec503b9ec6
feat: implement advanced live logs with KQL search, histogram, and live/historical modes
2026-04-08 21:01:05 -04:00
32b06afef6
feat: add .env based configuration for API, Web, and Auth options
2026-04-08 01:27:11 -04:00
31e0c5151b
fix: ensure API-deployed deckies inherit the correct log ingestion path
2026-04-08 01:09:48 -04:00
cc3d434c02
feat: add server-side validation for web-based INI deployments
2026-04-08 01:04:59 -04:00
168ecf14ab
feat: add API-only mode and web-based INI deployment
2026-04-08 00:56:25 -04:00
c544964f57
feat: migrate dashboard live logs to Server-Sent Events (SSE)
2026-04-08 00:30:31 -04:00
18de381a43
feat: implement dynamic decky mutation and fix dot-separated INI sections
2026-04-08 00:16:57 -04:00
a9c7ddec2b
fix: enforce absolute paths for state and database files
2026-04-07 23:21:16 -04:00
eb4be44c9a
feat: add dedicated Decoy Fleet inventory page and API
2026-04-07 23:15:20 -04:00
ba2faba5d5
chore: enforce strict typing and internal naming conventions across web components
2026-04-07 19:56:15 -04:00
7bc8d75242
feat: parse RFC 5424 fields and msg directly in backend
2026-04-07 15:56:01 -04:00
5f637b5272
feat: switch to JSON-based log ingestion for higher reliability
2026-04-07 15:47:29 -04:00
bad90dfb75
feat: implement background log ingestion from local file
2026-04-07 15:30:44 -04:00
52c26a2891
feat: backend support for mandatory password change on first login
2026-04-07 15:15:03 -04:00