chore: fix unused imports in tests and update development roadmap
Some checks failed
CI / Lint (ruff) (push) Successful in 16s
CI / Test (pytest) (3.11) (push) Failing after 34s
CI / Test (pytest) (3.12) (push) Failing after 36s
CI / SAST (bandit) (push) Successful in 12s
CI / Merge dev → testing (push) Has been cancelled
CI / Open PR to main (push) Has been cancelled
CI / Dependency audit (pip-audit) (push) Has been cancelled

This commit is contained in:
2026-04-12 03:46:23 -04:00
parent fdc404760f
commit 0f63820ee6
18 changed files with 10 additions and 1038 deletions

View File

@@ -1,40 +0,0 @@
# arche-test.ini
# OS fingerprint smoke-test fleet.
#
# One group per OS family, each spinning up 2 deckies.
# Deploy with:
# sudo .venv/bin/decnet deploy --config arche-test.ini --dry-run
# sudo .venv/bin/decnet deploy --config arche-test.ini --interface eth0
#
# After deploy, verify with:
# sudo nmap -O --osscan-guess <ip>
# sudo p0f -i <iface> -p
# ---- Linux (TTL 64, timestamps on, ECN offer) ----
[os-linux]
nmap_os=linux
services=ssh,http
amount=2
# ---- Windows (TTL 128, timestamps off, no ECN) ----
[os-windows]
nmap_os=windows
services=smb,rdp
amount=2
# ---- BSD (TTL 64, timestamps on, no ECN) ----
[os-bsd]
nmap_os=bsd
services=ssh,http
amount=2
# ---- Embedded (TTL 255, timestamps off, no SACK, no window scaling) ----
[os-embedded]
nmap_os=embedded
services=snmp
amount=2
# ---- Cisco (TTL 255, timestamps off, no SACK, ip_no_pmtu_disc on) ----
[os-cisco]
nmap_os=cisco
services=snmp
amount=2

View File

