feat(smtp_relay): move probe forwarding to realism worker via bus
Attacker probe emails are now forwarded by the master (realism worker) rather than inside the MACVLAN container, which has no internet gateway. - New smtp.probe.pending bus topic: ingester publishes when smtp_relay message_stored fires; worker subscribes and does the actual delivery - decnet/orchestrator/drivers/smtp_relay.py: pure-sync forward_probe() reads the .eml from disk and sends via smtplib on a thread executor - worker.py: _run_smtp_probe_listener + _handle_probe_pending subtask; limit enforced via count_probe_relays() (DB-backed, restart-safe) - bounties.py: count_probe_relays() query on probe_relay bounty type - fleet.py: get_fleet_decky_by_name() to pull service config from DB - services/smtp_relay.py: upstream_* and probe_limit fields defined in config_schema but NOT injected into container env (credentials stay out of docker env vars) - ingester.py: stripped of smtplib; publishes probe.pending and exits - tests: assert upstream keys absent from container environment
This commit is contained in:
@@ -54,6 +54,7 @@ SYSTEM = "system"
|
||||
CREDENTIAL = "credential"
|
||||
ORCHESTRATOR = "orchestrator"
|
||||
CANARY = "canary"
|
||||
SMTP = "smtp"
|
||||
|
||||
|
||||
# ─── Leaf event-type constants (the last segment of each topic) ──────────────
|
||||
@@ -394,6 +395,16 @@ def system_control(worker: str) -> str:
|
||||
return f"{SYSTEM}.{worker}.{SYSTEM_CONTROL}"
|
||||
|
||||
|
||||
def smtp(event_type: str) -> str:
|
||||
"""Build ``smtp.<event_type>``.
|
||||
|
||||
*event_type* may contain dots (e.g. ``probe.pending``).
|
||||
"""
|
||||
if not event_type:
|
||||
raise ValueError("smtp topic requires a non-empty event_type")
|
||||
return f"{SMTP}.{event_type}"
|
||||
|
||||
|
||||
def _reject_tokens(*parts: str) -> None:
|
||||
"""Reject topic segments that would break NATS-style tokenization.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user