Deploy isolated Old IPMI browser behind Authentik in oldimpi

This commit is contained in:
feedc0de committed 2026-10-30 21:18:05 +01:00
1 parent 1ffd25226d
commit 1fc551ac9d
8 files changed
+199

No files matched your search

+44
View File
@@ -203,6 +203,50 @@ additionalObjects:
order: 0
attrs:
enabled: true
oldipmi.yaml: |
version: 1
metadata:
name: Old IPMI forward authentication
labels:
blueprints.goauthentik.io/description: Admin-only access to Old IPMI
entries:
- model: authentik_providers_proxy.proxyprovider
id: oldipmi-provider
state: present
identifiers:
name: Old IPMI
attrs:
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-explicit-consent]]
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
client_type: confidential
grant_types:
- authorization_code
- refresh_token
mode: forward_single
internal_host: ""
external_host: https://oldipmi.brunner.ninja
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [managed, goauthentik.io/providers/proxy/scope-proxy]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- model: authentik_core.application
id: oldipmi-application
state: present
identifiers:
slug: oldipmi
attrs:
name: Old IPMI
provider: !KeyOf oldipmi-provider
launch_url: https://oldipmi.brunner.ninja
- model: authentik_policies.policybinding
state: present
identifiers:
target: !KeyOf oldipmi-application
group: !Find [authentik_core.group, [name, authentik Admins]]
order: 0
attrs:
enabled: true
- apiVersion: v1
kind: ConfigMap
metadata:
+38
View File
@@ -0,0 +1,38 @@
# Legacy IPMI browser
Argo Application `oldipmi` deploys the independent published `oldipmi` chart into
namespace **oldimpi** (intentional spelling). Its chart targetRevision is the
single selected version. Chart source: https://code.brunner.ninja/feedc0de/oldipmi
Open https://oldipmi.brunner.ninja. Traefik uses its existing wildcard TLS
certificate and the namespace's Authentik forward-auth middleware for every
browser asset and WebSocket handshake. The `Old IPMI` application is restricted
to `authentik Admins` by the blueprint in `apps/authentik/values.yaml`.
The existing shared `/outpost.goauthentik.io/` route handles login callbacks.
As with Kubernetes Dashboard, the proxy provider is attached additively to the
embedded Authentik outpost, preserving all its other providers. Recovery: apply
the blueprint, then add `Old IPMI` to that outpost through Authentik's admin UI.
Cloudflare DNS: unproxied CNAME `oldipmi.brunner.ninja` → `brunner.ninja`, following
the existing admin service domains. DNS is account-managed outside Argo CD.
The chart's namespace-wide NetworkPolicy admits only Traefik pods on the web
port. Cilium allows external destinations, including Internet, 192.168.0.0/16
and Funkfeuer 10.12.0.0/16, but explicitly denies cluster/node/API identities,
ServiceCIDR, link-local metadata, MetalLB's pool, and the cluster's Funkfeuer
service address. Public resolvers and no Kubernetes search domains prevent
ordinary `.svc.cluster.local` discovery. This is not a domain-name firewall;
IP policy enforces the boundary even if a name resolves to a cluster IP.
Public ingress URLs remain reachable. Keep the explicit service/MetalLB
exclusions aligned with platform range changes; pod/node exclusions follow
Cilium identities automatically. Cilium policy must reconcile before startup.
This is one shared disposable browser session. BMC passwords, downloads and
sessions are not persisted or backed up. Log out of the BMC after use. A pod
replacement resets the desktop. No existing PVCs or legacy cluster writer are
involved. The user's local Podman session is left intact for comparison.
Verification: check Argo Synced/Healthy, non-root/zero-capability runtime,
HTTP and WebSocket authentication redirects, admin policy/outpost membership,
external connectivity and denied pod/node/Service/LoadBalancer destinations.
Actual hardware KVM verification requires identifying the BMC and logging in.
+8
View File
@@ -0,0 +1,8 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: oldipmi-authentik
spec:
forwardAuth:
address: http://authentik-server.authentik.svc.cluster.local/outpost.goauthentik.io/auth/traefik
trustForwardHeader: true
@@ -0,0 +1,25 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: oldipmi-external-only
annotations:
argocd.argoproj.io/sync-wave: '-1'
spec:
endpointSelector: {}
egress:
# Includes Internet, 192.168.0.0/16 LAN and 10.12.0.0/16 Funkfeuer.
- toEntities: [world]
egressDeny:
# Identity-based protection follows pod and node address changes.
- toEntities: [cluster, host, remote-node, kube-apiserver]
- toCIDR:
- 10.96.0.0/12 # Kubernetes ServiceCIDR
- 169.254.0.0/16 # Link-local/metadata services
- 10.12.4.170/32 # Cluster services exposed through Funkfeuer
toCIDRSet:
# MetalLB's complete reserved pool: 192.168.0.10-192.168.0.49.
- cidr: 192.168.0.10/31
- cidr: 192.168.0.12/30
- cidr: 192.168.0.16/28
- cidr: 192.168.0.32/28
- cidr: 192.168.0.48/31
+18
View File
@@ -0,0 +1,18 @@
ingress:
enabled: true
className: traefik
host: oldipmi.brunner.ninja
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: 'true'
traefik.ingress.kubernetes.io/router.middlewares: oldimpi-oldipmi-authentik@kubernetescrd
networkPolicy:
ingressFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
app.kubernetes.io/instance: traefik-default
# Cilium policy supplies external egress with explicit cluster exclusions.
+2
View File
@@ -149,3 +149,5 @@ resources:
- ghostfolio-postgresql.yaml
- ghostfolio-valkey.yaml
- ghostfolio.yaml
- oldipmi-project.yaml
- oldipmi.yaml
+28
View File
@@ -0,0 +1,28 @@
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: oldipmi
namespace: argocd
spec:
description: Isolated legacy IPMI browser
sourceRepos:
- https://brunner.ninja/charts
- https://code.brunner.ninja/feedc0de/homelab-gitops.git
destinations:
- namespace: oldimpi
server: https://kubernetes.default.svc
namespaceResourceWhitelist:
- group: ''
kind: ConfigMap
- group: ''
kind: Service
- group: apps
kind: Deployment
- group: networking.k8s.io
kind: Ingress
- group: networking.k8s.io
kind: NetworkPolicy
- group: cilium.io
kind: CiliumNetworkPolicy
- group: traefik.io
kind: Middleware
+36
View File
@@ -0,0 +1,36 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: oldipmi
namespace: argocd
spec:
project: oldipmi
sources:
- repoURL: https://brunner.ninja/charts
chart: oldipmi
targetRevision: 0.0.0
helm:
releaseName: oldipmi
valueFiles:
- $values/apps/oldipmi/values.yaml
- repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
ref: values
- repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
path: apps/oldipmi/resources
destination:
server: https://kubernetes.default.svc
namespace: oldimpi
syncPolicy:
automated:
enabled: true
prune: false
selfHeal: true
managedNamespaceMetadata:
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
syncOptions:
- CreateNamespace=true