@@ -1,419 +0,0 @@
# DECNET Codebase AST Graph
This diagram shows the structural organization of the DECNET project, extracted directly from the Python Abstract Syntax Tree (AST). It includes modules (prefixed with `Module_`), their internal functions, and the classes and methods they contain.
```mermaid
classDiagram
class Module_distros {
+random_hostname()
+get_distro()
+random_distro()
+all_distros()
}
class distros_DistroProfile {
}
Module_distros ..> distros_DistroProfile : contains
class custom_service_CustomService {
+__init__()
+compose_fragment()
+dockerfile_context()
}
Module_custom_service ..> custom_service_CustomService : contains
class Module_os_fingerprint {
+get_os_sysctls()
+all_os_families()
}
class Module_network {
+_run()
+detect_interface()
+detect_subnet()
+get_host_ip()
+allocate_ips()
+create_macvlan_network()
+create_ipvlan_network()
+remove_macvlan_network()
+_require_root()
+setup_host_macvlan()
+teardown_host_macvlan()
+setup_host_ipvlan()
+teardown_host_ipvlan()
+ips_to_range()
}
class Module_env {
+_port()
+_require_env()
}
class Module_config {
+random_hostname()
+save_state()
+load_state()
+clear_state()
}
class config_DeckyConfig {
+services_not_empty()
}
Module_config ..> config_DeckyConfig : contains
class config_DecnetConfig {
}
Module_config ..> config_DecnetConfig : contains
class Module_ini_loader {
+load_ini()
+load_ini_from_string()
+validate_ini_string()
+_parse_configparser()
}
class ini_loader_DeckySpec {
}
Module_ini_loader ..> ini_loader_DeckySpec : contains
class ini_loader_CustomServiceSpec {
}
Module_ini_loader ..> ini_loader_CustomServiceSpec : contains
class ini_loader_IniConfig {
}
Module_ini_loader ..> ini_loader_IniConfig : contains
class Module_composer {
+generate_compose()
+write_compose()
}
class Module_archetypes {
+get_archetype()
+all_archetypes()
+random_archetype()
}
class archetypes_Archetype {
}
Module_archetypes ..> archetypes_Archetype : contains
class Module_fleet {
+all_service_names()
+resolve_distros()
+build_deckies()
+build_deckies_from_ini()
}
class Module_cli {
+_kill_api()
+api()
+deploy()
+collect()
+mutate()
+status()
+teardown()
+list_services()
+list_distros()
+correlate()
+list_archetypes()
+serve_web()
}
class services_base_BaseService {
+compose_fragment()
+dockerfile_context()
}
Module_services_base ..> services_base_BaseService : contains
class services_http_HTTPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_http ..> services_http_HTTPService : contains
class services_smtp_SMTPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_smtp ..> services_smtp_SMTPService : contains
class services_mysql_MySQLService {
+compose_fragment()
+dockerfile_context()
}
Module_services_mysql ..> services_mysql_MySQLService : contains
class services_redis_RedisService {
+compose_fragment()
+dockerfile_context()
}
Module_services_redis ..> services_redis_RedisService : contains
class services_elasticsearch_ElasticsearchService {
+compose_fragment()
+dockerfile_context()
}
Module_services_elasticsearch ..> services_elasticsearch_ElasticsearchService : contains
class services_ftp_FTPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_ftp ..> services_ftp_FTPService : contains
class services_imap_IMAPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_imap ..> services_imap_IMAPService : contains
class services_k8s_KubernetesAPIService {
+compose_fragment()
+dockerfile_context()
}
Module_services_k8s ..> services_k8s_KubernetesAPIService : contains
class services_ldap_LDAPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_ldap ..> services_ldap_LDAPService : contains
class services_llmnr_LLMNRService {
+compose_fragment()
+dockerfile_context()
}
Module_services_llmnr ..> services_llmnr_LLMNRService : contains
class services_mongodb_MongoDBService {
+compose_fragment()
+dockerfile_context()
}
Module_services_mongodb ..> services_mongodb_MongoDBService : contains
class services_mqtt_MQTTService {
+compose_fragment()
+dockerfile_context()
}
Module_services_mqtt ..> services_mqtt_MQTTService : contains
class services_mssql_MSSQLService {
+compose_fragment()
+dockerfile_context()
}
Module_services_mssql ..> services_mssql_MSSQLService : contains
class services_pop3_POP3Service {
+compose_fragment()
+dockerfile_context()
}
Module_services_pop3 ..> services_pop3_POP3Service : contains
class services_postgres_PostgresService {
+compose_fragment()
+dockerfile_context()
}
Module_services_postgres ..> services_postgres_PostgresService : contains
class services_rdp_RDPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_rdp ..> services_rdp_RDPService : contains
class services_sip_SIPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_sip ..> services_sip_SIPService : contains
class services_smb_SMBService {
+compose_fragment()
+dockerfile_context()
}
Module_services_smb ..> services_smb_SMBService : contains
class services_snmp_SNMPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_snmp ..> services_snmp_SNMPService : contains
class services_tftp_TFTPService {
+compose_fragment()
+dockerfile_context()
}
Module_services_tftp ..> services_tftp_TFTPService : contains
class services_vnc_VNCService {
+compose_fragment()
+dockerfile_context()
}
Module_services_vnc ..> services_vnc_VNCService : contains
class services_docker_api_DockerAPIService {
+compose_fragment()
+dockerfile_context()
}
Module_services_docker_api ..> services_docker_api_DockerAPIService : contains
class Module_services_registry {
+_load_plugins()
+register_custom_service()
+get_service()
+all_services()
}
class services_smtp_relay_SMTPRelayService {
+compose_fragment()
+dockerfile_context()
}
Module_services_smtp_relay ..> services_smtp_relay_SMTPRelayService : contains
class services_conpot_ConpotService {
+compose_fragment()
+dockerfile_context()
}
Module_services_conpot ..> services_conpot_ConpotService : contains
class services_ssh_SSHService {
+compose_fragment()
+dockerfile_context()
}
Module_services_ssh ..> services_ssh_SSHService : contains
class services_telnet_TelnetService {
+compose_fragment()
+dockerfile_context()
}
Module_services_telnet ..> services_telnet_TelnetService : contains
class Module_logging_forwarder {
+parse_log_target()
+probe_log_target()
}
class Module_logging_file_handler {
+_get_logger()
+write_syslog()
+get_log_path()
}
class Module_logging_syslog_formatter {
+_pri()
+_truncate()
+_sd_escape()
+_sd_element()
+format_rfc5424()
}
class correlation_graph_TraversalHop {
}
Module_correlation_graph ..> correlation_graph_TraversalHop : contains
class correlation_graph_AttackerTraversal {
+first_seen()
+last_seen()
+duration_seconds()
+deckies()
+decky_count()
+path()
+to_dict()
}
Module_correlation_graph ..> correlation_graph_AttackerTraversal : contains
class Module_correlation_engine {
+_fmt_duration()
}
class correlation_engine_CorrelationEngine {
+__init__()
+ingest()
+ingest_file()
+traversals()
+all_attackers()
+report_table()
+report_json()
+traversal_syslog_lines()
}
Module_correlation_engine ..> correlation_engine_CorrelationEngine : contains
class Module_correlation_parser {
+_parse_sd_params()
+_extract_attacker_ip()
+parse_line()
}
class correlation_parser_LogEvent {
}
Module_correlation_parser ..> correlation_parser_LogEvent : contains
class Module_web_auth {
+verify_password()
+get_password_hash()
+create_access_token()
}
class Module_engine_deployer {
+_sync_logging_helper()
+_compose()
+_compose_with_retry()
+deploy()
+teardown()
+status()
+_print_status()
}
class Module_collector_worker {
+parse_rfc5424()
+_load_service_container_names()
+is_service_container()
+is_service_event()
+_stream_container()
}
class Module_mutator_engine {
+mutate_decky()
+mutate_all()
+run_watch_loop()
}
class web_db_repository_BaseRepository {
}
Module_web_db_repository ..> web_db_repository_BaseRepository : contains
class web_db_models_User {
}
Module_web_db_models ..> web_db_models_User : contains
class web_db_models_Log {
}
Module_web_db_models ..> web_db_models_Log : contains
class web_db_models_Bounty {
}
Module_web_db_models ..> web_db_models_Bounty : contains
class web_db_models_Token {
}
Module_web_db_models ..> web_db_models_Token : contains
class web_db_models_LoginRequest {
}
Module_web_db_models ..> web_db_models_LoginRequest : contains
class web_db_models_ChangePasswordRequest {
}
Module_web_db_models ..> web_db_models_ChangePasswordRequest : contains
class web_db_models_LogsResponse {
}
Module_web_db_models ..> web_db_models_LogsResponse : contains
class web_db_models_BountyResponse {
}
Module_web_db_models ..> web_db_models_BountyResponse : contains
class web_db_models_StatsResponse {
}
Module_web_db_models ..> web_db_models_StatsResponse : contains
class web_db_models_MutateIntervalRequest {
}
Module_web_db_models ..> web_db_models_MutateIntervalRequest : contains
class web_db_models_DeployIniRequest {
}
Module_web_db_models ..> web_db_models_DeployIniRequest : contains
class Module_web_db_sqlite_database {
+get_async_engine()
+get_sync_engine()
+init_db()
}
class web_db_sqlite_repository_SQLiteRepository {
+__init__()
+_initialize_sync()
+_apply_filters()
+_apply_bounty_filters()
}
Module_web_db_sqlite_repository ..> web_db_sqlite_repository_SQLiteRepository : contains
```

