network-policies: agent pods -> shelly-manager API via header-stripping :8081 (REN-931, REN-935) #1161
@@ -123,5 +123,13 @@ configMapGenerator:
|
||||
namespace: home-assistant
|
||||
files:
|
||||
- mqtt-accounts.yaml
|
||||
# shelly-manager api-proxy sidecar config (REN-935). Hash suffix disabled
|
||||
# (name stays stable), so editing shelly-manager-api-proxy.conf does not
|
||||
# auto-roll the pod — restart manually with
|
||||
# `kubectl rollout restart deploy/shelly-manager -n home-assistant`.
|
||||
- name: shelly-manager-api-proxy
|
||||
namespace: home-assistant
|
||||
files:
|
||||
- api.conf.template=shelly-manager-api-proxy.conf
|
||||
generatorOptions:
|
||||
disableNameSuffixHash: true
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# API-key-only listener for shelly-manager (REN-931, REN-935). Rendered by the
|
||||
# nginx-unprivileged entrypoint (envsubst, filtered to POD_IP) into
|
||||
# /etc/nginx/conf.d/ at start.
|
||||
#
|
||||
# shelly-manager signs in whoever X-authentik-username names when the peer is
|
||||
# in Auth__ReverseProxy__TrustedProxies (the pod CIDR). Only the Authentik
|
||||
# outpost may reach :8080 directly. Paperclip agent pods reach this :8081
|
||||
# instead, which drops the identity header, so every request here falls through
|
||||
# to the API key (or the login cookie) and a forged header gets 401.
|
||||
#
|
||||
# Bound to ${POD_IP}, not 0.0.0.0, so it stays off the net1 macvlan (see the
|
||||
# ASPNETCORE_URLS comment in shelly-manager-deployment.yaml).
|
||||
server {
|
||||
listen ${POD_IP}:8081;
|
||||
server_tokens off;
|
||||
client_max_body_size 64m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://${POD_IP}:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
# Empty value = nginx does not pass the header at all, whatever the
|
||||
# client's case or how many copies it sent. X-Forwarded-User is the
|
||||
# app's default HeaderName, dropped too in case the setting changes.
|
||||
# Header names with underscores never pass (ignore_invalid_headers).
|
||||
proxy_set_header X-authentik-username "";
|
||||
proxy_set_header X-Forwarded-User "";
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,9 @@ spec:
|
||||
# outpost pod's address is dynamic, so this trusts the cluster pod
|
||||
# CIDR and leans on the namespace CNP to keep other pods off the
|
||||
# app port. ADMIN_PASSWORD (above) stays as break-glass, e.g. for
|
||||
# port-forward access when authentik is down.
|
||||
# port-forward access when authentik is down. Never open :8080 to
|
||||
# another client: they get the api-proxy sidecar's :8081 (below),
|
||||
# which drops the header (REN-935).
|
||||
- name: Auth__ReverseProxy__Enabled
|
||||
value: "true"
|
||||
- name: Auth__ReverseProxy__HeaderName
|
||||
@@ -168,7 +170,62 @@ spec:
|
||||
memory: 128Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
# API-key-only listener for clients other than the Authentik outpost
|
||||
# (Paperclip agents, REN-931). nginx on ${POD_IP}:8081 proxies to
|
||||
# :8080 and drops X-authentik-username, so the ProxyHeader sign-in
|
||||
# cannot be reached through it. Config and reasoning:
|
||||
# shelly-manager-api-proxy.conf. Service: shelly-manager-api.
|
||||
# No probes: it only serves the agent path, and a probe failure would
|
||||
# also pull the outpost's endpoint out of the shelly-manager Service.
|
||||
- name: api-proxy
|
||||
image: nginxinc/nginx-unprivileged:1.31-alpine@sha256:26b0bf6fbf07297983cb341998d79c831508787de26627dd2a112321b9c3a4af
|
||||
env:
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
- name: NGINX_ENVSUBST_FILTER
|
||||
value: "^POD_IP$"
|
||||
ports:
|
||||
- name: api
|
||||
containerPort: 8081
|
||||
protocol: TCP
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 101
|
||||
runAsGroup: 101
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 16Mi
|
||||
limits:
|
||||
memory: 64Mi
|
||||
volumeMounts:
|
||||
- name: api-proxy-config
|
||||
mountPath: /etc/nginx/templates
|
||||
readOnly: true
|
||||
# envsubst output of the template above.
|
||||
- name: api-proxy-conf-d
|
||||
mountPath: /etc/nginx/conf.d
|
||||
# pid file and proxy temp paths of the unprivileged image.
|
||||
- name: api-proxy-tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: shelly-manager-data
|
||||
- name: api-proxy-config
|
||||
configMap:
|
||||
name: shelly-manager-api-proxy
|
||||
- name: api-proxy-conf-d
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
sizeLimit: 1Mi
|
||||
- name: api-proxy-tmp
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
sizeLimit: 32Mi
|
||||
|
||||
@@ -11,3 +11,21 @@ spec:
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# API-key-only entry for Paperclip agent pods (REN-931, REN-935): the
|
||||
# api-proxy sidecar, which drops the X-authentik-username header. Agents call
|
||||
# http://shelly-manager-api.home-assistant.svc/api/v1/... with the API key.
|
||||
# The CNPs admit agents to :8081 only; :8080 stays outpost-only.
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: shelly-manager-api
|
||||
namespace: home-assistant
|
||||
spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: shelly-manager
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: api
|
||||
protocol: TCP
|
||||
|
||||
@@ -407,3 +407,32 @@ spec:
|
||||
- ports:
|
||||
- port: "5432"
|
||||
protocol: TCP
|
||||
---
|
||||
# Paperclip agent pods reach the shelly-manager API on :8081 (REN-931), the
|
||||
# api-proxy sidecar that drops X-authentik-username. NEVER :8080: the app signs
|
||||
# in whoever that header names when the peer is in the pod CIDR, so :8080 is
|
||||
# for the Authentik outpost only (REN-935). Through :8081 every call needs the
|
||||
# API key. Egress half: agent-egress-shelly-manager in paperclip-renner-ns.yaml.
|
||||
#
|
||||
# DEDICATED policy selecting shelly-manager alone, not a rule on the
|
||||
# endpointSelector:{} default-deny (see the caution there).
|
||||
#
|
||||
# Revert: delete this document and agent-egress-shelly-manager.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: shelly-manager-agent-ingress
|
||||
namespace: home-assistant
|
||||
spec:
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: shelly-manager
|
||||
ingress:
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": paperclip-renner
|
||||
paperclip.io/role: agent
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8081"
|
||||
protocol: TCP
|
||||
|
||||
@@ -134,3 +134,35 @@ spec:
|
||||
- ports:
|
||||
- port: "443"
|
||||
protocol: TCP
|
||||
---
|
||||
# Agent pods reach the shelly-manager API (REN-931, for Argus's REN-929 live
|
||||
# MQTT credential test). Service shelly-manager-api:80 -> targetPort api =
|
||||
# container port 8081, the api-proxy sidecar that drops X-authentik-username;
|
||||
# socket-LB translates before egress policy, so the rule names 8081. Never
|
||||
# :8080: there a forged header signs in without a key (REN-935). Ingress side:
|
||||
# shelly-manager-agent-ingress in home-assistant-ns.yaml.
|
||||
#
|
||||
# Selects every agent pod: the sandbox pods carry no per-agent label (the
|
||||
# plugin writes the run id into `paperclip.io/agent-id`, see above), so it
|
||||
# cannot be narrowed to Argus. The TCP path is not the grant: every call on
|
||||
# :8081 needs the shelly-manager API key, which only Argus holds (REN-930).
|
||||
#
|
||||
# Revert: delete this document and shelly-manager-agent-ingress.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: agent-egress-shelly-manager
|
||||
namespace: paperclip-renner
|
||||
spec:
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
paperclip.io/role: agent
|
||||
egress:
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": home-assistant
|
||||
app.kubernetes.io/name: shelly-manager
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8081"
|
||||
protocol: TCP
|
||||
|
||||
Reference in New Issue
Block a user