From 78c5c967f268e3e50ef9560a6770e53ff6eb79a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Verstraeten?= <1546779+cedricve@users.noreply.github.com> Date: Wed, 4 Nov 2026 08:51:45 +0000 Subject: [PATCH] Fix Hub frontend routing for hardened images Route frontend NodePort traffic through the named http port, cover legacy and hardened primary/demo frontends in CI, and document coordinated runtime upgrades. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/kind.yaml | 4 ++ README.md | 56 ++++++++++++++++++++++++ base/hub/kerberos-hub-nodeports.yaml | 2 +- scripts/check-hub-runtime.sh | 64 ++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 scripts/check-hub-runtime.sh diff --git a/.github/workflows/kind.yaml b/.github/workflows/kind.yaml index c7d5973..485e432 100644 --- a/.github/workflows/kind.yaml +++ b/.github/workflows/kind.yaml @@ -27,6 +27,10 @@ jobs: kubectl get sc - name: Checkout repository uses: actions/checkout@v2 + - name: Check Hub legacy and hardened routing + run: | + helm repo add kerberos https://charts.kerberos.io + bash scripts/check-hub-runtime.sh kerberos/hub - name: Install OpenEBS run: | kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml diff --git a/README.md b/README.md index 48b385c..611535d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,62 @@ The Kerberos.io stack offers flexible installation options, supporting deploymen This repository continuously tests the Kerberos.io deployment using GitHub Actions across various platforms. Refer to the badges for an overview of the operating systems and Kubernetes distributions we are deploying to. We welcome suggestions for additional automations to consider. +### Upgrading to hardened Hub images + +Upgrade the chart and image runtime settings together, not just the image tags. +Use chart `0.167.3` or newer for hardened Admin and worker runtime settings +(`0.167.2` or newer for both primary and demo frontends). The base Hub values +still select legacy images; do not apply hardened settings indiscriminately to +legacy or custom images. + +For a compatible hardened frontend, merge this into your Hub values: + +```yaml +kerberoshub: + frontend: + containerPort: 8080 + securityContext: + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: RuntimeDefault + volumes: + - name: frontend-tmp + emptyDir: + medium: Memory + sizeLimit: 16Mi + volumeMounts: + - name: frontend-tmp + mountPath: /tmp +``` + +Select your verified hardened image tag alongside these settings. Preserve any +existing branding/translation volumes and mounts when merging the lists. These +settings also apply to the demo frontend. Admin uses the **top-level** `admin` +values key, not `kerberoshub.admin`; configure its image, port, scratch mount and +security context separately. See the +[chart runtime documentation](https://github.com/kerberos-io/helm-charts/blob/master/charts/hub/README.md) +for Admin, health probes and per-worker settings. + +The frontend Service and NodePort still expose port `80` and node port `32080`; +their target must be the container port named `http`, which resolves to `80` +for legacy images or `8080` for hardened images. Reapply +[the NodePort manifest](./base/hub/kerberos-hub-nodeports.yaml) when upgrading an +existing deployment. A numeric target of `80` causes connection failures with +hardened images even when the pod is running. Rollbacks must restore the legacy +port and remove incompatible security contexts/probes along with the image tag. + +Run the cluster-free routing regression check against a local chart checkout: + +```sh +bash scripts/check-hub-runtime.sh ../helm-charts/charts/hub +``` + ## Architecture As previously indicated, several integral components, including Object Storage, Database, and Message Brokers, are deployed and configured to ensure the proper functionality of Kerberos.io. The architecture diagrams below aims to provide a visual representation of these components and their interactions with one another depending the deployment; self-hosted or managed cloud deployment. diff --git a/base/hub/kerberos-hub-nodeports.yaml b/base/hub/kerberos-hub-nodeports.yaml index fee0c95..df8f50b 100644 --- a/base/hub/kerberos-hub-nodeports.yaml +++ b/base/hub/kerberos-hub-nodeports.yaml @@ -9,7 +9,7 @@ spec: type: NodePort ports: - port: 80 - targetPort: 80 + targetPort: http nodePort: 32080 # You can specify a port in the range 30000-32767 or let Kubernetes assign one automatically name: frontend protocol: TCP diff --git a/scripts/check-hub-runtime.sh b/scripts/check-hub-runtime.sh new file mode 100644 index 0000000..de39f6e --- /dev/null +++ b/scripts/check-hub-runtime.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CHART_DIR="${1:?Usage: bash scripts/check-hub-runtime.sh /path/to/charts/hub}" + +assert_contains() { + local rendered="$1" pattern="$2" + if ! grep -Eq -- "$pattern" <<< "$rendered"; then + printf 'Missing expected Hub runtime setting: %s\n' "$pattern" >&2 + return 1 + fi +} + +nodeport="$(awk ' + /^---/ { selected=0 } + /name: hub-frontend-nodeport$/ { selected=1 } + selected { print } +' "$ROOT/base/hub/kerberos-hub-nodeports.yaml")" +assert_contains "$nodeport" 'targetPort: http$' +assert_contains "$nodeport" 'port: 80$' +assert_contains "$nodeport" 'nodePort: 32080' + +HARDENED_FLAGS=( + --set kerberoshub.frontend.containerPort=8080 + --set-json 'kerberoshub.frontend.securityContext={"runAsNonRoot":true,"runAsUser":65532,"runAsGroup":65532,"readOnlyRootFilesystem":true,"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"seccompProfile":{"type":"RuntimeDefault"}}' + --set-json 'kerberoshub.frontend.volumes=[{"name":"frontend-tmp","emptyDir":{"medium":"Memory","sizeLimit":"16Mi"}}]' + --set-json 'kerberoshub.frontend.volumeMounts=[{"name":"frontend-tmp","mountPath":"/tmp"}]' +) + +for runtime in legacy hardened; do + flags=() + port=80 + if [[ "$runtime" == hardened ]]; then + flags=("${HARDENED_FLAGS[@]}") + port=8080 + fi + rendered="$(helm template hub "$CHART_DIR" \ + --values "$ROOT/base/hub/kerberos-hub-values.yaml" \ + --set mode=ui --set kerberoshub.frontend.demoEnabled=true "${flags[@]}")" + for frontend in hub-frontend hub-frontend-demo; do + resource="$(awk -v source="# Source: hub/templates/kerberos-hub/$frontend.yaml" ' + /^---/ { selected=0 } + /^# Source:/ { selected=($0 == source); next } + selected { print } + ' <<< "$rendered")" + assert_contains "$resource" 'targetPort: http$' + assert_contains "$resource" 'port: 80$' + assert_contains "$resource" "containerPort: $port$" + assert_contains "$resource" 'name: http$' + if [[ "$runtime" == hardened ]]; then + for setting in 'runAsNonRoot: true' 'runAsUser: 65532' \ + 'runAsGroup: 65532' 'readOnlyRootFilesystem: true' \ + 'allowPrivilegeEscalation: false' 'type: RuntimeDefault' \ + 'drop:' '- ALL' 'medium: Memory' 'sizeLimit: 16Mi' \ + 'mountPath: /tmp' 'name: frontend-tmp'; do + assert_contains "$resource" "^[[:space:]]*(- )?$setting$" + done + fi + echo "OK ($runtime): $frontend routes http to $port" + done +done + +echo "Hub frontend NodePort and chart runtime checks passed."