Identity enrolment with OpenZiti controller failing

JWT issued by the openziti controller for one of the identity has the controller internal IP in the URI instead of public dns and hence the enrolment fails. One of the identities I generated for my egress tunneller had the right URI in JWT and I was able to enroll. Is there a way to configure such that the JWT will always have the public dns/ip ?

You must advertise an address for the edge-client API that resolves to the web listener where the edge-client API is bound.

So, three points of configuration must be aligned:

  1. .edge.api.address (the advertisement embedded in enrollment tokens) and
  2. A .web[] listener with the edge-client binding must have the same address in .bindpoints[].address (this determines which TLS server key signs the token)
  3. That web listener's .bindpoints[].interface must be reachable by enrollees who call the advertised address.

Here's a typical example of a controller configuration. In this example, the edge client API advertised address is kbtest:1280, there's one web listener with an address matching the edge API advertised address and has the edge-client binding, and edge clients can reach that same web listener binding's interface address by resolving the advertised address kbtest:1280.

v: 3

db:                     "./db/ctrl.db"

identity:
  cert:        "./pki/intermediate-ca/certs/client.cert"
  server_cert: "./pki/intermediate-ca/certs/server.chain.pem"
  key:         "./pki/intermediate-ca/keys/server.key"
  ca:          "./pki/root-ca/certs/root-ca.cert"

ctrl:
  listener:             tls:0.0.0.0:1280

healthChecks:
  boltCheck:
    interval: 30s
    timeout: 20s
    initialDelay: 30s

edge:
  api:
    address: kbtest:1280
  enrollment:
    signingCert:
      cert: ./pki/intermediate-ca/certs/intermediate-ca.cert
      key:  ./pki/intermediate-ca/keys/intermediate-ca.key
    edgeIdentity: {}
    edgeRouter: {}

web:
  - name: combined-edge
    bindPoints:
      - interface: 0.0.0.0:1280
        address: kbtest:1280
    identity:
      ca:          "./pki/root-ca/certs/root-ca.cert"
      key:         "./pki/intermediate-ca/keys/server.key"
      server_cert: "./pki/intermediate-ca/certs/server.chain.pem"
      cert:        "./pki/intermediate-ca/certs/client.cert"
    apis:
      - binding: edge-management
        options: { }
      - binding: edge-client
        options: { }
      - binding: fabric
        options: { }

I changed the controller config as you described, now when I try to enroll from ziti desktop edge (MAC v2.37), I get the following error:

(806)[2023-12-27T17:37:04.704Z]   DEBUG ziti-sdk:ziti_enroll.c:138 well_known_certs_cb() err->message is: software caused connection abort
(806)[2023-12-27T17:37:04.704Z]   ERROR ziti-sdk:ziti_enroll.c:221 well_known_certs_cb() /Users/runner/work/ziti-sdk-swift/ziti-sdk-swift/deps/ziti-tunnel-sdk-c/build-macosx-x86_64/_deps/ziti-sdk-c-src/library/ziti_enroll.c:139 - ZITI_JWT_VERIFICATION_FAILED => -7 (JWT verification failed)
[2023-12-27T17:37:04:705Z]   ERROR CZiti:ZitiEnroller.swift:213 on_enroll() CONTROLLER_UNAVAILABLE
[2023-12-27T17:37:04:705Z]   ERROR CZiti:Ziti.swift:327 enroll() Optional(Error Domain=ZitiError Code=-7 "CONTROLLER_UNAVAILABLE" UserInfo={NSLocalizedDescription=CONTROLLER_UNAVAILABLE})
[2023-12-27T17:37:06:416Z]    INFO Ziti Desktop Edge:Array+ZitiIdentity.swift:25 updateIdentity() testoneid.jwt:cH-LrxDf.- CHANGED

When I try to entroll from JVM SDK, I get the following SSL Handshake error :

cause : javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching ec2-100-26-ABC-XYZ.compute-1.amazonaws.com found

The Ziti Desktop Edge for macOS error indicates the controller is unavailable at the token address. You can parse the token to find the issuer (iss) claim to help you diagnose the problem. For example, you can check the issuer URL is valid for enrollees to call the edge-client API.

You may parse the enrollment token with https://jwt.io or this Python script to inspect the claims.

The JVM SDK error indicates that the TLS server certificate encountered by the SDK does not match the advertised address. I'm unsure precisely how the JVM SDK's trust is normally configured, but I expected it to use a standard Ziti identity context which includes a bundle of trusted issuer certificates by which to verify any server TLS certificate that it encounters. Let me know if you see evidence this is not the case.

You may verify the error reported by the JVM SDK by checking the DNS and IP SANs on the server certificate configured for the controller's web listener where the edge-client API is bound. One must match the advertised address.

Useful tools for this diagnostic are (my preference) cfssl (link) and openssl, e.g., cfssl certinfo -domain ec2-100-26-ABC-XYZ.compute-1.amazonaws.com:443 | jq .sans

I verified the issuer in JWT token and it matches the public accessible endpoint. I am able to login to the controller using the endpoint url in "iss" field using curl/postman. Not sure why ZDE says "CONTROLLER UNAVAILABLE". I verified the IP SANS on the server certificate. It does not match the advertised address which I had updated in the YAML. May be the certificate needs to be regenerated after the YAML update? Is there an utility to do the same?

I regenerated the ziti controller server certificate by following the instructions here : Certificate Expired - #4 by TheLumberjack

Now I am able to enroll the identity from ZDE and JVM SDK

Thanks for your support.

1 Like