I’m currently in the process of setting up a home k3s cluster. As part of that I want to use Keycloak as an OIDC provider for managing authorization and authentication in a couple of apps that I’m hosting.
Because I’m hosting the cluster at home and my ISP users a CGNAT which prevents me from forwarding ports from my home router I am using Cloudflare Tunnels to allow access (as described here).
The problem is that although the Keycloak admin console is available internally via IP address when accessing via the exposed domain ingress route the site refuses to load with mixed content errors in the browser.
Mixed Content: The page at ‘<URL>’ was loaded over HTTPS, but requested an insecure resource ‘<URL>’
After a lot of trial and error the solution to this was to explicitly state the hostname and admin hostname in the container environment variables which seems to get the console to realise that it should be running on https rather than http.
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: keycloak
labels:
app: keycloak
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: keycloak
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: keycloak
labels:
app: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.0.7
args: ["start-dev"]
env:
- name: KC_BOOTSTRAP_ADMIN_USERNAME
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: bootstrap_admin_username
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: bootstrap_admin_password
- name: KC_PROXY_ADDRESS_FORWARDING
value: "true"
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_PROXY
value: "edge"
- name: KC_HOSTNAME_STRICT
value: "false"
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_HOSTNAME_STRICT_BACKCHANNEL
value: "false"
- name: KC_HOSTNAME
value: "https://sub.domain.com"
- name: KC_HOSTNAME_ADMIN
value: "https://sub.domain.com"
- name: KC_HOSTNAME_STRICT_HTTPS
value: "true"
ports:
- name: http
containerPort: 8080
readinessProbe:
httpGet:
path: /health/ready
port: 9000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keycloak-ingress
namespace: keycloak
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
cert-manager.io/cluster-issuer: cert-manager-cluster-issuer
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
external-dns.alpha.kubernetes.io/hostname: sub.domain.com
external-dns.alpha.kubernetes.io/target: TUNNEL-ID.cfargotunnel.com
spec:
tls:
- hosts:
- sub.domain.com
secretName: keycloak-tls
rules:
- host: sub.domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: keycloak
port:
number: 8080
In order to get this working just replace the “TUNNEL-ID” and “sub.domain” placeholders with the actual values for your Cloudflare tunnel and external domain.
0 Comments