Add per-service customization, stealth hardening, and BYOS support
- HTTP: configurable server_header, response_code, fake_app presets (apache/nginx/wordpress/phpmyadmin/iis), extra_headers, custom_body, static files directory mount - SSH/Cowrie: configurable kernel_version, hardware_platform, ssh_banner, and users/passwords via COWRIE_USERDB_ENTRIES; switched to build mode so cowrie.cfg.j2 persona fields and userdb.txt generation work - SMTP: configurable banner and MTA hostname - MySQL: configurable version string in protocol greeting - Redis: configurable redis_version and os string in INFO response - BYOS: [custom-*] INI sections define bring-your-own Docker services - Stealth: rename all *_honeypot.py → server.py; replace HONEYPOT_NAME env var with NODE_NAME across all 22+ service templates and plugins; strip "honeypot" from all in-container file content - Config: DeckyConfig.service_config dict; INI [decky-N.svc] subsections; composer passes service_cfg to compose_fragment - 350 tests passing (100%) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,12 @@ class BaseService(ABC):
|
||||
default_image: str # Docker image tag, or "build" if a Dockerfile is needed
|
||||
|
||||
@abstractmethod
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(
|
||||
self,
|
||||
decky_name: str,
|
||||
log_target: str | None = None,
|
||||
service_cfg: dict | None = None,
|
||||
) -> dict:
|
||||
"""
|
||||
Return the docker-compose service dict for this service on a given decky.
|
||||
|
||||
@@ -26,6 +31,7 @@ class BaseService(ABC):
|
||||
Args:
|
||||
decky_name: unique identifier for the decky (e.g. "decky-01")
|
||||
log_target: "ip:port" string if log forwarding is enabled, else None
|
||||
service_cfg: optional per-service persona config from INI subsection
|
||||
"""
|
||||
|
||||
def dockerfile_context(self) -> Path | None:
|
||||
|
||||
@@ -12,7 +12,7 @@ class ConpotService(BaseService):
|
||||
ports = [502, 161, 80]
|
||||
default_image = "honeynet/conpot"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
return {
|
||||
"image": "honeynet/conpot",
|
||||
"container_name": f"{decky_name}-conpot",
|
||||
|
||||
@@ -9,12 +9,12 @@ class DockerAPIService(BaseService):
|
||||
ports = [2375, 2376]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-docker-api",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -10,13 +10,13 @@ class ElasticsearchService(BaseService):
|
||||
ports = [9200]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-elasticsearch",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {
|
||||
"HONEYPOT_NAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
},
|
||||
}
|
||||
if log_target:
|
||||
|
||||
@@ -9,13 +9,13 @@ class FTPService(BaseService):
|
||||
ports = [21]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-ftp",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {
|
||||
"HONEYPOT_NAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
},
|
||||
}
|
||||
if log_target:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from decnet.services.base import BaseService
|
||||
|
||||
@@ -9,17 +10,43 @@ class HTTPService(BaseService):
|
||||
ports = [80, 443]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(
|
||||
self,
|
||||
decky_name: str,
|
||||
log_target: str | None = None,
|
||||
service_cfg: dict | None = None,
|
||||
) -> dict:
|
||||
cfg = service_cfg or {}
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-http",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {
|
||||
"HONEYPOT_NAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
# Optional persona overrides — only injected when explicitly set
|
||||
if "server_header" in cfg:
|
||||
fragment["environment"]["SERVER_HEADER"] = cfg["server_header"]
|
||||
if "response_code" in cfg:
|
||||
fragment["environment"]["RESPONSE_CODE"] = str(cfg["response_code"])
|
||||
if "fake_app" in cfg:
|
||||
fragment["environment"]["FAKE_APP"] = cfg["fake_app"]
|
||||
if "extra_headers" in cfg:
|
||||
val = cfg["extra_headers"]
|
||||
fragment["environment"]["EXTRA_HEADERS"] = (
|
||||
json.dumps(val) if isinstance(val, dict) else val
|
||||
)
|
||||
if "custom_body" in cfg:
|
||||
fragment["environment"]["CUSTOM_BODY"] = cfg["custom_body"]
|
||||
if "files" in cfg:
|
||||
files_path = str(Path(cfg["files"]).resolve())
|
||||
fragment["environment"]["FILES_DIR"] = "/opt/html_files"
|
||||
fragment.setdefault("volumes", []).append(f"{files_path}:/opt/html_files:ro")
|
||||
|
||||
return fragment
|
||||
|
||||
def dockerfile_context(self) -> Path | None:
|
||||
|
||||
@@ -9,12 +9,12 @@ class IMAPService(BaseService):
|
||||
ports = [143, 993]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-imap",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,12 +9,12 @@ class KubernetesAPIService(BaseService):
|
||||
ports = [6443, 8080]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-k8s",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,13 +9,13 @@ class LDAPService(BaseService):
|
||||
ports = [389, 636]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-ldap",
|
||||
"restart": "unless-stopped",
|
||||
"cap_add": ["NET_BIND_SERVICE"],
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -16,12 +16,12 @@ class LLMNRService(BaseService):
|
||||
ports = [5355, 5353]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-llmnr",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,12 +9,12 @@ class MongoDBService(BaseService):
|
||||
ports = [27017]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-mongodb",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,12 +9,12 @@ class MQTTService(BaseService):
|
||||
ports = [1883]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-mqtt",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,12 +9,12 @@ class MSSQLService(BaseService):
|
||||
ports = [1433]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-mssql",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,15 +9,23 @@ class MySQLService(BaseService):
|
||||
ports = [3306]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(
|
||||
self,
|
||||
decky_name: str,
|
||||
log_target: str | None = None,
|
||||
service_cfg: dict | None = None,
|
||||
) -> dict:
|
||||
cfg = service_cfg or {}
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-mysql",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
if "version" in cfg:
|
||||
fragment["environment"]["MYSQL_VERSION"] = cfg["version"]
|
||||
return fragment
|
||||
|
||||
def dockerfile_context(self) -> Path | None:
|
||||
|
||||
@@ -9,12 +9,12 @@ class POP3Service(BaseService):
|
||||
ports = [110, 995]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-pop3",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,12 +9,12 @@ class PostgresService(BaseService):
|
||||
ports = [5432]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-postgres",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,13 +9,13 @@ class RDPService(BaseService):
|
||||
ports = [3389]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-rdp",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {
|
||||
"HONEYPOT_NAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
},
|
||||
}
|
||||
if log_target:
|
||||
|
||||
@@ -9,15 +9,25 @@ class RedisService(BaseService):
|
||||
ports = [6379]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(
|
||||
self,
|
||||
decky_name: str,
|
||||
log_target: str | None = None,
|
||||
service_cfg: dict | None = None,
|
||||
) -> dict:
|
||||
cfg = service_cfg or {}
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-redis",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
if "version" in cfg:
|
||||
fragment["environment"]["REDIS_VERSION"] = cfg["version"]
|
||||
if "os_string" in cfg:
|
||||
fragment["environment"]["REDIS_OS"] = cfg["os_string"]
|
||||
return fragment
|
||||
|
||||
def dockerfile_context(self) -> Path | None:
|
||||
|
||||
@@ -31,6 +31,12 @@ def _load_plugins() -> None:
|
||||
_loaded = True
|
||||
|
||||
|
||||
def register_custom_service(instance: BaseService) -> None:
|
||||
"""Register a dynamically created service (e.g. BYOS from INI)."""
|
||||
_load_plugins()
|
||||
_registry[instance.name] = instance
|
||||
|
||||
|
||||
def get_service(name: str) -> BaseService:
|
||||
_load_plugins()
|
||||
if name not in _registry:
|
||||
|
||||
@@ -9,12 +9,12 @@ class SIPService(BaseService):
|
||||
ports = [5060]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-sip",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,14 +9,14 @@ class SMBService(BaseService):
|
||||
ports = [445, 139]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-smb",
|
||||
"restart": "unless-stopped",
|
||||
"cap_add": ["NET_BIND_SERVICE"],
|
||||
"environment": {
|
||||
"HONEYPOT_NAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
},
|
||||
}
|
||||
if log_target:
|
||||
|
||||
@@ -10,18 +10,28 @@ class SMTPService(BaseService):
|
||||
ports = [25, 587]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(
|
||||
self,
|
||||
decky_name: str,
|
||||
log_target: str | None = None,
|
||||
service_cfg: dict | None = None,
|
||||
) -> dict:
|
||||
cfg = service_cfg or {}
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-smtp",
|
||||
"restart": "unless-stopped",
|
||||
"cap_add": ["NET_BIND_SERVICE"],
|
||||
"environment": {
|
||||
"HONEYPOT_NAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
if "banner" in cfg:
|
||||
fragment["environment"]["SMTP_BANNER"] = cfg["banner"]
|
||||
if "mta" in cfg:
|
||||
fragment["environment"]["SMTP_MTA"] = cfg["mta"]
|
||||
return fragment
|
||||
|
||||
def dockerfile_context(self) -> Path:
|
||||
|
||||
@@ -9,12 +9,12 @@ class SNMPService(BaseService):
|
||||
ports = [161]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-snmp",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
from pathlib import Path
|
||||
from decnet.services.base import BaseService
|
||||
|
||||
TEMPLATES_DIR = Path(__file__).parent.parent.parent / "templates" / "cowrie"
|
||||
|
||||
|
||||
class SSHService(BaseService):
|
||||
name = "ssh"
|
||||
ports = [22, 2222]
|
||||
default_image = "cowrie/cowrie"
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(
|
||||
self,
|
||||
decky_name: str,
|
||||
log_target: str | None = None,
|
||||
service_cfg: dict | None = None,
|
||||
) -> dict:
|
||||
cfg = service_cfg or {}
|
||||
env: dict = {
|
||||
# Override [honeypot] and [ssh] listen_endpoints to also bind port 22
|
||||
"COWRIE_HONEYPOT_HOSTNAME": decky_name,
|
||||
"NODE_NAME": decky_name,
|
||||
"COWRIE_HOSTNAME": decky_name,
|
||||
"COWRIE_HONEYPOT_LISTEN_ENDPOINTS": "tcp:22:interface=0.0.0.0 tcp:2222:interface=0.0.0.0",
|
||||
"COWRIE_SSH_LISTEN_ENDPOINTS": "tcp:22:interface=0.0.0.0 tcp:2222:interface=0.0.0.0",
|
||||
}
|
||||
@@ -18,13 +27,26 @@ class SSHService(BaseService):
|
||||
env["COWRIE_OUTPUT_TCP_ENABLED"] = "true"
|
||||
env["COWRIE_OUTPUT_TCP_HOST"] = host
|
||||
env["COWRIE_OUTPUT_TCP_PORT"] = port
|
||||
|
||||
# Optional persona overrides
|
||||
if "kernel_version" in cfg:
|
||||
env["COWRIE_HONEYPOT_KERNEL_VERSION"] = cfg["kernel_version"]
|
||||
if "kernel_build_string" in cfg:
|
||||
env["COWRIE_HONEYPOT_KERNEL_BUILD_STRING"] = cfg["kernel_build_string"]
|
||||
if "hardware_platform" in cfg:
|
||||
env["COWRIE_HONEYPOT_HARDWARE_PLATFORM"] = cfg["hardware_platform"]
|
||||
if "ssh_banner" in cfg:
|
||||
env["COWRIE_SSH_VERSION"] = cfg["ssh_banner"]
|
||||
if "users" in cfg:
|
||||
env["COWRIE_USERDB_ENTRIES"] = cfg["users"]
|
||||
|
||||
return {
|
||||
"image": "cowrie/cowrie",
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-ssh",
|
||||
"restart": "unless-stopped",
|
||||
"cap_add": ["NET_BIND_SERVICE"],
|
||||
"environment": env,
|
||||
}
|
||||
|
||||
def dockerfile_context(self):
|
||||
return None
|
||||
def dockerfile_context(self) -> Path:
|
||||
return TEMPLATES_DIR
|
||||
|
||||
@@ -6,7 +6,7 @@ class TelnetService(BaseService):
|
||||
ports = [23]
|
||||
default_image = "cowrie/cowrie"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
env: dict = {
|
||||
"COWRIE_HONEYPOT_HOSTNAME": decky_name,
|
||||
"COWRIE_TELNET_ENABLED": "true",
|
||||
|
||||
@@ -9,12 +9,12 @@ class TFTPService(BaseService):
|
||||
ports = [69]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-tftp",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
@@ -9,12 +9,12 @@ class VNCService(BaseService):
|
||||
ports = [5900]
|
||||
default_image = "build"
|
||||
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None) -> dict:
|
||||
def compose_fragment(self, decky_name: str, log_target: str | None = None, service_cfg: dict | None = None) -> dict:
|
||||
fragment: dict = {
|
||||
"build": {"context": str(TEMPLATES_DIR)},
|
||||
"container_name": f"{decky_name}-vnc",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {"HONEYPOT_NAME": decky_name},
|
||||
"environment": {"NODE_NAME": decky_name},
|
||||
}
|
||||
if log_target:
|
||||
fragment["environment"]["LOG_TARGET"] = log_target
|
||||
|
||||
Reference in New Issue
Block a user