View File

@@ -1,192 +0,0 @@
# DECNET: Complete Execution Graph
This diagram represents the absolute complete call graph of the DECNET project. It connects initial entry points (CLI and Web API) through the orchestration layers, down to the low-level network and service container logic.
```mermaid
graph TD
subgraph CLI_Entry
cli__kill_api([_kill_api])
cli_api([api])
cli_deploy([deploy])
cli_collect([collect])
cli_mutate([mutate])
cli_status([status])
cli_teardown([teardown])
cli_list_services([list_services])
cli_list_distros([list_distros])
cli_correlate([correlate])
cli_list_archetypes([list_archetypes])
cli_serve_web([serve_web])
cli_do_GET([do_GET])
end
subgraph Fleet_Management
distros_random_hostname([distros_random_hostname])
distros_get_distro([distros_get_distro])
distros_random_distro([distros_random_distro])
distros_all_distros([distros_all_distros])
ini_loader_load_ini([ini_loader_load_ini])
ini_loader_load_ini_from_string([ini_loader_load_ini_from_string])
ini_loader_validate_ini_string([ini_loader_validate_ini_string])
ini_loader__parse_configparser([ini_loader__parse_configparser])
archetypes_get_archetype([archetypes_get_archetype])
archetypes_all_archetypes([archetypes_all_archetypes])
archetypes_random_archetype([archetypes_random_archetype])
fleet_all_service_names([all_service_names])
fleet_resolve_distros([resolve_distros])
fleet_build_deckies([build_deckies])
fleet_build_deckies_from_ini([build_deckies_from_ini])
end
subgraph Deployment_Engine
network__run([network__run])
network_detect_interface([network_detect_interface])
network_detect_subnet([network_detect_subnet])
network_get_host_ip([network_get_host_ip])
network_allocate_ips([network_allocate_ips])
network_create_macvlan_network([network_create_macvlan_network])
network_create_ipvlan_network([network_create_ipvlan_network])
network_remove_macvlan_network([network_remove_macvlan_network])
network__require_root([network__require_root])
network_setup_host_macvlan([network_setup_host_macvlan])
network_teardown_host_macvlan([network_teardown_host_macvlan])
network_setup_host_ipvlan([network_setup_host_ipvlan])
network_teardown_host_ipvlan([network_teardown_host_ipvlan])
network_ips_to_range([network_ips_to_range])
config_random_hostname([config_random_hostname])
config_save_state([config_save_state])
config_load_state([config_load_state])
config_clear_state([config_clear_state])
composer_generate_compose([composer_generate_compose])
composer_write_compose([composer_write_compose])
engine_deployer__sync_logging_helper([_sync_logging_helper])
engine_deployer__compose([_compose])
engine_deployer__compose_with_retry([_compose_with_retry])
engine_deployer_deploy([deploy])
engine_deployer_teardown([teardown])
engine_deployer_status([status])
engine_deployer__print_status([_print_status])
end
subgraph Monitoring_Mutation
collector_worker_parse_rfc5424([parse_rfc5424])
collector_worker__load_service_container_names([_load_service_container_names])
collector_worker_is_service_container([is_service_container])
collector_worker_is_service_event([is_service_event])
collector_worker__stream_container([_stream_container])
collector_worker_log_collector_worker([log_collector_worker])
collector_worker__spawn([_spawn])
collector_worker__watch_events([_watch_events])
mutator_engine_mutate_decky([mutate_decky])
mutator_engine_mutate_all([mutate_all])
mutator_engine_run_watch_loop([run_watch_loop])
end
subgraph Web_Service
web_auth_verify_password([web_auth_verify_password])
web_auth_get_password_hash([web_auth_get_password_hash])
web_auth_create_access_token([web_auth_create_access_token])
web_db_repository_initialize([web_db_repository_initialize])
web_db_repository_add_log([web_db_repository_add_log])
web_db_repository_get_logs([web_db_repository_get_logs])
web_db_repository_get_total_logs([web_db_repository_get_total_logs])
web_db_repository_get_stats_summary([web_db_repository_get_stats_summary])
web_db_repository_get_deckies([web_db_repository_get_deckies])
web_db_repository_get_user_by_uuid([web_db_repository_get_user_by_uuid])
web_db_repository_update_user_password([web_db_repository_update_user_password])
web_db_repository_add_bounty([web_db_repository_add_bounty])
web_db_repository_get_bounties([web_db_repository_get_bounties])
web_db_repository_get_total_bounties([web_db_repository_get_total_bounties])
web_db_sqlite_database_get_async_engine([web_db_sqlite_database_get_async_engine])
web_db_sqlite_database_get_sync_engine([web_db_sqlite_database_get_sync_engine])
web_db_sqlite_database_init_db([web_db_sqlite_database_init_db])
web_db_sqlite_repository_initialize([web_db_sqlite_repository_initialize])
web_db_sqlite_repository_reinitialize([web_db_sqlite_repository_reinitialize])
web_db_sqlite_repository_add_log([web_db_sqlite_repository_add_log])
web_db_sqlite_repository__apply_filters([web_db_sqlite_repository__apply_filters])
web_db_sqlite_repository_get_logs([web_db_sqlite_repository_get_logs])
web_db_sqlite_repository_get_max_log_id([web_db_sqlite_repository_get_max_log_id])
web_db_sqlite_repository_get_logs_after_id([web_db_sqlite_repository_get_logs_after_id])
web_db_sqlite_repository_get_total_logs([web_db_sqlite_repository_get_total_logs])
web_db_sqlite_repository_get_log_histogram([web_db_sqlite_repository_get_log_histogram])
web_db_sqlite_repository_get_stats_summary([web_db_sqlite_repository_get_stats_summary])
web_db_sqlite_repository_get_deckies([web_db_sqlite_repository_get_deckies])
web_db_sqlite_repository_get_user_by_username([web_db_sqlite_repository_get_user_by_username])
web_db_sqlite_repository_get_user_by_uuid([web_db_sqlite_repository_get_user_by_uuid])
web_db_sqlite_repository_create_user([web_db_sqlite_repository_create_user])
web_db_sqlite_repository_update_user_password([web_db_sqlite_repository_update_user_password])
web_db_sqlite_repository_add_bounty([web_db_sqlite_repository_add_bounty])
web_db_sqlite_repository__apply_bounty_filters([web_db_sqlite_repository__apply_bounty_filters])
web_db_sqlite_repository_get_bounties([web_db_sqlite_repository_get_bounties])
web_db_sqlite_repository_get_total_bounties([web_db_sqlite_repository_get_total_bounties])
web_router_auth_api_change_pass_change_password([auth_api_change_pass_change_password])
web_router_auth_api_login_login([auth_api_login_login])
web_router_logs_api_get_logs_get_logs([logs_api_get_logs_get_logs])
web_router_logs_api_get_histogram_get_logs_histogram([logs_api_get_histogram_get_logs_histogram])
web_router_bounty_api_get_bounties_get_bounties([bounty_api_get_bounties_get_bounties])
web_router_stats_api_get_stats_get_stats([stats_api_get_stats_get_stats])
web_router_fleet_api_mutate_decky_api_mutate_decky([api_mutate_decky_api_mutate_decky])
web_router_fleet_api_get_deckies_get_deckies([api_get_deckies_get_deckies])
web_router_fleet_api_mutate_interval_api_update_mutate_interval([api_mutate_interval_api_update_mutate_interval])
web_router_fleet_api_deploy_deckies_api_deploy_deckies([api_deploy_deckies_api_deploy_deckies])
web_router_stream_api_stream_events_stream_events([stream_api_stream_events_stream_events])
web_router_stream_api_stream_events_event_generator([stream_api_stream_events_event_generator])
end
%% Key Connection Edges
network_detect_interface --> network__run
network_detect_subnet --> network__run
network_get_host_ip --> network__run
network_setup_host_macvlan --> network__run
network_teardown_host_macvlan --> network__run
network_setup_host_ipvlan --> network__run
network_teardown_host_ipvlan --> network__run
ini_loader_load_ini --> ini_loader__parse_configparser
ini_loader_load_ini_from_string --> ini_loader__parse_configparser
composer_generate_compose --> os_fingerprint_get_os_sysctls
composer_write_compose --> composer_generate_compose
fleet_resolve_distros --> distros_random_distro
fleet_build_deckies --> fleet_resolve_distros
fleet_build_deckies --> config_random_hostname
fleet_build_deckies_from_ini --> archetypes_get_archetype
fleet_build_deckies_from_ini --> fleet_all_service_names
cli_deploy --> ini_loader_load_ini
cli_deploy --> network_detect_interface
cli_deploy --> fleet_build_deckies_from_ini
cli_deploy --> engine_deployer_deploy
cli_collect --> collector_worker_log_collector_worker
cli_mutate --> mutator_engine_run_watch_loop
cli_correlate --> correlation_engine_ingest_file
cli_correlate --> correlation_engine_traversals
engine_deployer_deploy --> network_ips_to_range
engine_deployer_deploy --> network_setup_host_macvlan
engine_deployer_deploy --> composer_write_compose
engine_deployer_deploy --> engine_deployer__compose_with_retry
engine_deployer_teardown --> network_teardown_host_macvlan
engine_deployer_teardown --> config_clear_state
collector_worker_log_collector_worker --> collector_worker__stream_container
collector_worker__stream_container --> collector_worker_parse_rfc5424
mutator_engine_mutate_decky --> composer_write_compose
mutator_engine_mutate_decky --> engine_deployer__compose_with_retry
mutator_engine_mutate_all --> mutator_engine_mutate_decky
mutator_engine_run_watch_loop --> mutator_engine_mutate_all
web_db_sqlite_repository_initialize --> web_db_sqlite_database_init_db
web_db_sqlite_repository_get_logs --> web_db_sqlite_repository__apply_filters
web_router_auth_api_login_login --> web_auth_verify_password
web_router_auth_api_login_login --> web_auth_create_access_token
web_router_logs_api_get_logs_get_logs --> web_db_sqlite_repository_get_logs
web_router_fleet_api_mutate_decky_api_mutate_decky --> mutator_engine_mutate_decky
web_router_fleet_api_deploy_deckies_api_deploy_deckies --> fleet_build_deckies_from_ini
web_router_stream_api_stream_events_stream_events --> web_db_sqlite_repository_get_logs_after_id
web_router_stream_api_stream_events_stream_events --> web_router_stream_api_stream_events_event_generator
```

