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:
@@ -172,7 +172,7 @@ class TestCollectorLiveIsolation:
|
||||
|
||||
def test_rfc5424_parser_handles_real_formats(self):
|
||||
"""Parser works on real log lines, not just test fixtures."""
|
||||
valid = '<134>1 2026-04-14T12:00:00Z decky-01 ssh - login_attempt [decnet@55555 src_ip="10.0.0.1" username="root" password="toor"] Failed login'
|
||||
valid = '<134>1 2026-04-14T12:00:00Z decky-01 ssh - login_attempt [relay@55555 src_ip="10.0.0.1" username="root" password="toor"] Failed login'
|
||||
result = parse_rfc5424(valid)
|
||||
assert result is not None
|
||||
assert result["decky"] == "decky-01"
|
||||
@@ -236,7 +236,7 @@ class TestIngesterLiveIsolation:
|
||||
"attacker_ip": "10.99.99.1",
|
||||
"fields": {"username": "root", "password": "toor"},
|
||||
"msg": "Failed login",
|
||||
"raw_line": '<134>1 2026-04-14T12:00:00Z decky-live-01 ssh - login_attempt [decnet@55555 src_ip="10.99.99.1"] Failed login',
|
||||
"raw_line": '<134>1 2026-04-14T12:00:00Z decky-live-01 ssh - login_attempt [relay@55555 src_ip="10.99.99.1"] Failed login',
|
||||
}
|
||||
json_file.write_text(json.dumps(record) + "\n")
|
||||
|
||||
@@ -333,7 +333,7 @@ class TestAttackerWorkerLiveIsolation:
|
||||
"attacker_ip": "10.77.77.1",
|
||||
"fields": {"username": "admin"},
|
||||
"msg": "",
|
||||
"raw_line": f'<134>1 2026-04-14T14:0{i}:00Z decky-live-03 {"ssh" if i < 2 else "http"} - login_attempt [decnet@55555 src_ip="10.77.77.1" username="admin"]',
|
||||
"raw_line": f'<134>1 2026-04-14T14:0{i}:00Z decky-live-03 {"ssh" if i < 2 else "http"} - login_attempt [relay@55555 src_ip="10.77.77.1" username="admin"]',
|
||||
})
|
||||
|
||||
state = _WorkerState()
|
||||
|
||||
@@ -18,8 +18,8 @@ _FUZZ_SETTINGS = dict(
|
||||
)
|
||||
|
||||
|
||||
def make_fake_decnet_logging() -> ModuleType:
|
||||
mod = ModuleType("decnet_logging")
|
||||
def make_fake_syslog_bridge() -> ModuleType:
|
||||
mod = ModuleType("syslog_bridge")
|
||||
mod.syslog_line = MagicMock(return_value="")
|
||||
mod.write_syslog_file = MagicMock()
|
||||
mod.forward_syslog = MagicMock()
|
||||
|
||||
@@ -17,8 +17,8 @@ import pytest
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _make_fake_decnet_logging() -> ModuleType:
|
||||
mod = ModuleType("decnet_logging")
|
||||
def _make_fake_syslog_bridge() -> ModuleType:
|
||||
mod = ModuleType("syslog_bridge")
|
||||
mod.syslog_line = MagicMock(return_value="")
|
||||
mod.write_syslog_file = MagicMock()
|
||||
mod.forward_syslog = MagicMock()
|
||||
@@ -28,17 +28,17 @@ def _make_fake_decnet_logging() -> ModuleType:
|
||||
|
||||
|
||||
def _load_imap():
|
||||
"""Import imap server module, injecting a stub decnet_logging."""
|
||||
"""Import imap server module, injecting a stub syslog_bridge."""
|
||||
env = {
|
||||
"NODE_NAME": "testhost",
|
||||
"IMAP_USERS": "admin:admin123,root:toor",
|
||||
"IMAP_BANNER": "* OK [testhost] Dovecot ready.",
|
||||
}
|
||||
for key in list(sys.modules):
|
||||
if key in ("imap_server", "decnet_logging"):
|
||||
if key in ("imap_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
|
||||
sys.modules["decnet_logging"] = _make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = _make_fake_syslog_bridge()
|
||||
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"imap_server", "templates/imap/server.py"
|
||||
|
||||
@@ -14,16 +14,16 @@ import pytest
|
||||
from hypothesis import given, settings
|
||||
from hypothesis import strategies as st
|
||||
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_decnet_logging, run_with_timeout
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_syslog_bridge, run_with_timeout
|
||||
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _load_mongodb():
|
||||
for key in list(sys.modules):
|
||||
if key in ("mongodb_server", "decnet_logging"):
|
||||
if key in ("mongodb_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
sys.modules["decnet_logging"] = make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = make_fake_syslog_bridge()
|
||||
spec = importlib.util.spec_from_file_location("mongodb_server", "templates/mongodb/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
|
||||
@@ -16,8 +16,8 @@ import pytest
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _make_fake_decnet_logging() -> ModuleType:
|
||||
mod = ModuleType("decnet_logging")
|
||||
def _make_fake_syslog_bridge() -> ModuleType:
|
||||
mod = ModuleType("syslog_bridge")
|
||||
mod.syslog_line = MagicMock(return_value="")
|
||||
mod.write_syslog_file = MagicMock()
|
||||
mod.forward_syslog = MagicMock()
|
||||
@@ -34,10 +34,10 @@ def _load_mqtt(accept_all: bool = True, custom_topics: str = "", persona: str =
|
||||
"MQTT_CUSTOM_TOPICS": custom_topics,
|
||||
}
|
||||
for key in list(sys.modules):
|
||||
if key in ("mqtt_server", "decnet_logging"):
|
||||
if key in ("mqtt_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
|
||||
sys.modules["decnet_logging"] = _make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = _make_fake_syslog_bridge()
|
||||
|
||||
spec = importlib.util.spec_from_file_location("mqtt_server", "templates/mqtt/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
|
||||
@@ -15,16 +15,16 @@ import pytest
|
||||
from hypothesis import given, settings
|
||||
from hypothesis import strategies as st
|
||||
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_decnet_logging, run_with_timeout
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_syslog_bridge, run_with_timeout
|
||||
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _load_mqtt():
|
||||
for key in list(sys.modules):
|
||||
if key in ("mqtt_server", "decnet_logging"):
|
||||
if key in ("mqtt_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
sys.modules["decnet_logging"] = make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = make_fake_syslog_bridge()
|
||||
spec = importlib.util.spec_from_file_location("mqtt_server", "templates/mqtt/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
with patch.dict("os.environ", {"MQTT_ACCEPT_ALL": "1", "MQTT_PERSONA": "water_plant"}, clear=False):
|
||||
|
||||
@@ -14,16 +14,16 @@ import pytest
|
||||
from hypothesis import given, settings
|
||||
from hypothesis import strategies as st
|
||||
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_decnet_logging, run_with_timeout
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_syslog_bridge, run_with_timeout
|
||||
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _load_mssql():
|
||||
for key in list(sys.modules):
|
||||
if key in ("mssql_server", "decnet_logging"):
|
||||
if key in ("mssql_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
sys.modules["decnet_logging"] = make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = make_fake_syslog_bridge()
|
||||
spec = importlib.util.spec_from_file_location("mssql_server", "templates/mssql/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
|
||||
@@ -14,16 +14,16 @@ import pytest
|
||||
from hypothesis import given, settings
|
||||
from hypothesis import strategies as st
|
||||
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_decnet_logging, run_with_timeout
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_syslog_bridge, run_with_timeout
|
||||
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _load_mysql():
|
||||
for key in list(sys.modules):
|
||||
if key in ("mysql_server", "decnet_logging"):
|
||||
if key in ("mysql_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
sys.modules["decnet_logging"] = make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = make_fake_syslog_bridge()
|
||||
spec = importlib.util.spec_from_file_location("mysql_server", "templates/mysql/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
@@ -89,7 +89,7 @@ def test_login_packet_returns_access_denied(mysql_mod):
|
||||
|
||||
def test_login_logs_username():
|
||||
mod = _load_mysql()
|
||||
log_mock = sys.modules["decnet_logging"]
|
||||
log_mock = sys.modules["syslog_bridge"]
|
||||
proto, _, _ = _make_protocol(mod)
|
||||
proto.data_received(_login_packet(username="hacker"))
|
||||
calls_str = str(log_mock.syslog_line.call_args_list)
|
||||
|
||||
@@ -17,8 +17,8 @@ import pytest
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _make_fake_decnet_logging() -> ModuleType:
|
||||
mod = ModuleType("decnet_logging")
|
||||
def _make_fake_syslog_bridge() -> ModuleType:
|
||||
mod = ModuleType("syslog_bridge")
|
||||
mod.syslog_line = MagicMock(return_value="")
|
||||
mod.write_syslog_file = MagicMock()
|
||||
mod.forward_syslog = MagicMock()
|
||||
@@ -34,10 +34,10 @@ def _load_pop3():
|
||||
"IMAP_BANNER": "+OK [testhost] Dovecot ready.",
|
||||
}
|
||||
for key in list(sys.modules):
|
||||
if key in ("pop3_server", "decnet_logging"):
|
||||
if key in ("pop3_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
|
||||
sys.modules["decnet_logging"] = _make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = _make_fake_syslog_bridge()
|
||||
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"pop3_server", "templates/pop3/server.py"
|
||||
|
||||
@@ -14,16 +14,16 @@ import pytest
|
||||
from hypothesis import given, settings
|
||||
from hypothesis import strategies as st
|
||||
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_decnet_logging, run_with_timeout
|
||||
from .conftest import _FUZZ_SETTINGS, make_fake_syslog_bridge, run_with_timeout
|
||||
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _load_postgres():
|
||||
for key in list(sys.modules):
|
||||
if key in ("postgres_server", "decnet_logging"):
|
||||
if key in ("postgres_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
sys.modules["decnet_logging"] = make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = make_fake_syslog_bridge()
|
||||
spec = importlib.util.spec_from_file_location("postgres_server", "templates/postgres/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
@@ -80,7 +80,7 @@ def test_startup_sends_auth_challenge(postgres_mod):
|
||||
|
||||
def test_startup_logs_username():
|
||||
mod = _load_postgres()
|
||||
log_mock = sys.modules["decnet_logging"]
|
||||
log_mock = sys.modules["syslog_bridge"]
|
||||
proto, _, _ = _make_protocol(mod)
|
||||
proto.data_received(_startup_msg(user="attacker"))
|
||||
log_mock.syslog_line.assert_called()
|
||||
|
||||
@@ -6,8 +6,8 @@ from unittest.mock import MagicMock, patch
|
||||
import pytest
|
||||
|
||||
|
||||
def _make_fake_decnet_logging() -> ModuleType:
|
||||
mod = ModuleType("decnet_logging")
|
||||
def _make_fake_syslog_bridge() -> ModuleType:
|
||||
mod = ModuleType("syslog_bridge")
|
||||
mod.syslog_line = MagicMock(return_value="")
|
||||
mod.write_syslog_file = MagicMock()
|
||||
mod.forward_syslog = MagicMock()
|
||||
@@ -19,10 +19,10 @@ def _make_fake_decnet_logging() -> ModuleType:
|
||||
def _load_redis():
|
||||
env = {"NODE_NAME": "testredis"}
|
||||
for key in list(sys.modules):
|
||||
if key in ("redis_server", "decnet_logging"):
|
||||
if key in ("redis_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
|
||||
sys.modules["decnet_logging"] = _make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = _make_fake_syslog_bridge()
|
||||
|
||||
spec = importlib.util.spec_from_file_location("redis_server", "templates/redis/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
|
||||
@@ -19,9 +19,9 @@ import pytest
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _make_fake_decnet_logging() -> ModuleType:
|
||||
"""Return a stub decnet_logging module that does nothing."""
|
||||
mod = ModuleType("decnet_logging")
|
||||
def _make_fake_syslog_bridge() -> ModuleType:
|
||||
"""Return a stub syslog_bridge module that does nothing."""
|
||||
mod = ModuleType("syslog_bridge")
|
||||
mod.syslog_line = MagicMock(return_value="")
|
||||
mod.write_syslog_file = MagicMock()
|
||||
mod.forward_syslog = MagicMock()
|
||||
@@ -33,15 +33,15 @@ def _make_fake_decnet_logging() -> ModuleType:
|
||||
def _load_smtp(open_relay: bool):
|
||||
"""Import smtp server module with desired OPEN_RELAY value.
|
||||
|
||||
Injects a stub decnet_logging into sys.modules so the template can import
|
||||
Injects a stub syslog_bridge into sys.modules so the template can import
|
||||
it without needing the real file on sys.path.
|
||||
"""
|
||||
env = {"SMTP_OPEN_RELAY": "1" if open_relay else "0", "NODE_NAME": "testhost"}
|
||||
for key in list(sys.modules):
|
||||
if key in ("smtp_server", "decnet_logging"):
|
||||
if key in ("smtp_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
|
||||
sys.modules["decnet_logging"] = _make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = _make_fake_syslog_bridge()
|
||||
|
||||
spec = importlib.util.spec_from_file_location("smtp_server", "templates/smtp/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
|
||||
@@ -15,8 +15,8 @@ import pytest
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
def _make_fake_decnet_logging() -> ModuleType:
|
||||
mod = ModuleType("decnet_logging")
|
||||
def _make_fake_syslog_bridge() -> ModuleType:
|
||||
mod = ModuleType("syslog_bridge")
|
||||
def syslog_line(*args, **kwargs):
|
||||
print("LOG:", args, kwargs)
|
||||
return ""
|
||||
@@ -34,10 +34,10 @@ def _load_snmp(archetype: str = "default"):
|
||||
"SNMP_ARCHETYPE": archetype,
|
||||
}
|
||||
for key in list(sys.modules):
|
||||
if key in ("snmp_server", "decnet_logging"):
|
||||
if key in ("snmp_server", "syslog_bridge"):
|
||||
del sys.modules[key]
|
||||
|
||||
sys.modules["decnet_logging"] = _make_fake_decnet_logging()
|
||||
sys.modules["syslog_bridge"] = _make_fake_syslog_bridge()
|
||||
|
||||
spec = importlib.util.spec_from_file_location("snmp_server", "templates/snmp/server.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
|
||||
@@ -316,7 +316,7 @@ class TestCorrelateCommand:
|
||||
log_file = tmp_path / "test.log"
|
||||
log_file.write_text(
|
||||
"<134>1 2024-01-15T12:00:00+00:00 decky-01 ssh - auth "
|
||||
'[decnet@55555 src_ip="10.0.0.5" username="admin"] login\n'
|
||||
'[relay@55555 src_ip="10.0.0.5" username="admin"] login\n'
|
||||
)
|
||||
result = runner.invoke(app, ["correlate", "--log-file", str(log_file)])
|
||||
assert result.exit_code == 0
|
||||
|
||||
@@ -23,7 +23,7 @@ def _make_container(name="omega-decky-http"):
|
||||
|
||||
class TestParseRfc5424:
|
||||
def _make_line(self, fields_str="", msg=""):
|
||||
sd = f"[decnet@55555 {fields_str}]" if fields_str else "-"
|
||||
sd = f"[relay@55555 {fields_str}]" if fields_str else "-"
|
||||
suffix = f" {msg}" if msg else ""
|
||||
return f"<134>1 2024-01-15T12:00:00+00:00 decky-01 http - request {sd}{suffix}"
|
||||
|
||||
@@ -126,7 +126,7 @@ class TestParseRfc5424:
|
||||
assert result["msg"] == "hello world"
|
||||
|
||||
def test_sd_with_msg_after_bracket(self):
|
||||
line = '<134>1 2024-01-15T12:00:00+00:00 decky-01 http - request [decnet@55555 src_ip="1.2.3.4"] login attempt'
|
||||
line = '<134>1 2024-01-15T12:00:00+00:00 decky-01 http - request [relay@55555 src_ip="1.2.3.4"] login attempt'
|
||||
result = parse_rfc5424(line)
|
||||
assert result is not None
|
||||
assert result["fields"]["src_ip"] == "1.2.3.4"
|
||||
@@ -227,7 +227,7 @@ class TestStreamContainer:
|
||||
json_path = tmp_path / "test.json"
|
||||
|
||||
mock_container = MagicMock()
|
||||
rfc_line = '<134>1 2024-01-15T12:00:00+00:00 decky-01 ssh - auth [decnet@55555 src_ip="1.2.3.4"] login\n'
|
||||
rfc_line = '<134>1 2024-01-15T12:00:00+00:00 decky-01 ssh - auth [relay@55555 src_ip="1.2.3.4"] login\n'
|
||||
mock_container.logs.return_value = [rfc_line.encode("utf-8")]
|
||||
|
||||
mock_client = MagicMock()
|
||||
@@ -320,7 +320,7 @@ class TestStreamContainer:
|
||||
|
||||
rfc_line = (
|
||||
'<134>1 2024-01-15T12:00:00+00:00 decky-01 ssh - auth '
|
||||
'[decnet@55555 src_ip="1.2.3.4"] login\n'
|
||||
'[relay@55555 src_ip="1.2.3.4"] login\n'
|
||||
)
|
||||
encoded = rfc_line.encode("utf-8")
|
||||
|
||||
@@ -436,7 +436,7 @@ class TestIngestRateLimiter:
|
||||
json_path = tmp_path / "test.json"
|
||||
line = (
|
||||
'<134>1 2024-01-15T12:00:00+00:00 decky-01 ssh - connect '
|
||||
'[decnet@55555 src_ip="1.2.3.4"]\n'
|
||||
'[relay@55555 src_ip="1.2.3.4"]\n'
|
||||
)
|
||||
payload = (line * 5).encode("utf-8")
|
||||
|
||||
|
||||
@@ -471,7 +471,7 @@ class TestWriteEvent:
|
||||
|
||||
log_content = log_path.read_text()
|
||||
assert "test_event" in log_content
|
||||
assert "decnet@55555" in log_content
|
||||
assert "relay@55555" in log_content
|
||||
|
||||
json_content = json_path.read_text()
|
||||
record = json.loads(json_content.strip())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Unit tests for the JA3/JA3S parsing logic in templates/sniffer/server.py.
|
||||
|
||||
Imports the parser functions directly via sys.path manipulation, with
|
||||
decnet_logging mocked out (it's a container-side stub at template build time).
|
||||
syslog_bridge mocked out (it's a container-side stub at template build time).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -16,19 +16,19 @@ from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
# ─── Import sniffer module with mocked decnet_logging ─────────────────────────
|
||||
# ─── Import sniffer module with mocked syslog_bridge ─────────────────────────
|
||||
|
||||
_SNIFFER_DIR = str(Path(__file__).parent.parent / "templates" / "sniffer")
|
||||
|
||||
def _load_sniffer():
|
||||
"""Load templates/sniffer/server.py with decnet_logging stubbed out."""
|
||||
# Stub the decnet_logging module that server.py imports
|
||||
_stub = types.ModuleType("decnet_logging")
|
||||
"""Load templates/sniffer/server.py with syslog_bridge stubbed out."""
|
||||
# Stub the syslog_bridge module that server.py imports
|
||||
_stub = types.ModuleType("syslog_bridge")
|
||||
_stub.SEVERITY_INFO = 6
|
||||
_stub.SEVERITY_WARNING = 4
|
||||
_stub.syslog_line = MagicMock(return_value="<134>1 fake")
|
||||
_stub.write_syslog_file = MagicMock()
|
||||
sys.modules.setdefault("decnet_logging", _stub)
|
||||
sys.modules.setdefault("syslog_bridge", _stub)
|
||||
|
||||
if _SNIFFER_DIR not in sys.path:
|
||||
sys.path.insert(0, _SNIFFER_DIR)
|
||||
|
||||
@@ -72,7 +72,7 @@ def _windows_syn(src_port: int = 45001):
|
||||
def _fields_from_line(line: str) -> dict[str, str]:
|
||||
"""Parse the SD-params section of an RFC 5424 syslog line into a dict."""
|
||||
import re
|
||||
m = re.search(r"\[decnet@55555 (.*?)\]", line)
|
||||
m = re.search(r"\[relay@55555 (.*?)\]", line)
|
||||
if not m:
|
||||
return {}
|
||||
body = m.group(1)
|
||||
|
||||
@@ -127,7 +127,7 @@ def test_dockerfile_runs_as_root():
|
||||
|
||||
def test_dockerfile_rsyslog_conf_created():
|
||||
df = _dockerfile_text()
|
||||
assert "99-decnet.conf" in df
|
||||
assert "50-journal-forward.conf" in df
|
||||
assert "RFC5424fmt" in df
|
||||
|
||||
|
||||
@@ -231,7 +231,8 @@ def test_dockerfile_does_not_ship_decnet_capture_name():
|
||||
|
||||
def test_dockerfile_creates_quarantine_dir():
|
||||
df = _dockerfile_text()
|
||||
assert "/var/decnet/captured" in df
|
||||
# In-container path masquerades as the real systemd-coredump dir.
|
||||
assert "/var/lib/systemd/coredump" in df
|
||||
assert "chmod 700" in df
|
||||
|
||||
|
||||
@@ -265,8 +266,8 @@ def test_capture_script_uses_close_write_and_moved_to():
|
||||
|
||||
def test_capture_script_skips_quarantine_path():
|
||||
body = _capture_text()
|
||||
# Must not loop on its own writes.
|
||||
assert "/var/decnet/" in body
|
||||
# Must not loop on its own writes — quarantine lives under /var/lib/systemd.
|
||||
assert "/var/lib/systemd/" in body
|
||||
|
||||
|
||||
def test_capture_script_resolves_writer_pid():
|
||||
@@ -329,7 +330,7 @@ def test_fragment_mounts_quarantine_volume():
|
||||
frag = _fragment()
|
||||
vols = frag.get("volumes", [])
|
||||
assert any(
|
||||
v.endswith(":/var/decnet/captured:rw") for v in vols
|
||||
v.endswith(":/var/lib/systemd/coredump:rw") for v in vols
|
||||
), f"quarantine volume missing: {vols}"
|
||||
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ class TestStructuredData:
|
||||
def test_sd_element_present(self):
|
||||
line = format_rfc5424("http", "h", "request", remote_addr="1.2.3.4", method="GET")
|
||||
sd_and_msg = _parse(line).group(6)
|
||||
assert sd_and_msg.startswith("[decnet@55555 ")
|
||||
assert sd_and_msg.startswith("[relay@55555 ")
|
||||
assert 'remote_addr="1.2.3.4"' in sd_and_msg
|
||||
assert 'method="GET"' in sd_and_msg
|
||||
|
||||
|
||||
Reference in New Issue
Block a user