fix(security): add missing FOWNER and DAC_OVERRIDE capabilities
The security hardening in v2.30.0 drops all container capabilities and re-adds a minimal set. The set was missing FOWNER and DAC_OVERRIDE which database containers (postgres, mysql, mariadb) need to chmod/traverse their data directories during entrypoint init when files are owned by the service user (e.g. UID 999) and the entrypoint runs as root. Without these, all DB attachment containers fail after a reboot with: chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted find: '/var/lib/postgresql/data': Permission denied
- commit
- 1983e1bb00a425b547b3d692b014cde531b152e8
- author
- brice · · 2026-03-29 06:26 UTC
- parent
- 3ef732b
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email - refs
- tag: v2.30.1
1 file · +5 -3
M internal/adapters/out/docker/runtime.go +5 -3
| @@ -182,9 +182,11 @@ func (r *Runtime) CreateContainer(ctx context.Context, config *domain.ContainerC | |||
| 182 | 182 | SecurityOpt: []string{"no-new-privileges:true"}, | |
| 183 | 183 | CapDrop: strslice.StrSlice{"ALL"}, | |
| 184 | 184 | // Re-add the minimal set of capabilities that standard images need. | |
| 185 | - | // Without these, containers that chown files (e.g. postgres, mysql) | |
| 186 | - | // or bind to ports <1024 (e.g. nginx) would fail to start. | |
| 187 | - | CapAdd: strslice.StrSlice{"CHOWN", "SETUID", "SETGID", "NET_BIND_SERVICE"}, | |
| 185 | + | // CHOWN/FOWNER/DAC_OVERRIDE: postgres, mysql etc. chown/chmod data dirs | |
| 186 | + | // owned by their service user during entrypoint init. | |
| 187 | + | // SETUID/SETGID: gosu/su-exec to drop privileges after init. | |
| 188 | + | // NET_BIND_SERVICE: nginx etc. binding to ports < 1024. | |
| 189 | + | CapAdd: strslice.StrSlice{"CHOWN", "DAC_OVERRIDE", "FOWNER", "SETUID", "SETGID", "NET_BIND_SERVICE"}, | |
| 188 | 190 | } | |
| 189 | 191 | ||
| 190 | 192 | // Create network configuration for container | |
| @@ -182,9 +182,11 @@ func (r *Runtime) CreateContainer(ctx context.Context, config *domain.ContainerC | |||||
| 182 | SecurityOpt: []string{"no-new-privileges:true"}, | 182 | SecurityOpt: []string{"no-new-privileges:true"}, | ||
| 183 | CapDrop: strslice.StrSlice{"ALL"}, | 183 | CapDrop: strslice.StrSlice{"ALL"}, | ||
| 184 | // Re-add the minimal set of capabilities that standard images need. | 184 | // Re-add the minimal set of capabilities that standard images need. | ||
| 185 | - | // Without these, containers that chown files (e.g. postgres, mysql) | 185 | + | // CHOWN/FOWNER/DAC_OVERRIDE: postgres, mysql etc. chown/chmod data dirs |
| 186 | - | // or bind to ports <1024 (e.g. nginx) would fail to start. | 186 | + | // owned by their service user during entrypoint init. |
| 187 | - | CapAdd: strslice.StrSlice{"CHOWN", "SETUID", "SETGID", "NET_BIND_SERVICE"}, | 187 | + | // SETUID/SETGID: gosu/su-exec to drop privileges after init. |
| 188 | + | // NET_BIND_SERVICE: nginx etc. binding to ports < 1024. | |||
| 189 | + | CapAdd: strslice.StrSlice{"CHOWN", "DAC_OVERRIDE", "FOWNER", "SETUID", "SETGID", "NET_BIND_SERVICE"}, | |||
| 188 | } | 190 | } | ||
| 189 | 191 | ||||
| 190 | // Create network configuration for container | 192 | // Create network configuration for container | ||