refactor: strip DECNET tokens from container-visible surface
Rename the container-side logging module decnet_logging → syslog_bridge (canonical at templates/syslog_bridge.py, synced into each template by the deployer). Drop the stale per-template copies; setuptools find was picking them up anyway. Swap useradd/USER/chown "decnet" for "logrelay" so no obvious token appears in the rendered container image. Apply the same cloaking pattern to the telnet template that SSH got: syslog pipe moves to /run/systemd/journal/syslog-relay and the relay is cat'd via exec -a "systemd-journal-fwd". rsyslog.d conf rename 99-decnet.conf → 50-journal-forward.conf. SSH capture script: /var/decnet/captured → /var/lib/systemd/coredump (real systemd path), logger tag decnet-capture → systemd-journal. Compose volume updated to match the new in-container quarantine path. SD element ID shifts decnet@55555 → relay@55555; synced across collector, parser, sniffer, prober, formatter, tests, and docs so the host-side pipeline still matches what containers emit.
This commit is contained in:
@@ -10,11 +10,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
||||
# rsyslog: forward auth.* and user.* to named pipe in RFC 5424 format
|
||||
RUN printf '%s\n' \
|
||||
'# DECNET log bridge — auth + user events → named pipe as RFC 5424' \
|
||||
'# syslog-relay log bridge — auth + user events → named pipe as RFC 5424' \
|
||||
'$template RFC5424fmt,"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n"' \
|
||||
'auth,authpriv.* |/var/run/decnet-logs;RFC5424fmt' \
|
||||
'user.* |/var/run/decnet-logs;RFC5424fmt' \
|
||||
> /etc/rsyslog.d/99-decnet.conf
|
||||
'auth,authpriv.* |/run/systemd/journal/syslog-relay;RFC5424fmt' \
|
||||
'user.* |/run/systemd/journal/syslog-relay;RFC5424fmt' \
|
||||
> /etc/rsyslog.d/50-journal-forward.conf
|
||||
|
||||
# Disable imklog — containers can't read /proc/kmsg
|
||||
RUN sed -i 's/^\(module(load="imklog"\)/# \1/' /etc/rsyslog.conf
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Shared RFC 5424 syslog helper for DECNET service templates.
|
||||
|
||||
Services call syslog_line() to format an RFC 5424 message, then
|
||||
write_syslog_file() to emit it to stdout — Docker captures it, and the
|
||||
host-side collector streams it into the log file.
|
||||
|
||||
RFC 5424 structure:
|
||||
<PRI>1 TIMESTAMP HOSTNAME APP-NAME PROCID MSGID [SD-ELEMENT] MSG
|
||||
|
||||
Facility: local0 (16), PEN for SD element ID: decnet@55555
|
||||
"""
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
|
||||
# ─── Constants ────────────────────────────────────────────────────────────────
|
||||
|
||||
_FACILITY_LOCAL0 = 16
|
||||
_SD_ID = "decnet@55555"
|
||||
_NILVALUE = "-"
|
||||
|
||||
SEVERITY_EMERG = 0
|
||||
SEVERITY_ALERT = 1
|
||||
SEVERITY_CRIT = 2
|
||||
SEVERITY_ERROR = 3
|
||||
SEVERITY_WARNING = 4
|
||||
SEVERITY_NOTICE = 5
|
||||
SEVERITY_INFO = 6
|
||||
SEVERITY_DEBUG = 7
|
||||
|
||||
_MAX_HOSTNAME = 255
|
||||
_MAX_APPNAME = 48
|
||||
_MAX_MSGID = 32
|
||||
|
||||
# ─── Formatter ────────────────────────────────────────────────────────────────
|
||||
|
||||
def _sd_escape(value: str) -> str:
|
||||
"""Escape SD-PARAM-VALUE per RFC 5424 §6.3.3."""
|
||||
return value.replace("\\", "\\\\").replace('"', '\\"').replace("]", "\\]")
|
||||
|
||||
|
||||
def _sd_element(fields: dict[str, Any]) -> str:
|
||||
if not fields:
|
||||
return _NILVALUE
|
||||
params = " ".join(f'{k}="{_sd_escape(str(v))}"' for k, v in fields.items())
|
||||
return f"[{_SD_ID} {params}]"
|
||||
|
||||
|
||||
def syslog_line(
|
||||
service: str,
|
||||
hostname: str,
|
||||
event_type: str,
|
||||
severity: int = SEVERITY_INFO,
|
||||
timestamp: datetime | None = None,
|
||||
msg: str | None = None,
|
||||
**fields: Any,
|
||||
) -> str:
|
||||
"""
|
||||
Return a single RFC 5424-compliant syslog line (no trailing newline).
|
||||
|
||||
Args:
|
||||
service: APP-NAME (e.g. "http", "mysql")
|
||||
hostname: HOSTNAME (decky node name)
|
||||
event_type: MSGID (e.g. "request", "login_attempt")
|
||||
severity: Syslog severity integer (default: INFO=6)
|
||||
timestamp: UTC datetime; defaults to now
|
||||
msg: Optional free-text MSG
|
||||
**fields: Encoded as structured data params
|
||||
"""
|
||||
pri = f"<{_FACILITY_LOCAL0 * 8 + severity}>"
|
||||
ts = (timestamp or datetime.now(timezone.utc)).isoformat()
|
||||
host = (hostname or _NILVALUE)[:_MAX_HOSTNAME]
|
||||
appname = (service or _NILVALUE)[:_MAX_APPNAME]
|
||||
msgid = (event_type or _NILVALUE)[:_MAX_MSGID]
|
||||
sd = _sd_element(fields)
|
||||
message = f" {msg}" if msg else ""
|
||||
return f"{pri}1 {ts} {host} {appname} {_NILVALUE} {msgid} {sd}{message}"
|
||||
|
||||
|
||||
def write_syslog_file(line: str) -> None:
|
||||
"""Emit a syslog line to stdout for Docker log capture."""
|
||||
print(line, flush=True)
|
||||
|
||||
|
||||
def forward_syslog(line: str, log_target: str) -> None:
|
||||
"""No-op stub. TCP forwarding is now handled by rsyslog, not by service containers."""
|
||||
pass
|
||||
@@ -27,12 +27,14 @@ cat /root/.env
|
||||
HIST
|
||||
fi
|
||||
|
||||
# Logging pipeline: named pipe → rsyslogd (RFC 5424) → stdout
|
||||
rm -f /var/run/decnet-logs
|
||||
mkfifo /var/run/decnet-logs
|
||||
# Logging pipeline: named pipe → rsyslogd (RFC 5424) → stdout.
|
||||
# Cloak the pipe path and the relay `cat` so `ps aux` / `ls /run` don't
|
||||
# betray the honeypot — see ssh/entrypoint.sh for the same pattern.
|
||||
mkdir -p /run/systemd/journal
|
||||
rm -f /run/systemd/journal/syslog-relay
|
||||
mkfifo /run/systemd/journal/syslog-relay
|
||||
|
||||
# Relay pipe to stdout so Docker captures all syslog events
|
||||
cat /var/run/decnet-logs &
|
||||
bash -c 'exec -a "systemd-journal-fwd" cat /run/systemd/journal/syslog-relay' &
|
||||
|
||||
# Start rsyslog
|
||||
rsyslogd
|
||||
|
||||
Reference in New Issue
Block a user