View File

@@ -8,7 +8,7 @@
- [ ] **Telnet (Cowrie)** — Realistic banner and command emulation. - [ ] **Telnet (Cowrie)** — Realistic banner and command emulation.
- [ ] **RDP** — Realistic NLA authentication and screen capture (where possible). - [ ] **RDP** — Realistic NLA authentication and screen capture (where possible).
- [ ] **VNC** — Realistic RFB protocol handshake and authentication. - [ ] **VNC** — Realistic RFB protocol handshake and authentication.
- [ ] **Real SSH**Pass-through or high-interaction proxying. - [x] **Real SSH**High-interaction sshd with shell logging.
### Databases ### Databases
- [ ] **MySQL** — Support for common SQL queries and realistic schema. - [ ] **MySQL** — Support for common SQL queries and realistic schema.
@@ -22,6 +22,7 @@
- [x] **HTTP** — Flexible templates (WordPress, phpMyAdmin, etc.) with logging. - [x] **HTTP** — Flexible templates (WordPress, phpMyAdmin, etc.) with logging.
- [ ] **Docker API** — Realistic responses for `docker version` and `docker ps`. - [ ] **Docker API** — Realistic responses for `docker version` and `docker ps`.
- [ ] **Kubernetes (K8s)** — Mocked kubectl responses and basic API exploration. - [ ] **Kubernetes (K8s)** — Mocked kubectl responses and basic API exploration.
- [x] **LLMNR** — Realistic local name resolution responses via responder-style emulation.
### File Transfer & Storage ### File Transfer & Storage
- [ ] **SMB** — Realistic share discovery and basic file browsing. - [ ] **SMB** — Realistic share discovery and basic file browsing.
@@ -38,7 +39,6 @@
- [x] **MQTT** — Basic topic subscription and publishing support. - [x] **MQTT** — Basic topic subscription and publishing support.
- [x] **SNMP** — Realistic MIB responses for common OIDs. - [x] **SNMP** — Realistic MIB responses for common OIDs.
- [ ] **SIP** — Basic VoIP protocol handshake and registration. - [ ] **SIP** — Basic VoIP protocol handshake and registration.
- [ ] **LLMNR** — Realistic local name resolution responses.
- [x] **Conpot** — SCADA/ICS protocol emulation (Modbus, etc.). - [x] **Conpot** — SCADA/ICS protocol emulation (Modbus, etc.).
--- ---
@@ -49,7 +49,7 @@
- [ ] **Canary tokens** — Embed fake AWS keys and honeydocs into decky filesystems. - [ ] **Canary tokens** — Embed fake AWS keys and honeydocs into decky filesystems.
- [ ] **Tarpit mode** — Slow down attackers by drip-feeding bytes or delaying responses. - [ ] **Tarpit mode** — Slow down attackers by drip-feeding bytes or delaying responses.
- [x] **Dynamic decky mutation** — Rotate exposed services or OS fingerprints over time. - [x] **Dynamic decky mutation** — Rotate exposed services or OS fingerprints over time.
- [ ] **Credential harvesting DB** — Centralized database for all username/password attempts. - [x] **Credential harvesting DB** — Centralized database for all username/password attempts.
- [ ] **Session recording** — Full capture for SSH/Telnet sessions. - [ ] **Session recording** — Full capture for SSH/Telnet sessions.
- [ ] **Payload capture** — Store and hash files uploaded by attackers. - [ ] **Payload capture** — Store and hash files uploaded by attackers.
@@ -67,7 +67,7 @@
- [x] **Decky Inventory** — Dedicated "Decoy Fleet" page showing all deployed assets. - [x] **Decky Inventory** — Dedicated "Decoy Fleet" page showing all deployed assets.
- [ ] **Pre-built Kibana/Grafana dashboards** — Ship JSON exports for ELK/Grafana. - [ ] **Pre-built Kibana/Grafana dashboards** — Ship JSON exports for ELK/Grafana.
- [ ] **CLI live feed**`decnet watch` command for a unified, colored terminal stream. - [ ] **CLI live feed**`decnet watch` command for a unified, colored terminal stream.
- [ ] **Traversal graph export** — Export attacker movement as DOT or JSON. - [x] **Traversal graph export** — Export attacker movement as JSON (via CLI).
## Deployment & Infrastructure ## Deployment & Infrastructure

