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:
@@ -111,6 +111,9 @@ func TestE2E(t *testing.T) {
|
||||
if err := checkPostfixHardening(h); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := checkPidsLimit(h); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := checkInboundRelayOff(h); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -146,6 +146,19 @@ func checkDKIMTree(s *stack) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkPidsLimit reads the container's process ceiling back from the kernel:
|
||||
// the shipped compose sets pids_limit (security audit 2026-10-17, I3).
|
||||
func checkPidsLimit(s *stack) error {
|
||||
out, err := s.execIn("selfpost", "cat", "/sys/fs/cgroup/pids.max")
|
||||
if err != nil {
|
||||
return fmt.Errorf("read pids.max: %v\n%s", err, out)
|
||||
}
|
||||
if got := strings.TrimSpace(out); got != "1024" {
|
||||
return fmt.Errorf("the container's pids.max is %q, want the compose file's 1024", got)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkPostfixHardening reads back what postfix-config.sh sets against
|
||||
// downgrade and enumeration (audit 2026-10-12, L31).
|
||||
func checkPostfixHardening(s *stack) error {
|
||||
|
||||
Reference in New Issue
Block a user