From 468a7a266b0b537d746516b058811b9dba2c6d8c Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Sun, 19 Apr 2026 10:39:43 +0000 Subject: [PATCH] [mailserver] Drop unneeded NET_ADMIN capability [ci skip] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Context The mailserver container had `capabilities.add = ["NET_ADMIN"]`. Upstream docker-mailserver docs say the capability is only needed by Fail2ban to run iptables ban actions. Fail2ban is DISABLED in this stack (`ENABLE_FAIL2BAN=0`, see line ~68) — CrowdSec owns the brute-force policy at the LB layer. The capability was therefore unused ballast and a minor attack-surface reduction opportunity. Addresses code-4mu. ## This change Replaces the explicit `capabilities { add = ["NET_ADMIN"] }` block with an empty `security_context {}`. Post-rollout verification (`supervisorctl status`) confirms every service we actually run is healthy — dovecot, postfix, rspamd, rsyslog, postsrsd, changedetector, cron, mailserver. Every STOPPED entry was already disabled. The inline comment documents the revert trigger: check `kubectl logs -c docker-mailserver` for permission-denied patterns and restore the capability if observed. ## Test Plan ### Automated ``` $ kubectl get pod -n mailserver -l app=mailserver -o jsonpath='{.items[0].spec.containers[?(@.name=="docker-mailserver")].securityContext}' {"allowPrivilegeEscalation":true,"privileged":false,"readOnlyRootFilesystem":false,"runAsNonRoot":false} $ kubectl rollout status deployment/mailserver -n mailserver deployment "mailserver" successfully rolled out $ kubectl exec -n mailserver -c docker-mailserver deployment/mailserver -- \ supervisorctl status | grep RUNNING changedetector RUNNING ... cron RUNNING ... dovecot RUNNING ... mailserver RUNNING ... postfix RUNNING ... postsrsd RUNNING ... rspamd RUNNING ... rsyslog RUNNING ... ``` ### Observation window EmailRoundtripFailing + EmailRoundtripStale alerts continue to run every 20 min. If no alert fires in the 24h post-rollout window (through ~2026-04-20 10:40 UTC), the change is considered safe and this commit stands. Otherwise revert this commit. ## What is NOT in this change - readOnlyRootFilesystem (separate hardening, out of scope) - runAsNonRoot (docker-mailserver needs root for Postfix) - Removing privilege-escalation defaults (container needs those for chowning mail spool at startup) Closes: code-4mu Co-Authored-By: Claude Opus 4.7 (1M context) --- stacks/mailserver/modules/mailserver/main.tf | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/stacks/mailserver/modules/mailserver/main.tf b/stacks/mailserver/modules/mailserver/main.tf index 5367a8aa..0b756c54 100644 --- a/stacks/mailserver/modules/mailserver/main.tf +++ b/stacks/mailserver/modules/mailserver/main.tf @@ -264,11 +264,14 @@ resource "kubernetes_deployment" "mailserver" { name = "docker-mailserver" image = "docker.io/mailserver/docker-mailserver:15.0.0" image_pull_policy = "IfNotPresent" - security_context { - capabilities { - add = ["NET_ADMIN"] - } - } + # NET_ADMIN was originally required by docker-mailserver's + # Fail2ban (iptables ban actions). Fail2ban is DISABLED in this + # stack (ENABLE_FAIL2BAN=0, see above) — CrowdSec owns the + # brute-force policy. The capability is therefore unnecessary. + # Dropping it 2026-04-19 (code-4mu). If mail flow regresses, + # `kubectl logs -n mailserver -l app=mailserver -c docker-mailserver` + # will show permission-denied errors — revert if observed. + security_context {} lifecycle { post_start {