fix(paperless-ngx): egress names the Tika/Gotenberg POD ports, not the Service port

The rule allowed outbound 80, the port the apache-tika and gotenberg Services
listen on, and justified it in a comment: an egress rule names the port on the
destination as the client dials it, and the client dials the Service. That is
wrong. kube-proxy does a ClusterIP Service's destination NAT BEFORE the egress
policy is evaluated at the pod's network interface, so the policy sees
podIP:targetPort and never clusterIP:port - and those two charts forward 80 to
9998 and 3000. Deployed as 14.0.0+up3.3.1 it cut Paperless off from both
services on 2026-10-15: mail import, EML, HTML and Office documents stopped,
plain PDFs and images kept working, and the error was httpx.ConnectTimeout with
no mention of a NetworkPolicy.

The rule now names 9998, 3000 and 80. The 80 stays because it costs nothing and
covers a foreign Tika that really does listen on 80. The refuted sentence is
quoted rather than deleted: it reads perfectly, which is how it survived review,
and the timeout-not-refused symptom is written down with it.

No policy switch of its own: the rule stays gated on
paperless.files.tikaGotenberg.enabled, because a second value that can drift
from the feature re-arms this very outage.

New networkPolicy.egress.mailImport opens IMAPS 993, off by default - paperless'
mail accounts are rows in its database, so the chart cannot derive the rule.
Plain IMAP (143) and POP3 stay in extraPorts, and 993 is noted as a real
destination port, because a mail server outside the cluster has no DNAT in the
path.

Minor: one additive value, and a fix that widens a rule. Nothing breaks, no
value becomes required, appVersion unchanged.

Part of #136
This commit is contained in:
jklein committed 2026-10-15 17:39:24 +00:00
1 parent 1ef23e9ce9
commit 530227405c
5 files changed
+168 -43

No files matched your search

+22 -4
View File
@@ -536,14 +536,32 @@ BACKUP IS TWO THINGS AT THE SAME TIME
NETWORKPOLICY IS ACTIVE — WHAT IT CAPS, AND WHAT IT DOES NOT
{{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy selects this workload's pods.
Inbound: TCP 8000 only. Outbound: DNS, TCP 5432 (Postgres), 6379
(Redis/Valkey), 443{{ if .Values.paperless.files.tikaGotenberg.enabled }}, 80 (the Tika and Gotenberg Services){{ end }}{{ with .Values.networkPolicy.egress }}{{ with .extraPorts }}, plus TCP
(Redis/Valkey), 443{{ if .Values.paperless.files.tikaGotenberg.enabled }}, 9998 and 3000 (the Tika and Gotenberg POD ports) plus 80{{ end }}{{ with .Values.networkPolicy.egress }}{{ if .mailImport }}, 993 (IMAPS, mail import){{ end }}{{ with .extraPorts }}, plus TCP
{{ join ", " . }}{{ end }}{{ end }}.
{{- if .Values.paperless.files.tikaGotenberg.enabled }}
THE TIKA/GOTENBERG RULE NAMES POD PORTS, AND THAT IS THE FIX FROM GITEA #136.
It named the Services' 80 alone until chart 14.1.0, which cut Paperless off
from both services: kube-proxy does a ClusterIP Service's destination NAT
BEFORE the egress policy is evaluated at the pod's interface, so the policy
sees podIP:targetPort. The symptom was a TIMEOUT and not "connection refused",
and no error mentioned a NetworkPolicy. If this release reaches a Tika or
Gotenberg that listens on some other port, that port goes into
networkPolicy.egress.extraPorts.
{{- end }}
{{- if (.Values.networkPolicy.egress).mailImport }}
MAIL IMPORT IS PERMITTED on 993 (IMAPS), because
networkPolicy.egress.mailImport is on. Plain IMAP (143) and POP3 are NOT
covered — add them to networkPolicy.egress.extraPorts if an account uses them.
{{- else }}
MAIL FETCHING IS NOT PERMITTED. Paperless' mail accounts are rows in its
database, configured in the web UI, so this chart cannot see them. A release
that fetches mail needs IMAP (993, or 143) in
networkPolicy.egress.extraPorts — otherwise a mail rule silently stops
importing, with a healthy pod behind it.
that fetches mail needs networkPolicy.egress.mailImport: true for IMAPS (993),
or 143/POP3 in networkPolicy.egress.extraPorts — otherwise a mail rule
silently stops importing, with a healthy pod behind it.
{{- end }}
AND TWO PODS OF THIS RELEASE ARE NOT COVERED BY THIS OBJECT:
- the valkey subchart's pod, which carries its own labels. It needs no