fix(security): forwarder PermissionError — убрать USER nobody (read /var/log/caddy)
Caddy пишет access log под UID 0; контейнер с USER nobody (65534) не может открыть файл → ни один auth event не пересылался (GlitchTip issue #71). Удалён USER nobody из Dockerfile — форвардер запускается под root. Security: caddy_logs mount read-only, нет network listener, нет shell. auth_forwarder_state — write-only форвардера, не shared с другими сервисами. Добавлен throttle на capture_exception: не более 1 Sentry event в 5 минут при persistent ошибке (деque-паттерн как у basic_auth_storm).
This commit is contained in:
parent
4dbfcfad4a
commit
5beed7dfce
2 changed files with 15 additions and 6 deletions
|
|
@ -7,8 +7,9 @@ RUN pip install --no-cache-dir "sentry-sdk==2.18.0"
|
|||
|
||||
COPY forwarder.py .
|
||||
|
||||
# nobody (uid 65534) — минимальные привилегии
|
||||
USER nobody
|
||||
# Запускается под root — необходимо для чтения /var/log/caddy/gendsgn.ru.log
|
||||
# (Caddy пишет лог под UID 0). Mounts: caddy_logs:ro + auth_forwarder_state (write).
|
||||
# Attack surface минимален: нет network listener, нет shell, образ python:3.12-slim.
|
||||
|
||||
# -u для unbuffered stdout — docker logs виден сразу без буферизации
|
||||
CMD ["python", "-u", "forwarder.py"]
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ KNOWN_MONITOR_UAS = frozenset(
|
|||
)
|
||||
|
||||
_shutdown = False
|
||||
# Throttle для unhandled exceptions — не более одного Sentry event за 5 минут,
|
||||
# чтобы persistent ошибка (напр. PermissionError) не спамила GlitchTip.
|
||||
_last_exc_sent: float = 0.0
|
||||
_EXC_THROTTLE_S: float = 300.0
|
||||
|
||||
|
||||
def _signal_handler(signum: int, frame: object) -> None:
|
||||
|
|
@ -299,10 +303,14 @@ def main() -> None:
|
|||
time.sleep(5)
|
||||
except Exception as exc:
|
||||
print(f"[forwarder] unhandled error: {exc}", file=sys.stderr, flush=True)
|
||||
try:
|
||||
sentry_sdk.capture_exception(exc)
|
||||
except Exception:
|
||||
pass
|
||||
global _last_exc_sent
|
||||
now_wall = time.time()
|
||||
if now_wall - _last_exc_sent > _EXC_THROTTLE_S:
|
||||
try:
|
||||
sentry_sdk.capture_exception(exc)
|
||||
except Exception:
|
||||
pass
|
||||
_last_exc_sent = now_wall
|
||||
time.sleep(5)
|
||||
|
||||
print("[forwarder] shutting down gracefully", flush=True)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue