diff --git a/kubernetes/apps/authentik/blueprints-configmap.yaml b/kubernetes/apps/authentik/blueprints-configmap.yaml index 9fdef09b..684f6b43 100644 --- a/kubernetes/apps/authentik/blueprints-configmap.yaml +++ b/kubernetes/apps/authentik/blueprints-configmap.yaml @@ -103,6 +103,16 @@ data: slug: paperless-proxy state: absent + # syncthing.paperless.renner.uno is gated by authentik-gate-sync + # (kubernetes/apps/paperless/syncthing.yaml), which admits this group. + # Members are managed in Authentik. + - model: authentik_core.group + identifiers: + name: Paperless Admins + state: present + attrs: + is_superuser: false + # vscode.home.renner.uno is gated by authentik-gate-sync # (kubernetes/apps/home-assistant/vscode-ingress.yaml), which admits this # group. Members are managed in Authentik. diff --git a/kubernetes/apps/monitoring-rules/probes-dns.yaml b/kubernetes/apps/monitoring-rules/probes-dns.yaml index 13a316bc..0ea94d8a 100644 --- a/kubernetes/apps/monitoring-rules/probes-dns.yaml +++ b/kubernetes/apps/monitoring-rules/probes-dns.yaml @@ -142,4 +142,4 @@ spec: - "[fd02:47::1]:53" - "10.2.47.1:53" labels: - dns_name: syncthing.paperless.renner.uno + dns_name: sync.paperless.renner.uno diff --git a/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml b/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml index efafa406..c33b1548 100644 --- a/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml +++ b/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml @@ -136,7 +136,7 @@ spec: prober: dns timeout: 5s dns: - query_name: syncthing.paperless.renner.uno + query_name: sync.paperless.renner.uno query_type: A valid_rcodes: [NOERROR] validate_answer_rrs: diff --git a/kubernetes/apps/paperless/kumamonitors.yaml b/kubernetes/apps/paperless/kumamonitors.yaml index a78ce801..dc87bbea 100644 --- a/kubernetes/apps/paperless/kumamonitors.yaml +++ b/kubernetes/apps/paperless/kumamonitors.yaml @@ -138,3 +138,25 @@ spec: expiryNotification: true keyword: keyword: "authentik" +--- +apiVersion: uptime.renner.uno/v1alpha1 +kind: KumaMonitor +metadata: + name: syncthing-ui-gate + namespace: paperless +spec: + type: keyword + displayName: Syncthing Login + parentRef: + name: docs + interval: 60 + retryInterval: 60 + maxRetries: 1 + timeout: 20 + http: + # behind the Authentik gate; asserts the login page the redirect chain ends on + url: https://syncthing.paperless.renner.uno/ + acceptedStatusCodes: ["200-299"] + expiryNotification: true + keyword: + keyword: "authentik" diff --git a/kubernetes/apps/paperless/syncthing.yaml b/kubernetes/apps/paperless/syncthing.yaml index 08c30e98..a518f2c2 100644 --- a/kubernetes/apps/paperless/syncthing.yaml +++ b/kubernetes/apps/paperless/syncthing.yaml @@ -52,11 +52,8 @@ spec: - name: syncthing image: syncthing/syncthing:2.1.7@sha256:2b71da7c0d0a91a6ae5285ad079226fecc0a365d08b27720e1f7037b018f7546 env: - # UI bind: any-interface so the ClusterIP Service can reach - # it. Network exposure is gated by the absence of an Ingress - # and the namespace default-deny CNP — set a UI password in - # the Syncthing UI on first port-forward access before - # publishing it. + # UI bind: any-interface so the ClusterIP Service can reach it. + # External access goes through the syncthing-ui Ingress only. - name: STGUIADDRESS value: "0.0.0.0:8384" - name: PUID @@ -115,10 +112,6 @@ spec: persistentVolumeClaim: claimName: paperless-consume --- -# UI Service — ClusterIP only. Access via `kubectl -n paperless -# port-forward svc/syncthing-ui 8384:8384` for first-time setup -# (set admin password). Future Ingress + Authentik gate is a -# separate change once auth is configured. apiVersion: v1 kind: Service metadata: @@ -132,6 +125,36 @@ spec: port: 8384 targetPort: ui --- +# LAN-only UI: Paperless Admins through the Authentik gate. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: syncthing-ui + namespace: paperless + labels: + dns.renner.uno/internal: "true" + annotations: + traefik.ingress.kubernetes.io/router.middlewares: authentik-gate@kubernetescrd + cert-manager.io/cluster-issuer: letsencrypt-cluster + auth.renner.uno/group: Paperless Admins +spec: + ingressClassName: traefik + rules: + - host: syncthing.paperless.renner.uno + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: syncthing-ui + port: + number: 8384 + tls: + - secretName: syncthing-ui-tls + hosts: + - syncthing.paperless.renner.uno +--- # Sync ports — LAN-reachable LoadBalancer. Peers (phones, laptops) # connect here for the dropbox sync. external-dns publishes the # hostname into UniFi DNS only (no cloudflare label); off-LAN peers @@ -146,7 +169,7 @@ metadata: dns.renner.uno/internal: "true" annotations: io.cilium/lb-ipam-ips: "10.2.99.85,fd99::85" - external-dns.kubernetes.io/hostname: syncthing.paperless.renner.uno + external-dns.kubernetes.io/hostname: sync.paperless.renner.uno spec: type: LoadBalancer externalTrafficPolicy: Local diff --git a/kubernetes/infrastructure/network-policies/paperless-ns.yaml b/kubernetes/infrastructure/network-policies/paperless-ns.yaml index 31b5b94b..7cde08a4 100644 --- a/kubernetes/infrastructure/network-policies/paperless-ns.yaml +++ b/kubernetes/infrastructure/network-policies/paperless-ns.yaml @@ -145,8 +145,8 @@ spec: # Allow Syncthing peer-to-peer sync from the LAN/world. # - 22000 TCP+QUIC: actual sync traffic between peers. # - 21027 UDP: local-discovery broadcast packets from peers on the LAN. -# UI (8384) is intentionally NOT listed — accessed via port-forward -# until an Ingress + Authentik gate is added. +# UI (8384) is intentionally NOT listed — authentik-gate-sync generates the +# CNP syncthing-ui-gate that admits traefik. apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: