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:
2026-04-04 04:08:27 -03:00
parent 07c06e3c0a
commit cf1e00af28
102 changed files with 974 additions and 309 deletions

View File

@@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
&& rm -rf /var/lib/apt/lists/*
COPY redis_honeypot.py /opt/redis_honeypot.py
COPY server.py /opt/server.py
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

View File

@@ -1,3 +1,3 @@
#!/bin/bash
set -e
exec python3 /opt/redis_honeypot.py
exec python3 /opt/server.py

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
Redis honeypot.
Redisserver.
Implements enough of the RESP protocol to respond to AUTH, INFO, CONFIG GET,
KEYS, and arbitrary commands. Logs every command and argument as JSON.
"""
@@ -11,19 +11,22 @@ import os
import socket
from datetime import datetime, timezone
HONEYPOT_NAME = os.environ.get("HONEYPOT_NAME", "cache-server")
LOG_TARGET = os.environ.get("LOG_TARGET", "")
NODE_NAME = os.environ.get("NODE_NAME", "cache-server")
LOG_TARGET = os.environ.get("LOG_TARGET", "")
_REDIS_VER = os.environ.get("REDIS_VERSION", "7.0.12")
_REDIS_OS = os.environ.get("REDIS_OS", "Linux 5.15.0")
_INFO = f"""# Server
redis_version:7.0.12
redis_mode:standalone
os:Linux 5.15.0
arch_bits:64
tcp_port:6379
uptime_in_seconds:864000
connected_clients:1
# Keyspace
""".encode()
_INFO = (
f"# Server\n"
f"redis_version:{_REDIS_VER}\n"
f"redis_mode:standalone\n"
f"os:{_REDIS_OS}\n"
f"arch_bits:64\n"
f"tcp_port:6379\n"
f"uptime_in_seconds:864000\n"
f"connected_clients:1\n"
f"# Keyspace\n"
).encode()
def _forward(event: dict) -> None:
@@ -41,7 +44,7 @@ def _log(event_type: str, **kwargs) -> None:
event = {
"ts": datetime.now(timezone.utc).isoformat(),
"service": "redis",
"host": HONEYPOT_NAME,
"host": NODE_NAME,
"event": event_type,
**kwargs,
}
@@ -158,7 +161,7 @@ class RedisProtocol(asyncio.Protocol):
async def main():
_log("startup", msg=f"Redis honeypot starting as {HONEYPOT_NAME}")
_log("startup", msg=f"Redis server starting as {NODE_NAME}")
loop = asyncio.get_running_loop()
server = await loop.create_server(RedisProtocol, "0.0.0.0", 6379)
async with server: