Open bnevis-i opened 1 year ago
This functionality is broken because edgex-ui forwards requests to the EdgeX API gateway. In the Docker deployment, it does this through an internal unencrypted HTTP port and passes the authentication token through.
This is configured in the edgex-ui configuration file res/docker/configuration.yaml
:
APIGateway:
Server: edgex-nginx
ApplicationPort: 8000
ApplicationPortSSL: 8443
These values are incorrect and not overridden in the helm chart deployment.
A possible override is:
--- a/templates/edgex-ui/edgex-ui-deployment.yaml
+++ b/templates/edgex-ui/edgex-ui-deployment.yaml
@@ -39,6 +39,10 @@ spec:
hostIP: {{.Values.edgex.hostPortExternalBind}}
{{- end}}
env:
+ - name: APIGATEWAY_SERVER
+ value: ingress-nginx-controller.ingress-nginx.svc
+ - name: APIGATEWAY_APPLICATIONPORT
+ value: "80"
This will cause the edgex-ui backend to send requests to the internal HTTP service port for the NGINX ingress controller.
After making these changes, edgex-ui will behave as follows (where 10.108.97.79 is the service ip of edgex-ui)
$ curl -i http://10.108.97.79:4000/core-data/api/v3/ping
HTTP/1.1 404 Not Found
Content-Length: 146
Content-Type: text/html
While this is better than the HTTP 503 error, it still does not work.
This is because the core-data
ingress resource is declared as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
org.edgexfoundry.service: {{.Values.edgex.app.core.data}}
name: {{.Values.edgex.app.core.data}}
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-secret: "edgex/edgex-client-ca"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
spec:
ingressClassName: nginx
rules:
- host: "{{.Values.edgex.security.tlsHost}}"
http:
paths:
- path: /core-data/(.*)
pathType: Prefix
backend:
service:
name: {{.Values.edgex.app.core.data}}
port:
name: http
tls:
- secretName: edgex-tls
hosts:
- "{{.Values.edgex.security.tlsHost}}"
Where tlsHost
defaults to edgex
.
In other words, the ingress controller is listening on a mutual-auth TLS required TLS host named "edgex". This means that only the following kinds of requests will be honored:
$ curl -s --resolve edgex:443:ipaddress --cacert server-ca.pem --cert client.pem --key client.key "https://edgex/..."
In other words, they must be edgex
hostname, on some ipaddress
, with a client certificate and key supplied.
The helm deployment of EdgeX does not implement JWT authentication via the ingress controller, but relies on mutual-auth TLS instead. Prior to EdgeX 3.0, it was not safe to expose EdgeX services directly via ingress routes, as the services themselves had not direct way to authenticate incoming requests. Even in EdgeX 3.0, there may still be some API routes that are unauthenticated, so directly exposing EdgeX services via Kubernetes ingress resources is risky.
Since the ingress controller doesn't check JWT authentication and edgex-ui-go does not have access to the TLS certificate and key to successfully pass TLS client authentication, edgex-ui-go is unable to reissue the background request.
In other words, edgex-ui is broken in the helm deployment in secure mode.
🐞 Bug Report
Affected Services [REQUIRED]
edgex-ui
Is this a regression?
This has probably always been broken in the Kubernetes deployment in secure mode.
Description and Minimal Reproduction [REQUIRED]
See discussion for original bug report.
🔥 Exception or Error
🌍 Your Environment
Deployment Environment: kubernetes
EdgeX Version [REQUIRED]: main (pending 3.1)
Anything else relevant?