View File

@@ -1,66 +0,0 @@
# DECNET Execution Graphs
These graphs illustrate the logical flow of execution within the DECNET framework, showing how high-level commands and API requests trigger secondary processes and subsystem interactions.
## 1. Deployment & Teardown Flow
This flow shows the orchestration from a CLI `deploy` command down to network setup and container instantiation.
```mermaid
graph TD
CLI_Deploy([cli.deploy]) --> INI[ini_loader.load_ini]
CLI_Deploy --> NET_Detect[network.detect_interface]
CLI_Deploy --> FleetBuild[fleet.build_deckies_from_ini]
FleetBuild --> Archetype[archetypes.get_archetype]
FleetBuild --> Distro[distros.get_distro]
CLI_Deploy --> Engine_Deploy[engine.deployer.deploy]
Engine_Deploy --> IP_Alloc[network.allocate_ips]
Engine_Deploy --> NET_Setup[network.setup_host_macvlan]
Engine_Deploy --> Compose_Gen[composer.write_compose]
Engine_Deploy --> Docker_Up[engine.deployer._compose_with_retry]
CLI_Teardown([cli.teardown]) --> Engine_Teardown[engine.deployer.teardown]
Engine_Teardown --> NET_Cleanup[network.teardown_host_macvlan]
Engine_Teardown --> Docker_Down[engine.deployer._compose]
```
## 2. Mutation & Monitoring Flow
How DECNET maintains deception by periodically changing decoy identities and monitoring activities.
```mermaid
graph LR
subgraph Periodic_Process
CLI_Mutate([cli.mutate]) --> Mutate_Loop[mutator.engine.run_watch_loop]
end
Mutate_Loop --> Mutate_All[mutator.engine.mutate_all]
Mutate_All --> Mutate_Decky[mutator.engine.mutate_decky]
Mutate_Decky --> Get_New_Identity[archetypes.get_archetype]
Mutate_Decky --> Rewrite_Compose[composer.write_compose]
Mutate_Decky --> Restart_Container[engine.deployer._compose_with_retry]
subgraph Log_Collection
CLI_Collect([cli.collect]) --> Worker[collector.worker.log_collector_worker]
Worker --> Stream[collector.worker._stream_container]
Stream --> Parse[collector.worker.parse_rfc5424]
end
```
## 3. Web API Flow (Fleet Management)
How the Web UI interacts with the underlying systems via the FastAPI router.
```mermaid
graph TD
Web_UI[Web Dashboard] --> API_Deploy[web.router.fleet.deploy_deckies]
Web_UI --> API_Mutate[web.router.fleet.mutate_decky]
Web_UI --> API_Stream[web.router.stream.stream_events]
API_Deploy --> FleetBuild[fleet.build_deckies_from_ini]
API_Mutate --> Mutator[mutator.engine.mutate_decky]
API_Stream --> DB_Pull[web.db.sqlite.repository.get_logs_after_id]
DB_Pull --> SQLite[(SQLite Database)]
```

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 528 KiB

