Router Deployment
Deploy a router as a Linux system service. The router introduction may help to read first.
Router creation
Create the router in the controller first with the web console or the CLI.
After creating the router, save the enrollment token (JWT) for the configuration step below.
Install the router package
The router package provides a systemd service unit and bootstrapping script.
One-liner install script
curl -sS https://get.openziti.io/install.bash | sudo bash -s openziti-router
Manual package repo setup
Configure the package repository and install openziti-router.
- Debian
- RedHat
Configure the repository for the Debian family of distributions (Ubuntu, Mint, Pop!_OS)
Install the OpenZiti repository key.
curl -sSLf https://get.openziti.io/tun/package-repos.gpg | sudo gpg --dearmor --output /usr/share/keyrings/openziti.gpg
Ensure the key is readable by all users.
sudo chmod a+r /usr/share/keyrings/openziti.gpg
Create the repository file.
sudo tee /etc/apt/sources.list.d/openziti-release.list >/dev/null <<EOF
deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main
EOF
Update the package list.
sudo apt update
Configure the repository for the RedHat family (Fedora, Rocky, Alma)
Create the repository file.
sudo tee /etc/yum.repos.d/openziti-release.repo >/dev/null <<\EOF
[OpenZitiRelease]
name=OpenZiti Release
baseurl=https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch
enabled=1
gpgcheck=0
gpgkey=https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch/repodata/repomd.xml.key
repo_gpgcheck=1
EOF
Update the package list.
sudo dnf update
Finally, install the package: openziti-router
The openziti package provides the ziti CLI and is installed as a dependency.
Configuration
You need a config file and an enrollment with the controller. The easiest way to get both is to run the bootstrap script. You can also migrate from an existing installation or craft a config by hand. The bootstrap script is a convenience — it is not required.
Run the bootstrap script
sudo /opt/openziti/etc/router/bootstrap.bash
The script creates a config file and enrolls the router with the controller. It prompts for any answers it needs. If an answer has already been supplied (through the answer file, environment, or stdin), the script skips that prompt.
The script asks for:
- Router address — permanent DNS name or IP address (default: localhost)
- Enrollment token — the JWT from the controller (as a string or file path)
Migrate an existing configuration
This example illustrates copying the configuration and identity files from a previous installation.
Craft a configuration
Create a config file directly with ziti create config router edge --routerName=router. Run ziti create config environment to see the available environment variables. See the router configuration reference for details.
Automation
If you're scripting deployments or using configuration management, you can supply answers ahead of time and run the bootstrap script without prompts. You can also choose which components to bootstrap.
How to supply answers
Answers can come from any combination of:
- Answer file — write answers in /opt/openziti/etc/router/bootstrap.env
- Environment — export answers as environment variables and pass them with
sudo -E - Stdin — pipe answers as
KEY=VALUElines (one per line) into the script
All answers are persisted to bootstrap.env regardless of how they were supplied.
To run without prompts, redirect stdin:
sudo -E /opt/openziti/etc/router/bootstrap.bash < /dev/null
Router answers
ZITI_ENROLL_TOKEN— enrollment token as a string or file path (required)ZITI_ROUTER_ADVERTISED_ADDRESS— permanent DNS name or IP address (required)ZITI_ROUTER_PORT— TCP port for routers (default: 3022)
Selective bootstrapping
You don't have to bootstrap everything at once. Each component can be enabled or disabled independently in /opt/openziti/etc/router/service.env:
| Answer | Default | What it does |
|---|---|---|
ZITI_BOOTSTRAP_CONFIG | true | Generate config.yml (set to force to regenerate) |
ZITI_BOOTSTRAP_ENROLLMENT | true | Enroll with the controller (set to force to re-enroll) |
Starting up
Enable and start the service:
sudo systemctl enable --now ziti-router.service
Further configuration
Customize /var/lib/ziti-router/config.yml as needed and restart the service.
sudo systemctl restart ziti-router.service
Here's a link to the configuration reference.
Learn more about managing routers with the CLI.
Customize the systemd service
Use systemctl edit to override service directives like capabilities or the startup command. Pass -E to sudo so your shell's SYSTEMD_EDITOR (or EDITOR / VISUAL) is used.
sudo -E systemctl edit ziti-router.service
sudo systemctl restart ziti-router.service
An example drop-in with commented directives is included at /opt/openziti/etc/router/override.conf.example.
Firewall
The router's generated configuration uses a single TCP port (default: 3022).
Confirm the router is listening:
sudo ss -tlnp | grep ziti
Troubleshooting
Controller address override
The router learns the controller's address from the enrollment token, so you don't normally need to supply it. If you need to override the address in the enrollment token, set these answers in /opt/openziti/etc/router/bootstrap.env or supply them to the bootstrap script:
ZITI_CTRL_ADVERTISED_ADDRESS— controller DNS name or IP addressZITI_CTRL_ADVERTISED_PORT— controller port (default: 1280)
For Ziti versions 1.6 and lower, both answers are required.
Verify edge listener
Verify the edge listener is reachable by identities. The edge listener must terminate TLS for identities because they will authenticate with a client certificate for all interactions.
The server certificate must be issued by the controller's edge signer CA (edge.enrollment.signerCert in the controller's config.yml).
Substitute the value of listeners[?binding == 'edge'].options.advertise from /var/lib/ziti-router/config.yml:
openssl s_client -connect {listeners[?binding == 'edge'].options.advertise} -alpn ziti-edge -showcerts <>/dev/null \
|& openssl storeutl -certs -noout -text /dev/stdin \
| grep -E '(Subject|Issuer):'
Verify link listener
At least one router must provide a link listener if you have multiple routers. Verify all link listeners are reachable by all routers. The link listener must terminate TLS for routers because they will authenticate with a client certificate for all interactions.
The server certificate must be issued by the controller's edge signer CA (edge.enrollment.signerCert in the controller's config.yml).
Substitute the value of link.listeners[?binding == 'transport'].advertise after the tls: prefix from /var/lib/ziti-router/config.yml:
openssl s_client -connect {link.listeners[?binding == 'transport'].advertise} -alpn ziti-link -showcerts <>/dev/null \
|& openssl storeutl -certs -noout -text /dev/stdin \
| grep -E '(Subject|Issuer):'
Logging
View the service's output.
journalctl -u ziti-router.service
- Log Formats
- Log Levels
Set a different format in the ZITI_ARGS environment variable and restart the service.
ZITI_ARGS='--log-formatter text'
Enable DEBUG log level with the --verbose flag in the ZITI_ARGS environment variable and restart the service.
ZITI_ARGS='--verbose'
Learn more in the logging reference.
Uninstall
-
Clean the service state.
sudo systemctl disable --now ziti-router.service
sudo systemctl reset-failed ziti-router.service
sudo systemctl clean --what=state ziti-router.service -
Purge the package, including configuration files.
APT - Debian, Ubuntu, etc.
sudo apt-get purge openziti-routerRPM - RedHat, Fedora, etc.
sudo dnf remove openziti-router -
Remove any firewall exceptions you created.