Windows Ziti-Tunnel Command Line

I am trying to Enroll a Client and a server into an offline Ziti Network Environment… The inital windows offline installer does not work getting various issues with Certs

I have since moved on to trying to call Ziti-tunnel from the exe without msi installation

The Following Steps were taken belwo:

  1. Open command prompt as an admin
  2. Run the Ziti-Tunnel. Command: ziti-edge-tunnell.exe run
  3. From a second command prompt window enroll. Command: ziti-edge-tunnel.exe enroll -j c:\temp\client.jwt -i c:\some\idenity\path\client.json

The tunnel fails with the following error

Going through a different tool it looks to be failing on connection because our controller was setup without dns so it resolves to localhost:1280 problem is the jwt file which is on a different machine resolves to localhost:1280 meaning it is going to itself

I was just typing all this up… I’ll keep typing but it looks like you got that sorted? Right?


I would expect your controller certificate didn’t match the advertised address when seeing a “jwt verification failure”.

The jwt will have an ISS field that describes the url the enrolling endpoint must attach to. if you cat the jwt and put it into’s jwt parser, is the url specified therein the “right” one?


Well I know the problem its now thinking about the solution as if I create a simple dns I have no clue the impacts it could have on the controller. Is there a way to update jwt to use the IP instead of dns

I honesty don’t know I have not really ever worked with one before

The way to influence what is placed into the controller is via the ‘address’ field of the controller’s configuration. Specifically the edge.api.address field. I would suspect that is set to “localhost” right now.

Here’s an example of one of mine:

    # address - required
    # The default address (host:port) to use for enrollment for the Client API. This value must match one of the addresses
    # defined in this Controller.WebListener.'s bindPoints.
    address: sg3:1280

Then down below you need a bindPoint that maps to this in the setting:

  # name - required
  # Provides a name for this listener, used for logging output. Not required to be unique, but is highly suggested.
  - name: client-management
    # bindPoints - required
    # One or more bind points are required. A bind point specifies an interface (interface:port string) that defines
    # where on the host machine the webListener will listen and the address (host:port) that should be used to
    # publicly address the webListener(i.e., localhost, This public address may be used for
    # incoming address resolution as well as used in responses in the API.
      #interface - required
      # A host:port string on which network interface to listen on. will listen on all interfaces
      - interface:
        # address - required
        # The public address that external incoming requests will be able to resolve. Used in request processing and
        # response content that requires full host:port/path addresses.
        address: sg3:1280
1 Like

This also effects the PKI, you’ll need to make sure the certificates are valid for whatever values you place in there, meaning they have a SANS set for DNS:sg3 or IP: I can expand on that if you need/want me to, but if you know what I mean, I don’t need to :slight_smile:

When the quickstart script executes, it makes an attempt to resolve the hostname and use that field but you don’t need to use that if you don’t want to… Let me know if that’s helpful or just more confusing…

I was able to follow all your steps and change what was needed to be changed and I believe I am one key value away from working

I only changed the Controller yaml file not the edge router and looking at the edge router localhost is listed quite a bit I have a feeling that is supposed to be updated could be wrong about that

Hey great!

That error right there means when the controller was created, it generated a PKI that’s only valid for “localhost” type stuff. You’ll probably have to replace the PKI at this point, and tbh the easiest way to accomplish that is with a total reinstall of the network… :expressionless: We could work through being surgical, but really, that’s “the fastest and easiest” way. It also makes me think we should/could detect all IP addresses at “install” time and ask you which of the IPs you’d like to use along with…

The good news is that you should be able to simply set EXTERNAL_IP=“” and rerun the quickstart.

I just did that locally. (well, i used MY ip: export EXTERNAL_IP="") and I can see in my output of expressInstall this line:

Creating server cert from ca: sg3-intermediate for sg3,localhost,sg3,sg3 /,

Then I used openssl:

openssl s_client -connect | openssl x509 -text

And I can see the SANS set properly:

            X509v3 Subject Alternative Name:
                DNS:sg3, DNS:localhost, DNS:sg3, DNS:sg3, IP Address:, IP Address:

So that should resolve this issue.

Stupid question I know but can I take the express Installer offline I had troubles with doing that and made the image and then moved to the lab but it would be so much easier if it can be offline

and if so would it just be the wget command to download it but don’t run the express install

Yes sure. Let me try it out fully disconnected and I’ll get back to you

1 Like

Yet again you are the best

Yep. It worked fine. I’m playing around with twitch streaming these sorta things too if you’re interested in watching me fumble and bumble through this as well… :slight_smile: Twitch

Here’s basically what I did…

  • on rhel79: block all outbound except for ssh (so i could USE the vm)

    [root@rhel79 ~]# cat
    iptables -P INPUT DROP
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A INPUT -m state --state INVALID -j DROP
    iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -P OUTPUT DROP
    iptables -A OUTPUT -o lo -j ACCEPT
    iptables -A OUTPUT -m state --state INVALID -j DROP
    iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp -m tcp --dport 22 -j ACCEPT
    [root@rhel79 ~]# ping
    ping: Name or service not known
  • on my workstation: pull down the latest from my local computer:

  • on my workstation: source and issue getZiti to pull down the latest ziti

    . ./; getZiti
  • on my workstation: scp ziti-cli-functions and the ziti binaries to rhel

  • on rhel79: set hostname [optional] hostnamectl set-hostname "rhel79"

  • on rhel79: source

  • on rhel79: call ‘unsetZitiEnv’, export ZITI_BIN_DIR and ZITI_PWD, and run expressInstall:

    source ./; \
      unsetZitiEnv; \
      export ZITI_BIN_DIR=/root/ziti-v0.27.5; \
      export ZITI_PWD=admin; \
      rm -rf $HOME/.ziti; \
  • verify it all worked…

  • on rhel79: start the controller: startController

  • on rhel79: verify it all actually worked using openssl:

    openssl s_client -connect localhost:1280 | openssl x509 -text
  • see the SANS set properly (albeit with a few extra DNS entries lol):

    X509v3 Subject Alternative Name:
        DNS:rhel79, DNS:localhost, DNS:rhel79, DNS:rhel79, IP Address:, IP Address:

Everything Works perfect now I have a Client and server connected to the overlay I have snapped the baseline and handing it off

Thank you for all your support I will now be doing a lot of documentation

1 Like

Excellent, that’s great to hear! If you ever want to share what you did or how you did it, I know we’d love to hear about it.