Subject: Seeking Guidance on OpenZiti Deployment for On-Prem Server Access
Hi there,
I’m a Machine Learning Engineer, and our team needs to access on-premise servers across multiple sites. Currently, we use NoMachine for remote access, with Twingate handling connectivity. However, we’re exploring OpenZiti as an open-source alternative.
While I’m relatively new to networking (with only basic knowledge), I’ve taken the following steps to set up OpenZiti:
Reviewed Documentation: Followed the Docker deployment guide: OpenZiti Docker Docs
Hi @aymja, welcome to the community and to OpenZiti!
Can you provide the exact steps you mean when you say "the jwt"? Do you mean an identity for a client? Which client is trying to enroll? Can you provide some sort of output so we know what you're doing better?
Also, keep in mind if you have too many troubles that you can get an OpenZiti overlay from NetFoundry and take any setup out of the equation.
Can you provide any more details about what you did and how and where it went wrong? Cheers
Thank you for your support! I’ve been working through the OpenZiti setup similar to the blog post I mentioned earlier. Here’s where I stand:
Current Setup:
Deployed the controller and router on a server.
Created two identities:
Identity 1 (Office Workstation)
Identity 2 (Remote Site Machine)
(Each machine is on a separate network.)
Identity 1 Enrollment Output:
ziti-edge-tunnel enroll --jwt phone.client.jwt --identity phone.client.json
(3375946)[ 0.000] INFO ziti-sdk:utils.c:196 ziti_log_set_level() set log level: root=3/INFO
(3375946)[ 0.000] INFO ziti-sdk:utils.c:165 ziti_log_init() Ziti C SDK version 1.6.5 @gd72ea7c(HEAD) starting at (2025-06-24T09:36:13.294)
(3375946)[ 0.000] INFO ziti-sdk:ziti_enroll.c:112 ziti_enroll() Ziti C SDK version 1.6.5 @gd72ea7c(HEAD) starting enrollment at (2025-06-24T09:36:13.294)
(3375946)[ 0.000] INFO ziti-sdk:ziti_ctrl.c:637 ziti_ctrl_init() ctrl[https://{our_public_ip}.sslip.io:***] controller initialized
Identity 2 Enrollment Output:
ziti-edge-tunnel enroll --jwt nomachine.zotac.jwt --identity nomachine.zotac.json
(3294734)[ 0.000] INFO ziti-sdk:utils.c:196 ziti_log_set_level() set log level: root=3/INFO
(3294734)[ 0.000] INFO ziti-sdk:utils.c:165 ziti_log_init() Ziti C SDK version 1.6.5 @gd72ea7c(HEAD) starting at (2025-06-24T09:42:55.102)
(3294734)[ 0.000] INFO ziti-sdk:ziti_enroll.c:112 ziti_enroll() Ziti C SDK version 1.6.5 @gd72ea7c(HEAD) starting enrollment at (2025-06-24T09:42:55.103)
(3294734)[ 0.000] INFO ziti-sdk:ziti_ctrl.c:637 ziti_ctrl_init() ctrl[https://{our_public_ip}.sslip.io:***] controller initialized
Tested Ziti Mobile Edge with NoMachine and it shows on the mobile client that it is connected and there is one service. this the is the config of of nomachine connection:
This makes me wonder if NoMachine uses one port for brokering the connection to another port. Can you confirm the "firewall requirements" for the server? Ziti can represent multiple hosts and multiple ports or port ranges in a Ziti service config, if needed.
NoMachine uses port 4000 (TCP) as the default port for connections between devices on the same local network.
For connections over the internet (different networks), additional ports and configurations may be required, such as port forwarding or firewall adjustments.
But i think what is important to me to make the connection up is port 4000 TCP.
Here there are detailed information on NoMachine's connectivity (both LAN and internet-based), refer to their official support article: NoMachine Network Connectivity Guide
Recap: you solved the enrollment issue with the JWT, but your Ziti client tunnelers still don't show the nomachine.zotac service that you're trying to use to remote control the NoMachine terminal server, right?
A good troubleshooting step is to log in the ziti CLI and run policy advisor for the Ziti service in question. The key details are which identities have which permission via your Ziti service policies: Bind or Dial.
~/Documents/OZ$ ziti edge policy-advisor services -q nomachine.zotac
ERROR: phone.client (0) -> nomachine.zotac (0) Common Routers: (0/0) Dial: Y Bind: N
- Identity has no edge routers assigned. Adjust edge router policies.
- Service has no edge routers assigned. Adjust service edge router policies.
ERROR: nomachine.zotac (0) -> nomachine.zotac (0) Common Routers: (0/0) Dial: N Bind: Y
- Identity has no edge routers assigned. Adjust edge router policies.
- Service has no edge routers assigned. Adjust service edge router policies.
You must have one common router authorized for each identity and service paired by a service policy.
In many cases you can create a permissive router policy for all identities and all services, as long as you don't have any special requirements for fencing in your data.