merge testing->tomerge/main #7
@@ -34,13 +34,15 @@ RUN sed -i \
|
||||
-e 's|^#\?LogLevel.*|LogLevel VERBOSE|' \
|
||||
/etc/ssh/sshd_config
|
||||
|
||||
# rsyslog: forward auth.* and user.* to named pipe in RFC 5424 format.
|
||||
# The entrypoint relays the pipe to stdout for Docker log capture.
|
||||
# rsyslog: forward auth.* and user.* to PID 1's stdout in RFC 5424 format.
|
||||
# /proc/1/fd/1 is the container-stdout fd Docker attached — writing there
|
||||
# surfaces lines in `docker logs` without needing a named pipe + relay cat
|
||||
# (which would be readable AND writable by any root-in-container process).
|
||||
RUN printf '%s\n' \
|
||||
'# syslog-relay log bridge — auth + user events → named pipe as RFC 5424' \
|
||||
'# auth + user events → container stdout as RFC 5424' \
|
||||
'$template RFC5424fmt,"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n"' \
|
||||
'auth,authpriv.* |/run/systemd/journal/syslog-relay;RFC5424fmt' \
|
||||
'user.* |/run/systemd/journal/syslog-relay;RFC5424fmt' \
|
||||
'auth,authpriv.* /proc/1/fd/1;RFC5424fmt' \
|
||||
'user.* /proc/1/fd/1;RFC5424fmt' \
|
||||
> /etc/rsyslog.d/50-journal-forward.conf
|
||||
|
||||
# Silence default catch-all rules so we own auth/user routing exclusively
|
||||
|
||||
@@ -31,15 +31,10 @@ ls /var/www/html
|
||||
HIST
|
||||
fi
|
||||
|
||||
# Logging pipeline: named pipe → rsyslogd (RFC 5424) → stdout → Docker log capture.
|
||||
# Pipe lives under /run/systemd/journal/ and the relay process is cloaked via
|
||||
# exec -a so `ps aux` shows "systemd-journal-fwd" instead of a raw `cat`.
|
||||
mkdir -p /run/systemd/journal
|
||||
mkfifo /run/systemd/journal/syslog-relay
|
||||
|
||||
bash -c 'exec -a "systemd-journal-fwd" cat /run/systemd/journal/syslog-relay' &
|
||||
|
||||
# Start rsyslog (reads /etc/rsyslog.d/50-journal-forward.conf, writes to the pipe above)
|
||||
# Logging pipeline: rsyslogd (RFC 5424) → /proc/1/fd/1 → Docker log capture.
|
||||
# No intermediate pipe/relay — a named FIFO would be readable AND writable
|
||||
# by any root-in-container process, letting an attacker either eavesdrop on
|
||||
# the SIEM feed or inject forged log lines.
|
||||
rsyslogd
|
||||
|
||||
# File-catcher: mirror attacker drops into host-mounted quarantine with attribution.
|
||||
|
||||
@@ -144,27 +144,25 @@ def test_dockerfile_prompt_command_logger():
|
||||
assert "logger" in df
|
||||
|
||||
|
||||
def test_entrypoint_creates_named_pipe():
|
||||
assert "mkfifo" in _entrypoint_text()
|
||||
|
||||
|
||||
def test_entrypoint_relay_pipe_path_is_disguised():
|
||||
def test_entrypoint_has_no_named_pipe():
|
||||
# Named pipes in the container are a liability — readable and writable
|
||||
# by any root process. The log bridge must not rely on one.
|
||||
ep = _entrypoint_text()
|
||||
# Pipe lives under /run/systemd/journal/, not the obvious /var/run/decnet-logs.
|
||||
assert "/run/systemd/journal/syslog-relay" in ep
|
||||
assert "decnet-logs" not in ep
|
||||
assert "mkfifo" not in ep
|
||||
assert "syslog-relay" not in ep
|
||||
|
||||
|
||||
def test_entrypoint_cat_relay_is_cloaked():
|
||||
def test_entrypoint_has_no_relay_cat():
|
||||
# No intermediate cat relay either (removed together with the pipe).
|
||||
ep = _entrypoint_text()
|
||||
# `cat` is invoked via exec -a so ps shows systemd-journal-fwd.
|
||||
assert "systemd-journal-fwd" in ep
|
||||
assert "exec -a" in ep
|
||||
assert "systemd-journal-fwd" not in ep
|
||||
|
||||
|
||||
def test_dockerfile_rsyslog_uses_disguised_pipe():
|
||||
def test_dockerfile_rsyslog_targets_pid1_stdout():
|
||||
df = _dockerfile_text()
|
||||
assert "/run/systemd/journal/syslog-relay" in df
|
||||
# rsyslog writes straight to /proc/1/fd/1 — no pipe file on disk.
|
||||
assert "/proc/1/fd/1" in df
|
||||
assert "syslog-relay" not in df
|
||||
assert "decnet-logs" not in df
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user