Making ZAC and management API accessible only through service

Hey,

Is there a proper way to make ZAC and the management API accessible only through a service ?
Like close management API ports and make it route through Openziti ?

As the ZAC is an endpoint and not a separate "url", how Im I supposed to configure the host.v1 configuration ?

There's no "one way" but the way I like to do this is as follows:

  • ensure the controller has a router deployed on the same machine as the controller (single server setup style)
  • ensure the router is tunneler enabled
  • add the bindPoint for mgmt/zac using interface 127.0.0.1:9999 (loopback ip, whatever port you want)
  • create a service like the one you show but use the offload address of 127.0.0.1
  • authorize the router to bind the service
  • authorize your identity to dial the service
  • access ZAC/management API via openziti itself

If your router is not on the same machine as the controller, but is in the same address space it's not quite as good (imo) but you can use the private address for the interface binding and the offload address.

That make sense?

Yup totally makes sense.

Guess I'll have to edit the router's configuration aswell as it's pointing to the public FQDN right now, right ?

You should not edit the router no. You need that to be public or you won't be able to connect to the data plane.

Just got it working, thanks alot !

1 Like

Hi,

I'm following this topic to enable administrators to access the mgmt/fabric api endpoints via ziti-api.ziti address but I'm confronted to a certificate validation which can't works because the certificate is only valid for my public controller address and localhost.

When I ziti edge login https://ziti-api.ziti:

---------------------- REQUEST LOG -----------------------
POST  /authenticate?method=password  HTTP/1.1
HOST   : ziti-api.ziti
HEADERS:
                   Accept: application/json
             Content-Type: application/json
               User-Agent: go-resty/1.12.0 (https://github.com/go-resty/resty)
BODY   :
{
   "password": hidden,
   "username": hidden
}
----------------------------------------------------------
RESTY 2025/02/18 13:56:51 ERROR Post "https://ziti-api.ziti/authenticate?method=password": tls: failed to verify certificate: x509: certificate is valid for localhost, hidden_public_addr, not ziti-api.ziti, Attempt 5
error: unable to authenticate to https://ziti-api.ziti. Error: Post "https://ziti-api.ziti/authenticate?method=password": tls: failed to verify certificate: x509: certificate is valid for localhost, hidden_public_addr, not ziti-api.ziti

Do I need to create a certificate for the ziti-api.ziti address? If yes, how (CLI / ZAC)?

Hi @Damien, apparently I'd only ever tried to use the ZAC in this setup and not the CLI! I also received a similar error when using the ziti cli in this configuration. I always end up ssh'ing to the machine to use the CLI apparently!

I confirmed that using the ZAC will function as expected because the browser allows you to bypass this check however the ziti CLI doesn't have this functionality. The only way to get around this at this point is to regenreate a server certificate for your controller with an additional DNS entry. It's easy enough to do, but it's "more to do"... :frowning:

Here's how you can enable this.

  • ssh to the machine
  • ensure you have access to the PKI (this will depend greatly on your deployment you used or if you ran a quickstart to deploy a quickstart network)
  • run a command similar to (but not exactly) this:
    export EXTERNAL_DNS="your.external.address"
    export EXTERNAL_IP="169.254.0.0" #whatever your external ip is...
    export ZITI_PKI="/home/ubuntu/private-mgmt/pki"
    export ZITI_PKI_CTRL_INTERMEDIATE_NAME="intermediate-ca-quickstart"
    
    ziti pki create server \
     --dns "$EXTERNAL_DNS,ziti-api.ziti,$(hostname),localhost" \
     --ip "$EXTERNAL_IP,127.0.0.1" \
     --pki-root "$ZITI_PKI" \
     --ca-name "$ZITI_PKI_CTRL_INTERMEDIATE_NAME" \
     --key-file "server" \
     --server-file controller.server.cert.with.private.address \
     --server-name controller.server.cert.with.private.address
    

Once you create the server cert. You then update the new bindPoint. For example, in my environment it ended up looking like this. Notice i left the old entry by renaming it to _server_cert so that i could undo this easy enough if needed:

    bindPoints:
      - interface: 0.0.0.0:8601
        address: ec2-3-18-113-172.us-east-2.compute.amazonaws.com:8601
    identity:
      ca:          "/home/ubuntu/private-mgmt/pki/root-ca/certs/root-ca.cert"
      key:         "/home/ubuntu/private-mgmt/pki/intermediate-ca-quickstart/keys/server.key"
      _server_cert: "/home/ubuntu/private-mgmt/pki/intermediate-ca-quickstart/certs/server.chain.pem"
      server_cert: "/home/ubuntu/private-mgmt/pki/intermediate-ca-quickstart/certs/controller.server.cert.with.private.address.chain.pem"
      cert:        "/home/ubuntu/private-mgmt/pki/intermediate-ca-quickstart/certs/client.chain.pem"

Before doing this, I could get the same sort of error you did:

PS> ziti edge login ziti-api.ziti:443
RESTY 2025/02/18 12:44:42 ERROR Get "https://ziti-api.ziti:443/edge/management/v1/version": tls: failed to verify certificate: x509: certificate is valid for your.external.address, ziti-api.ziti, ip-172-31-47-200, localhost, not ziti-api.ziti, Attempt 1
RESTY 2025/02/18 12:44:42 ERROR Get "https://ziti-api.ziti:443/edge/management/v1/version": tls: failed to verify certificate: x509: certificate is valid for your.external.address, ziti-api.ziti, ip-...
...
...

AFTER restarting the controller and updating the cert, I can login fine with ziti CLI:

PS> ziti edge login ziti-api.ziti:443
Untrusted certificate authority retrieved from server
Verified that server supplied certificates are trusted by server
Server supplied 2 certificates
Trust server provided certificate authority [Y/N]:

Hope that helps!

1 Like

Perfect it worked!

Thank you a lot. :smile: