Skip to main content
Star us on GitHub Star

Router Deployment

This article is about deploying a router as a Linux system service. The router introduction may be helpful to read first.

Installation

The router package openziti-router provides a systemd service unit and optional bootstrapping. The package depends on the openziti package which provides the ziti CLI. The easiest way to install both is the cross-platform install script for RPM and Debian distributions.

Download and run the install script.

wget https://get.openziti.io/install.bash

Install interactively so that you will have an opportunity to answer questions about generating a configuration.

sudo bash ./install.bash openziti-router
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

Bootstrapping

You can opt-in to generating a configuration file and enrolling the router automatically. You will be prompted for the most relevant configuration values when installing interactively unless the answer is already known.

Bootstrapping consists of these steps:

  1. Generate a one-shot configuration file from env answers and defaults.
  2. Enroll the router with the controller.

At a minimum, you must set these to opt-in to bootstrapping.

  1. In /opt/openziti/etc/router/service.env (the answer file for the service)
    1. Set ZITI_BOOTSTRAP=true
  2. In /opt/openziti/etc/router/bootstrap.env (the answer file for bootstrapping the router)
    1. Set ZITI_CTRL_ADVERTISED_ADDRESS to the FQDN of the controller
    2. Set ZITI_ENROLL_TOKEN to the resulting token (JWT)

Additionally, you probably want to set these:

  1. In /opt/openziti/etc/router/bootstrap.env (the answer file for bootstrapping the router)
    1. Set ZITI_ROUTER_ADVERTISED_ADDRESS to the permanent FQDN of the router (default: localhost). This value can not be changed after enrollment.
    2. Set ZITI_ROUTER_MODE (default: none) if this router's built-in tunneler will provide a proxy for services. Mode tproxy requires additional kernel capabilities in /etc/systemd/system/ziti-router.service.d/override.conf and DNS resolver configuration for the host.

Bootstrapping the Configuration

The router's configuration is loaded from a YAML file (reference). The Linux system service will generate a valid configuration during the first startup, unless one already exists. You can modify the generated configuration in /var/lib/ziti-router/config.yml.

The filename of the configuration file, relative to the router's working directory, is given as an argument, e.g., entrypoint.bash run config.yml in /lib/systemd/system/ziti-router.service as an argument to the ExecStart command. You may override this in /etc/systemd/system/ziti-router.service.d/override.conf.

Explore configuration option variables by running ziti create config environment --help. Any of these may be set in /opt/openziti/etc/router/bootstrap.env to influence the generated configuration.

Disable generating a configuration by setting ZITI_BOOTSTRAP_CONFIG=false in /opt/openziti/etc/router/service.env.

Bootstrapping the Enrollment

You must provide an enrollment token. Obtain the token by administratively creating the router.

Create a router
ziti edge create edge-router "AcmeRouter1" \
--tunneler-enabled \
--jwt-output-file path/to/token.jwt

Learn more about managing routers with the CLI.

The systemd service looks for the token in /opt/openziti/etc/router/.token if env var ZITI_ENROLL_TOKEN is empty. The file must be readable by root (not others).

ZITI_ENROLL_TOKEN may be defined in /opt/openziti/etc/router/bootstrap.env.

The router will enroll with the controller during the first startup. The one-time enrollment token is consumed during the enrollment process and a private key is generated in the router's working directory.

Disable bootstrapping enrollment by setting ZITI_BOOTSTRAP_ENROLLMENT=false in /opt/openziti/etc/router/service.env.

Firewall

The router's generated configuration uses a single TCP port (default: 3022) defined by ZITI_ROUTER_PORT in /opt/openziti/etc/router/bootstrap.env.

Confirm the router is running and listening on the expected port.

This will list all listening TCP ports for commands that contain "ziti" in their name.

sudo ss -tlnp | grep ziti

If you have only one process named like "ziti" running, you will see output similar to this.

Output
LISTEN 0      4096                          *:3022             *:*    users:(("ziti",pid=2166302,fd=8))         

Verify the router is reachable and presents a server certificate from the controller's intermediate edge signer CA and the intermediate CA cert. Substitute the router's advertised address and port for localhost:3022 with the advertised address in /var/lib/ziti-router/config.yml.

openssl s_client -connect localhost:3022 -alpn ziti-edge -showcerts <>/dev/null \
|& openssl storeutl -certs -noout -text /dev/stdin \
| grep -E '(Subject|Issuer):'
Output
Issuer: C=US, L=Charlotte, O=NetFoundry, OU=ADV-DEV, CN=NetFoundry Inc. Intermediate CA 42KvRQxn.
Subject: C=US, ST=NC, L=Charlotte, O=NetFoundry, OU=Ziti, CN=BhCjN2Rkx
Issuer: C=US, L=Charlotte, O=NetFoundry, OU=ADV-DEV, CN=NetFoundry Inc. Certificate Authority IpcOEkAR6
Subject: C=US, ST=NC, L=Charlotte, O=NetFoundry, OU=ADV-DEV, CN=NetFoundry Inc. Intermediate CA 42KvRQxn.

Logging

View the router service's output with journalctl -u ziti-router.service.

Choose the logging format (default: text).

  • pfxlog - a human-readable format leveraging ANSI escape codes to colorize log levels
  • json - a machine-readable format targeting automated processes for log aggregation
  • text - a human-readable format using plain text (no ANSI escape codes)
Run without colorized log levels
ziti router run config.yml --log-formatter text

Uninstall

sudo systemctl disable --now ziti-router.service
sudo systemctl clean --what=state ziti-router.service