View File

@@ -1,192 +0,0 @@
# DECNET Full Test Config
# Covers all 25 registered services across 10 role-themed deckies + archetype pool.
# Distros are auto-cycled for heterogeneity (9 profiles, round-robin).
#
# nmap_os controls the TCP/IP stack sysctls injected into each decky's base
# container so nmap OS detection returns the expected OS family:
# linux → TTL 64, syn_retries 6
# windows → TTL 128, syn_retries 2, large recv buffer
# embedded → TTL 255, syn_retries 3
# bsd → TTL 64, syn_retries 6
# cisco → TTL 255, syn_retries 2
#
# Usage:
# decnet deploy --config test-full.ini --dry-run
# sudo decnet deploy --config test-full.ini --log-target 192.168.1.200:5140 \
# --log-file /var/log/decnet/decnet.log
[general]
net = 192.168.1.0/24
gw = 192.168.1.1
interface = wlp6s0
#log_target = 192.168.1.200:5140
# ── Archetype pool: 10 Windows workstations ───────────────────────────────────
# archetype=windows-workstation already sets nmap_os=windows automatically.
[windows-workstation]
archetype = windows-workstation
amount = 10
# ── Web / Mail stack ──────────────────────────────────────────────────────────
# Looks like an internet-facing Linux mail + web host
[decky-webmail]
ip = 192.168.1.110
services = http, smtp, imap, pop3
nmap_os = linux
[decky-webmail.http]
server_header = Apache/2.4.54 (Debian)
response_code = 200
fake_app = wordpress
[decky-webmail.smtp]
smtp_banner = 220 mail.corp.local ESMTP Postfix (Debian/GNU)
smtp_mta = mail.corp.local
# ── File / Transfer services ──────────────────────────────────────────────────
# Presents as a Windows/Samba file server — TTL 128 seals the illusion.
[decky-fileserv]
ip = 192.168.1.111
services = smb, ftp, tftp
nmap_os = windows
[decky-fileserv.smb]
workgroup = CORP
server_name = FILESERV01
os_version = Windows Server 2019
# ── LAMP-style database host ──────────────────────────────────────────────────
[decky-dbsrv01]
ip = 192.168.1.112
services = mysql, redis
nmap_os = linux
[decky-dbsrv01.mysql]
mysql_version = 5.7.38-log
mysql_banner = MySQL Community Server
[decky-dbsrv01.redis]
redis_version = 6.2.7
# ── Modern stack databases ────────────────────────────────────────────────────
[decky-dbsrv02]
ip = 192.168.1.113
services = postgres, mongodb, elasticsearch
nmap_os = linux
[decky-dbsrv02.postgres]
pg_version = 14.5
[decky-dbsrv02.mongodb]
mongo_version = 5.0.9
[decky-dbsrv02.elasticsearch]
es_version = 8.4.3
cluster_name = prod-search
# ── Windows workstation / server ──────────────────────────────────────────────
# RDP + SMB + MSSQL — nmap_os=windows gives TTL 128 to complete the fingerprint.
[decky-winbox]
ip = 192.168.1.114
services = rdp, smb, mssql
nmap_os = windows
[decky-winbox.rdp]
os_version = Windows Server 2016
build = 14393
[decky-winbox.smb]
workgroup = CORP
server_name = WINSRV-DC01
os_version = Windows Server 2016
[decky-winbox.mssql]
mssql_version = Microsoft SQL Server 2019
# ── DevOps / Container infra ──────────────────────────────────────────────────
[decky-devops]
ip = 192.168.1.115
services = k8s, docker_api
nmap_os = linux
[decky-devops.k8s]
k8s_version = v1.26.3
[decky-devops.docker_api]
docker_version = 24.0.2
# ── Directory / Auth services ─────────────────────────────────────────────────
# Active Directory DC persona — Windows TCP stack matches the LDAP/SMB services.
[decky-ldapdc]
ip = 192.168.1.116
services = ldap, ssh
nmap_os = windows
[decky-ldapdc.ldap]
base_dn = dc=corp,dc=local
domain = corp.local
[decky-ldapdc.ssh]
ssh_version = OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
kernel_version = 5.15.0-91-generic
users = root:toor,admin:admin123,svc_backup:backup2024
# ── IoT / Industrial / Network management ─────────────────────────────────────
# TTL 255 is the embedded/network-device giveaway nmap looks for.
[decky-iot]
ip = 192.168.1.117
services = mqtt, snmp, conpot
nmap_os = embedded
[decky-iot.mqtt]
mqtt_version = Mosquitto 2.0.15
[decky-iot.snmp]
snmp_community = public
sys_descr = Linux router 5.4.0 #1 SMP x86_64
# ── VoIP / Local network services ────────────────────────────────────────────
[decky-voip]
ip = 192.168.1.118
services = sip, llmnr
nmap_os = linux
[decky-voip.sip]
sip_server = Asterisk PBX 18.12.0
sip_domain = pbx.corp.local
# ── Legacy admin / remote access ─────────────────────────────────────────────
# Old-school unpatched box — BSD stack for variety.
[decky-legacy]
ip = 192.168.1.119
services = telnet, vnc, ssh
nmap_os = bsd
[decky-legacy.ssh]
ssh_version = OpenSSH_7.4p1 Debian-10+deb9u7
kernel_version = 4.9.0-19-amd64
users = root:root,admin:password,pi:raspberry
[decky-legacy.vnc]
vnc_version = RealVNC 6.7.2

