From fe46b8fc0bdd24749f151e5f33b454a5f2418423 Mon Sep 17 00:00:00 2001 From: anti Date: Sat, 11 Apr 2026 03:32:11 -0400 Subject: [PATCH] fix(conpot): use honeynet/conpot:latest base, run as conpot user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The BASE_IMAGE build arg was being unconditionally overwritten by composer.py with the decky's distro build_base (debian:bookworm-slim), turning the conpot container into a bare Debian image with no conpot installation — hence the silent restart loop. Two fixes: 1. composer.py: use args.setdefault() so services that pre-declare BASE_IMAGE in their compose_fragment() win over the distro default. 2. conpot.py: pre-declare BASE_IMAGE=honeynet/conpot:latest in build args so it always uses the upstream image regardless of decky distro. Also removed the USER decnet switch from the conpot Dockerfile. The upstream image already runs as the non-root 'conpot' user; switching to 'decnet' broke pkg_resources because conpot's eggs live under /home/conpot/.local and are only on sys.path for that user. --- decnet/composer.py | 5 ++++- decnet/services/conpot.py | 4 ++-- templates/conpot/Dockerfile | 21 ++++++++------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/decnet/composer.py b/decnet/composer.py index 9539451..973762e 100644 --- a/decnet/composer.py +++ b/decnet/composer.py @@ -69,8 +69,11 @@ def generate_compose(config: DecnetConfig) -> dict: # Inject the per-decky base image into build services so containers # vary by distro and don't all fingerprint as debian:bookworm-slim. + # Services that need a fixed upstream image (e.g. conpot) can pre-set + # build.args.BASE_IMAGE in their compose_fragment() to opt out. if "build" in fragment: - fragment["build"].setdefault("args", {})["BASE_IMAGE"] = decky.build_base + args = fragment["build"].setdefault("args", {}) + args.setdefault("BASE_IMAGE", decky.build_base) fragment.setdefault("environment", {}) fragment["environment"]["HOSTNAME"] = decky.hostname diff --git a/decnet/services/conpot.py b/decnet/services/conpot.py index 1b01f68..643eac6 100644 --- a/decnet/services/conpot.py +++ b/decnet/services/conpot.py @@ -1,4 +1,3 @@ -import os from pathlib import Path from decnet.services.base import BaseService @@ -24,7 +23,8 @@ class ConpotService(BaseService): return { "build": { - "context": str(self.dockerfile_context()) + "context": str(self.dockerfile_context()), + "args": {"BASE_IMAGE": "honeynet/conpot:latest"}, }, "container_name": f"{decky_name}-conpot", "restart": "unless-stopped", diff --git a/templates/conpot/Dockerfile b/templates/conpot/Dockerfile index 2286c4f..3cca519 100644 --- a/templates/conpot/Dockerfile +++ b/templates/conpot/Dockerfile @@ -3,21 +3,16 @@ FROM ${BASE_IMAGE} USER root -# Replace 5020 with 502 in all templates +# Replace 5020 with 502 in all templates so Modbus binds on the standard port RUN find /opt /usr /etc /home -name "*.xml" -exec sed -i 's/5020<\/port>/502<\/port>/g' {} + 2>/dev/null || true RUN find /opt /usr /etc /home -name "*.xml" -exec sed -i 's/port="5020"/port="502"/g' {} + 2>/dev/null || true -# Install libcap to allow binding to 502 +# Install libcap and give the Python interpreter permission to bind ports < 1024 RUN (apt-get update && apt-get install -y --no-install-recommends libcap2-bin 2>/dev/null) || (apk add --no-cache libcap 2>/dev/null) || true +RUN find /home/conpot/.local/bin /usr /opt -type f -name 'python*' -exec setcap 'cap_net_bind_service+eip' {} \; 2>/dev/null || true -# Apply setcap to python binaries -RUN find /usr /opt -type f -name 'python*' -exec setcap 'cap_net_bind_service+eip' {} \; 2>/dev/null || true - -# Create the decnet user following repository conventions -RUN (addgroup -S decnet && adduser -S decnet -G decnet 2>/dev/null) || useradd -r -s /bin/false decnet 2>/dev/null || true - -# Make sure all conpot-related directories are owned by decnet so it can run it -RUN chown -R decnet:decnet /var/log/conpot /opt/conpot /home/conpot /usr/local/lib/python*/site-packages/conpot/tests/data /tmp 2>/dev/null || true - -# Run as decnet user, avoiding the root-check failure and 777 hacks -USER decnet +# The upstream image already runs as the non-root 'conpot' user. +# We do NOT switch to a 'decnet' user here — doing so breaks pkg_resources +# because conpot's eggs live under /home/conpot/.local and are only on the +# Python path when the interpreter runs as 'conpot'. +USER conpot