rss-bridge: pin the unprivileged-port sysctl, quote env values
Follow-up to the template-chart hardening fixes in #133, which landed while this branch was open. The env block now quotes names, values and keyRef fields. Without it a value like "5" renders as a YAML number and the API server rejects the whole manifest. RSS-Bridge takes numeric settings that way (RSSBRIDGE_http_timeout), so this was reachable with the first env entry anyone adds. The port-80 question is settled by measurement rather than by the "it works in k3d" reasoning #133 warns about. Same pod spec in k3d (k3s v1.35.5), only ip_unprivileged_port_start changed: 1024, capabilities.drop [ALL] nginx: bind() to 0.0.0.0:80 failed (13: Permission denied) 1024, plus NET_BIND_SERVICE identical failure - for a non-root process the capability lands in the permitted but not the effective set, so it buys nothing 0 binds, HTTP 200 So the chart cannot buy safety with a capability the way samba does, and port 80 is not negotiable either: nginx is configured for it inside the image and the entrypoint's only lever is a sed against a read-only /etc/nginx. What it can do is stop depending on the node default - the pod securityContext now pins the sysctl to 0, so the bind no longer relies on cluster configuration. Verified: the chart-installed pod reports 0 and answers 200 through the Service. Worth recording how that failure looks without probes: the entrypoint backgrounds nginx and then execs php-fpm, so a failed bind leaves a container reporting Running with no web server at all. Both test pods above were Running. The probes on /?action=health are what turn it into a pod that never becomes Ready. trivy config still reports 0 to act on; the KSV-0117 statement is updated to the measured reasoning.
This commit is contained in:
4 files changed
+53
-10
No files matched your search
@@ -198,6 +198,10 @@ Two chart-specific facts a rebuilt default must not lose:
|
||||
everything in it owned by www-data, and both nginx and php-fpm are
|
||||
configured for that user. A "cleaner" high uid would leave the app unable
|
||||
to read its own bridge sources.
|
||||
- the ip_unprivileged_port_start sysctl is what lets a non-root nginx bind
|
||||
port 80, and this chart has no choice about that port - see the comment on
|
||||
it in values.yaml. Dropping it from a rebuilt default does not fail at
|
||||
render time; it fails on the first node whose default differs.
|
||||
- the probes address the port BY NAME (rss-bridge-port) and use the app's
|
||||
own health action. A default that drops the query string would probe the
|
||||
1.5 MB front page instead of a 49-byte JSON response, and a default that
|
||||
@@ -211,7 +215,8 @@ Two chart-specific facts a rebuilt default must not lose:
|
||||
"runAsGroup" 33
|
||||
"fsGroup" 33
|
||||
"fsGroupChangePolicy" "Always"
|
||||
"seccompProfile" (dict "type" "RuntimeDefault") -}}
|
||||
"seccompProfile" (dict "type" "RuntimeDefault")
|
||||
"sysctls" (list (dict "name" "net.ipv4.ip_unprivileged_port_start" "value" "0")) -}}
|
||||
{{- include "rss-bridge.defaultedDict" (dict "defaults" $defaults "given" $given "path" "rssBridge.securityContext.pod") -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
Reference in new issue
Block a user