deploy: a process ceiling on every container (audit I3)

Security audit 2026-10-17, finding I3 (low), stage 4. No compose file set
pids_limit: a fork bomb from a compromised panel or postfix had the host's
pid space as its limit. Now 1024 for SelfPost - the plan said 512, but
Postfix starts up to default_process_limit (100) processes per service,
and a busy server runs three smtpd services, cleanup and smtp at once -
256 for nginx, Caddy, Traefik and rspamd, 64 for certbot. The comment that
said root runs "very briefly" now says which root processes stay.

e2e: checkPidsLimit reads /sys/fs/cgroup/pids.max in the container.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-17 22:19:36 +03:00
co-authored by Claude Opus 5.5
parent a327962008
commit dd950364a3
9 changed files with 44 additions and 6 deletions
@@ -32,6 +32,8 @@ services:
# (its Dockerfile, USER 11333:11333).
image: rspamd/rspamd:3.11.1-3
restart: unless-stopped
# A ceiling on processes and threads (security audit 2026-10-17, I3).
pids_limit: 256
# No host ports: only SelfPost talks to the milter on the compose network.
volumes:
# The verdict headers SelfPost's inbound journal reads.
+2
View File
@@ -48,6 +48,8 @@ services:
caddy:
image: caddy:2
restart: unless-stopped
# A ceiling on processes and threads (security audit 2026-10-17, I3).
pids_limit: 256
depends_on:
- selfpost
ports:
+12 -4
View File
@@ -99,10 +99,12 @@ services:
# when the variable is true.
- "25:25"
- "127.0.0.1:8080:8080"
# Hardening. SelfPost's entrypoint still needs to run as
# root very briefly to fix /data ownership and normalise permissions
# under the shared `selfpost` group (see build/entrypoint.sh) before
# supervisord drops the panel to an unprivileged user — so this cannot be
# Hardening. SelfPost's entrypoint runs as root to fix /data ownership
# and normalise permissions under the shared `selfpost` group (see
# build/entrypoint.sh) before supervisord drops the panel to an
# unprivileged user; supervisord, Postfix's master, cert-reload and
# logrotate stay root for the container's life, which is inherent to
# them (security audit 2026-10-17, I3) — so this cannot be
# `user: panel` or a fully read-only rootfs without breaking that startup
# self-healing. What IS applied: no privilege escalation past what the
# image already grants, and every Linux capability dropped except the
@@ -151,3 +153,9 @@ services:
- SETGID
- DAC_OVERRIDE
- KILL
# A ceiling on processes and threads, so that a runaway or compromised
# program cannot use up the host's (security audit 2026-10-17, I3).
# Postfix starts up to 100 processes per service by default
# (default_process_limit), and a busy server runs three smtpd services,
# cleanup and smtp at once; 1024 leaves them room.
pids_limit: 1024
+3
View File
@@ -47,6 +47,8 @@ services:
nginx:
image: nginx:1.27
restart: unless-stopped
# A ceiling on processes and threads (security audit 2026-10-17, I3).
pids_limit: 256
depends_on:
- selfpost
ports:
@@ -59,6 +61,7 @@ services:
certbot:
image: certbot/certbot:latest
pids_limit: 64
volumes:
- ./nginx/certbot-etc:/etc/letsencrypt
- ./nginx/certbot-www:/var/www/certbot
@@ -40,6 +40,8 @@ services:
traefik:
image: traefik:v3.1
restart: unless-stopped
# A ceiling on processes and threads (security audit 2026-10-17, I3).
pids_limit: 256
depends_on:
- selfpost
command: