Kong OIDC: discovery url timeout - keycloak

I am building the kong + kong-oidc + keycloak stack for my application. All of them are deployed into minikube cluster.
What I want to achieve is to perform Open ID Connect using Google Identity Provider.
I was referring to this blog post to set the things up https://www.jerney.io/secure-apis-kong-keycloak-1/.
The only difference is that instead of docker-compose, I used minikube to build the stacks up and the keycloak version is image: jboss/keycloak:10.0.1.
Below are the steps I have taken:
Setup Keycloak exposed as NodePort
Create keycloak realm + client
Setup Kong
Install kong-oidc
Define ingress gateway
Configure Kong ingress using OIDC configuration + keycloak client's details from step 2
When I setup it up using Ip address, everything works well. I managed browser my application, and it was redirected to Google Sign in page.
Next, when I put a bind my Ip address with a domain name + SSL encryption. The kong-oidc unable to reach my keycloak discovery URL.
below are the error I got from my browser. Due to the privacy, I have change all domain to example.com
I browsed https://example.com/data
It waited for around 1 min, then the results shows this:
accessing discovery url (https://keycloak.example.com/auth/realms/example/.well-known/openid-configuration) failed: timeout
I have a domain says example.com, and a subdomain keycloak.example.com.
Once I have setup Keycloak behind the Kong proxy, I have removed the NodePort settings.
Below are my ingress definitions:
Ingress for example.com
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gateway-api
annotations:
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
konghq.com/plugins: oidc
spec:
tls:
- secretName: gateway-api
hosts:
- example.com
rules:
- host: example.com
http:
paths:
- path: /data
pathType: Prefix
backend:
serviceName: data-service
servicePort: 8080
Ingress for keycloak.example.com
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gateway-keycloak
annotations:
konghq.com/plugins: transform-function
spec:
rules:
- host: keycloak.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
serviceName: admin-keycloak
servicePort: 8080
The transform-function was used to override the default port forward to ensure the Keycloak admin console able to access through keycloak.example.com using https
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: transform-function
disabled: false
config:
functions:
- ngx.var.upstream_x_forwarded_port=443
plugin: post-function
My OIDC plugin definition:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: oidc
disabled: false
config:
client_id: <client_id>
client_secret: <client_secret>
ssl_verify: "true"
discovery: https://keycloak.example.com/auth/realms/example/.well-known/openid-configuration
introspection_endpoint: http://admin-keycloak:8080/auth/realms/example/protocol/openid-connect/token/introspect
plugin: oidc
Also, I have set the keycloak environment with PROXY_ADDRESS_FORWARDING: "true"
The certificate also installed correctly, I can browser keycloak admin console using https.
Below are the logs from kong pod.
Logs from proxy container
2020/05/11 16:12:16 [error] 22#0: *87800 [lua] openidc.lua:483: openidc_discover(): accessing discovery url (https://keycloak.example.com/auth/realms/example/.well-known/openid-configuration) failed: timeout, client: 172.17.0.1, server: kong, request: "GET /data HTTP/2.0", host: "example.com"
172.17.0.1 - - [11/May/2020:16:12:16 +0000] "GET /data HTTP/2.0" 500 130 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
No error messages from ingress-controller container.
I have run out of ideas on how to troubleshoot this error. Can anyone help on this?

Related

Access https backend with ingress and traefik

I am trying to use 'Kubernetes Ingress with Traefik, CertManager, LetsEncrypt and HAProxy' for certificates management.
What I want to do is use certificates in my application which deployed on kubernetes.
My application contains following services:
my-app1 NodePort 10.43.204.206 16686:31149/TCP
my-app2 NodePort 10.43.204.208 2746:30972/TCP
So for my-app1 without certificates I was accessing it as http://{IP}:31149/app1. And with certificates I am now accessing it as https://my-dns.com/app1. For this I am using this link. I created following ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prod-ingress
namespace: my-ns
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- "my-dns.com"
secretName: prod-cert
rules:
- host: "my-dns.com"
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: my-app1
port:
number: 16686
But for my-app2 without certificates I was accessing it as https://{IP}:30972/app2. So as I am already using https for my-app2 but I want to also use certificates for this service.
Any idea how to do this?
So the issue was, I was deploying my application with self signed certificates. So because of this I am getting issue while accessing my dashboard.
So now I just disabled self signed certificates in my application. And now I am able
to access dashboard with domain name https://my-dns.com.

Enable App Gateway ingress for Azure Kubernetes on 443 (https)

I am new to AKS and trying to set up the cluster and expose it via an app gateway ingress controller. While I was able to set up the cluster using az commands and was able to deploy and hit it using HTTP. I am having some challenges in enabling HTTPS over 443 in-app gateway ingress and looking to get some help.
Below is our workflow and I am trying to setup app gateway listener on port 443
Below is the k8 we used for enabling the ingress. If I apply is without ssl cert it woks but if I give ssl cert I get a 502 bad gateway.
Cert is uploaded to KV and Cluster has KV add-on installed. But I am not sure how to attach this specific kv to cluster and whether the cert should be uploaded to gateway or Kubernetes.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-web-ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/appgw-ssl-certificate: workspace-dev-cluster-cert
appgw.ingress.kubernetes.io/cookie-based-affinity: "true"
appgw.ingress.kubernetes.io/request-timeout: "90"
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
This link can help you with KV add-on certificate on App GW: https://azure.github.io/application-gateway-kubernetes-ingress/features/appgw-ssl-certificate/
I use different configuration to set certs on Appgw.
I'm getting certificates via the akv2k8s tool. This creates secrets on k8s cluster.
Then I use those certs in the ingress configuration. Please check tls definition under spec.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-web-ingress
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/appgw-ssl-certificate: workspace-dev-cluster-cert
appgw.ingress.kubernetes.io/cookie-based-affinity: "true"
appgw.ingress.kubernetes.io/request-timeout: "90"
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
tls:
- hosts:
- yourdomain.com
secretName: your-tls-secret-name
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80

K3S Kubernetes Ingress with multiple web apps under same domain: getting 404

Hi I am very new to kubernetes. I have a k3s.io cluster setup (Server version 1.20) and I want to run multiple web apps under the same domain. I use the k3s default ingress controller (traefik).
Depending on the path given, the request should be routed to the configured web app.
dev.xxxxxxx.de/app -> should go to my self developed .net blazor webassembly app
dev.xxxxxxx.de/graf -> should go to the grafana service/pod
Both apps/services are running in the browser and can be reached sucessfully by their service name via NodePort (without ingress). So I suspect the problem in ingress routing.
My ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
labels:
environment: dev
annotations:
kubernetes.io/ingress.class: "traefik"
spec:
tls:
- hosts:
- dev.xxxxxxx.de
rules:
- host: dev.xxxxxxx.de
http:
paths:
- path: /app
pathType: ImplementationSpecific
backend:
service:
name: iot-app
port:
number: 80
- path: /graf
pathType: ImplementationSpecific
backend:
service:
name: grafana
port:
number: 3000
The problem now is that when browsing to dev.xxxxxxx.de/app or dev.xxxxxxx.de/graf, in both cases the initial request is returned with a 200, but the subsequent requests like assets (css, js) return a 404.
I suspect that the URL
dev.xxxxx.de/app/bootstrap.min.css
is getting transformed to
dev.xxxxx.de/bootstrap.min.css
which leads to a 404.
All hints why I cannot fully browse both of the apps appreciated! Thanks.
As I solved the very same issue right now on my K3s-cluster:
Have you tried to start your master with the --cluster-domain option (see the docs)?
I added that option in the /etc/systemd/system/k3s.service of my master and that did the trick for me.

Nginx ingress results in redirect of login and 'invalid token specified error'

I have the following setup in Kubernetes:
Front-end Angular application (connected to Keycloak)
Keycloak for authorisation/authentication
Back-end service in Spring Webflux (connected to Keycloak)
The problem I am facing is: when I login to the Angular application (while running everything local, except Keycloak), everything works fine. However when I connect from the Angular app (weather local or deployed on kubernetes) to the Back-end Spring webflux service behind the Nginx ingress (depoloyed on kubernetes) I get redirected to the keycloak login page with the error: Invalid token specificied and token successfully revoked.
Here is my Nginx ingress config:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-ingress-prd
namespace: default
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://auth.xxxxx.com, https://001.xxxxxx.com, http://localhost:4200"
nginx.ingress.kubernetes.io/use-regex: "true"
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- mainservice.xxxxxxx.com
secretName: mainservice-com-06-01-2021
rules:
- host: mainservice.xxxxxxx.com
http:
paths:
- path: /*
pathType: Prefix
backend:
service:
name: main-service-prd
port:
number: 80
I have been struggling on this for days and playing around with settings for the Nginx ingress, but have not been successfully in getting this fixed. What am I missing here? Thanks in advance.

Traefik ingress does not work with cluster IP

I am using minikube for developing an application on Kubernetes and I am using Traefik as the ingress controller.
I am able to connect and use my application services when I use the url of the host which I defined in the ingress ("streambridge.local") and I set up in the linux hosts ("/etc/hosts"). But when I use the exact same ip address that I used for the dns I am not able to connect to any of the services and I receive "404 page not found". I have to mention that I am using the IP address of the minikube which I got by: $(minikube ip). Below is my ingress config and the commnads that I used for the dns.
How I can connect and use my application services with the IP?
Ingress config:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
traefik.frontend.rule.type: PathPrefixStrip
traefik.frontend.passHostHeader: "true"
traefik.backend.loadbalancer.sticky: "true"
traefik.wss.protocol: http
traefik.wss.protocol: https
spec:
rules:
- host: streambridge.local
http:
paths:
- path: /dashboard
backend:
serviceName: dashboard
servicePort: 9009
- path: /rdb
backend:
serviceName: rethinkdb
servicePort: 8085
My /etc/hosts:
127.0.0.1 localhost
192.168.99.100 traefik-ui.minikube
192.168.99.100 streambridge.local
This works: http://streambridge.local/rdb
But this does not work: http://192.168.99.100/rdb and returns 404 page not found
You have created ingress routes that evaluate the host header of the http request. So while you are actually connecting to the same ip, it is once with host:streambridge.local and once with "192.168.99.100" for which you did not add a rule in traefik. This is therefore working exactly as configured.