Correct two firewall claims the runtime test disproved

FIREWALL_INPUT_PORTS does not open the app ports inside a pod network. gluetun
detects the pod's own subnet and inserts an INPUT accept for it ahead of the
per-port rules, and every packet arriving at the pod IP matches that rule by
destination. Measured with the packet counters: 50 fresh requests moved the
subnet rule from 306 to 356 packets while every --dport rule stayed at 0 since
container start. A port that listens but is not in the list (gluetun's control
server on 8000) is reachable from another pod all the same.

The variable is kept - it is the explicit statement of which ports are meant to
be reachable, and the subnet detection is gluetun's behaviour rather than a
guarantee of this chart - but the comments no longer claim the traffic would be
dropped without it.

Second correction, same run: the /tmp/gluetun emptyDir fixed the "open ...
permission denied" failure, but gluetun also chowns the file, which needs
CAP_CHOWN. With all capabilities but NET_ADMIN dropped that logs "chown
/tmp/gluetun/ip: operation not permitted" on every VPN restart. The file is
written and the public IP is persisted, so this is a log line rather than a
failure, and granting CHOWN to silence it would widen the container's
capabilities for nothing. Noted where the mount is declared.
This commit is contained in:
jklein committed 2026-08-24 14:38:03 +02:00
1 parent bc6577f321
commit e4f70bc856
2 files changed
+26 -5

No files matched your search

+14 -3
View File
@@ -133,9 +133,12 @@ spec:
- name: FIREWALL_OUTBOUND_SUBNETS
value: {{ . | quote }}
{{- end }}
# Open the firewall for the UI/probe ports of the enabled apps and
# the health server - kubelet probes and ingress traffic arrive on
# the pod IP and would be dropped otherwise.
# Declare the UI/probe ports of the enabled apps and the health
# server as reachable. Note that inside a pod network gluetun's own
# pod-subnet rule already accepts this traffic and these per-port
# rules never match (measured - see the helper's comment); they are
# the explicit statement of intent and the fallback if that subnet
# detection ever stops covering the pod IP.
- name: FIREWALL_INPUT_PORTS
value: {{ include "freesailarr.firewallInputPorts" . | quote }}
# Bind the health server to all interfaces so the kubelet HTTP
@@ -169,6 +172,14 @@ spec:
# and every write fails with "clearing public IP data: open
# /tmp/gluetun/ip: permission denied". An emptyDir provides the
# path with usable permissions.
# Remaining, cosmetic: gluetun also chowns the file, which needs
# CAP_CHOWN. With all capabilities but NET_ADMIN dropped that call
# is denied and logs "clearing public IP data: chown
# /tmp/gluetun/ip: operation not permitted" on every VPN restart.
# The file itself is written and the public IP is persisted
# (verified at runtime), so this is a log line, not a failure -
# granting CHOWN just to silence it would widen the container's
# capabilities for nothing.
- mountPath: /tmp/gluetun
name: gluetun-tmp
{{- if .Values.qbittorrent.enabled }}