fix(security): forwarder PermissionError — убрать USER nobody (read /var/log/caddy) #432
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#432
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/auth-forwarder-permission"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
⚠️ Production hotfix
GlitchTip Issue #71:
После merge PR #430 forwarder запущен в проде, но НЕ работает — падает на open() лог-файла. Ни одного 401 event не отправлено в GlitchTip через sidecar.
Root cause
ops/glitchtip-auth-forwarder/Dockerfile:7—USER nobody(UID 65534).Caddy 2.x создаёт
/var/log/caddy/gendsgn.ru.logпод UID 0 (root). Volumecaddy_logsshared между контейнерами, но permissions файла0640 root:root—nobodyне может прочесть.Variables в stack trace:
file_size: 135276→ лог растёт, Caddy пишетcurrent_size: 351985→ продолжает растиoffset: 0→ forwarder ничего не прочиталFix
Убрать
USER nobodyиз Dockerfile. Forwarder работает под root.Security обоснование
caddy_logs:/var/log/caddy:ro— read-only → root не может писатьauth_forwarder_state:/state— write-only forwarder'а, не sharedGLITCHTIP_DSN(env) не доступныUSER nobodyАльтернативы (отброшены):
Bonus fix: exception throttle
forwarder.py— добавлены_last_exc_sent+_EXC_THROTTLE_S=300s.capture_exceptionв outerexceptне чаще раза в 5 минут. Предотвращает Sentry spam если persistent ошибка повторится (как сейчас с PermissionError — без throttle GlitchTip бы заспамил сотней дубликатов).Changes
ops/glitchtip-auth-forwarder/DockerfileUSER nobody, +2 строки commentops/glitchtip-auth-forwarder/forwarder.pyVerify after merge
После deploy.yml run (или ручного rebuild через
docker compose build glitchtip-auth-forwarder && up -d --force-recreate):Затем trigger тестовый 401:
Issue #71 после fix должен resolve (no new occurrences).
Related
1759158d7eto5beed7dfceMerged via deep-code-reviewer — verdict ✅ APPROVE.
Security trade-off accepted: root inside container OK при текущей конфигурации (caddy_logs read-only mount, нет network listener, минимальный image python:3.12-slim + sentry-sdk, no shell server, depends_on только caddy). Attack surface не растёт значительно vs USER nobody.
Cross-PR finding: deploy.yml automation (PR #431 scope) уже включена в этот PR (commit
4dbfcfa). После mergepaths-filterтеперь покрываетops/glitchtip-auth-forwarder/**→ deploy.yml сработает автоматически на этом merge commit, rebuild+force-recreate sidecar. Ручной SSH шаг не нужен. PR #431 можно закрыть как duplicate.Throttle verified: single-threaded process, module-level
_last_exc_sentthread-safe. Throttle scoped к outerexcept Exceptiononly, не маскирует FileNotFoundError / JSONDecodeError. Первый event всегда отправляется (now - 0.0 > 300⇒ True).Follow-up suggestion (non-blocking, отдельный PR — defence-in-depth):
Это нейтрализует CAP_NET_RAW/CAP_SYS_ADMIN и делает rootfs immutable. Не блокирующее, так как сейчас нет network input → реальный exploit vector минимален.
Verify after deploy completes:
GlitchTip Issue #71 должен auto-resolve после первого успешного цикла tail.