edgexfoundry / edgex-helm

Owner: Core WG
Apache License 2.0
4 stars 7 forks source link

helm deployment: edgex-ui-go does not work #22

Open bnevis-i opened 1 year ago

bnevis-i commented 1 year ago

🐞 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


edgex-ui-go container logs contains:

/(target service)/api/v3/ping
2023/09/20 18:03:53 http: proxy error: context deadline exceeded

🌍 Your Environment

Deployment Environment: kubernetes

EdgeX Version [REQUIRED]: main (pending 3.1)

Anything else relevant?

bnevis-i commented 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.