View File

@@ -2,13 +2,11 @@
Tests for the mutate interval API endpoint. Tests for the mutate interval API endpoint.
""" """
import json
import pytest import pytest
import httpx import httpx
from unittest.mock import patch, MagicMock from unittest.mock import patch
from pathlib import Path from pathlib import Path
import decnet.config
from decnet.config import DeckyConfig, DecnetConfig from decnet.config import DeckyConfig, DecnetConfig

View File

@@ -2,12 +2,10 @@
Tests for the SSE stream endpoint (decnet/web/router/stream/api_stream_events.py). Tests for the SSE stream endpoint (decnet/web/router/stream/api_stream_events.py).
""" """
import json
import pytest import pytest
import httpx import httpx
import asyncio
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, patch
# ── Stream endpoint tests ───────────────────────────────────────────────────── # ── Stream endpoint tests ─────────────────────────────────────────────────────

View File

@@ -2,14 +2,8 @@
Tests for decnet/cli.py — CLI commands via Typer's CliRunner. Tests for decnet/cli.py — CLI commands via Typer's CliRunner.
""" """
import subprocess from unittest.mock import MagicMock, patch
import os
import socketserver
from pathlib import Path
from unittest.mock import MagicMock, patch, AsyncMock
import pytest
import psutil
from typer.testing import CliRunner from typer.testing import CliRunner
from decnet.cli import app from decnet.cli import app

View File

@@ -3,9 +3,8 @@
import json import json
import asyncio import asyncio
import pytest import pytest
from pathlib import Path
from types import SimpleNamespace from types import SimpleNamespace
from unittest.mock import patch, MagicMock, AsyncMock from unittest.mock import patch, MagicMock
from decnet.collector import parse_rfc5424, is_service_container, is_service_event from decnet.collector import parse_rfc5424, is_service_container, is_service_event
from decnet.collector.worker import ( from decnet.collector.worker import (
_stream_container, _stream_container,

View File

@@ -8,8 +8,7 @@ All Docker and subprocess calls are mocked.
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from types import SimpleNamespace from unittest.mock import MagicMock, patch
from unittest.mock import MagicMock, patch, call
import pytest import pytest

View File

@@ -9,7 +9,6 @@ import pytest
from decnet.archetypes import get_archetype from decnet.archetypes import get_archetype
from decnet.fleet import ( from decnet.fleet import (
all_service_names,
build_deckies, build_deckies,
build_deckies_from_ini, build_deckies_from_ini,
resolve_distros, resolve_distros,

View File

@@ -8,7 +8,6 @@ async tests using temporary files.
import asyncio import asyncio
import json import json
import os import os
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, MagicMock, patch
import pytest import pytest

View File

@@ -3,14 +3,11 @@ Tests for decnet/web/api.py lifespan and decnet/web/dependencies.py auth helpers
""" """
import asyncio import asyncio
import os
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, MagicMock, patch
import jwt
import pytest import pytest
import httpx
from decnet.web.auth import SECRET_KEY, ALGORITHM, create_access_token from decnet.web.auth import create_access_token
# ── get_current_user ────────────────────────────────────────────────────────── # ── get_current_user ──────────────────────────────────────────────────────────