# Howto Install Router

**URL:** <https://openziti.discourse.group/t/howto-install-router/2556>\
**Category:** Support\
**Created:** [May 14, 2024, 4:25pm UTC](https://openziti.discourse.group/t/howto-install-router/2556 "2024-05-14T16:25:09Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![berndinox](https://avatars.discourse-cdn.com/v4/letter/b/0ea827/32.png) [@berndinox](https://openziti.discourse.group/u/berndinox)\
**Post date:** [May 14, 2024, 4:25pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/1 "2024-05-14T16:25:09Z")

</div>

Hy folks,  
i am new to ziti - i want to install ziti on two regions to get a resilient mesh for connecting my services.

Cloud:  
DE: Controller & Router  
FR: Router  
... that should be my base-environment

From home (i also have static IP there) i want to add my local network via tunnler (edge?)

I have studied the documentation for several hours, but its really confusing to me.

_tunnler, edge, edge-tunnler, fabric, router, edge-router, router with tunnler - hä?_

I installed the controller successfully in DE, want to add a router on the same server as well as on the FR server.  
When installing i cam across the following issues:

- What installation guid is the right one?  
[Router Deployment | OpenZiti](https://openziti.io/docs/guides/deployments/linux/router/deploy)  
[Run a Router in a Public Cloud | OpenZiti](https://openziti.io/docs/guides/deployments/cloud/router)  
[Local - No Docker | OpenZiti](https://openziti.io/docs/learn/quickstarts/network/local-no-docker#start-your-edge-router)  
_Every guide is slightly different._

- What mode should i use where?  
_Of course, there are some graphics, a componente list, but i dont get the big picture._  
Router: fabric or edge  
Tunnler: Enabled or not?  
Router Mode: none, tproxy, proxy host

Sorry, I really don't want to be nasty or unkind, but I'm missing a simple big picture here, an overview of all these things. Can someone help me? Thank you... cheers

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 14, 2024, 4:36pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/2 "2024-05-14T16:36:10Z")

</div>

Hey there and welcome, @berndinox. I welcome your insights on the deployment docs. I'm working on those as we speak.

It sounds like you followed the [Linux controller guide](https://openziti.io/docs/guides/deployments/linux/controller/deploy/) and are ready to also follow the [Linux router guide](https://openziti.io/docs/guides/deployments/linux/router/deploy).

I'll assume you're adding the first router to your ziti network. There are many router options and the defaults will work for most cases, certainly for the first router.

At a minimum, you need to set two things in `bootstrap.env` file before the first run.

- Set `ZITI_CTRL_ADVERTISED_ADDRESS` to the FQDN of the controller
- Set `ZITI_ENROLL_TOKEN` to the enrollment token you got from administratively creating the router

Do you see how to get the token with `ziti edge create edge-router`?

If you say `--tunneler-enabled` when you create the router then you can also set `ZITI_ROUTER_MODE=host` in `bootstrap.env` before the first run, or modify the generated `/var/lib/ziti-router/config.yml` if you've already run it once.

---

<div class="post-metadata">

**Author:** ![fre4ki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/fre4ki/32/2051_2.png) [@fre4ki](https://openziti.discourse.group/u/fre4ki)\
**Post date:** [May 14, 2024, 4:42pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/3 "2024-05-14T16:42:30Z")

</div>

Hi there!

I also started 1-2 weeks ago. Thats also for me a little bit confusing...

Have you amd64 or arm64 architecture?

I have made a manual for me but it is based in the Foundry Auto Enroll Script.

If you have amd64 i can post it here.

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 14, 2024, 4:52pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/4 "2024-05-14T16:52:12Z")

</div>

@berndinox You also asked about the router modes.

> Router: fabric or edge

The ziti router is versatile, and typical routers provide fabric and edge. Fabric links between routers compose the mesh data plane. Identities dialing or binding services use the edge function, which acts as an on-and-off-ramp for the fabric.

> Tunneler: Enabled or not?

The router can act as a TCP/UDP proxy. Ziti calls this "tunneling."

> Router Mode: none, tproxy, proxy host

This is the proxy mode (default: none). `tproxy` is transparent proxy and requires extra permissions and DNS setup. `host` is reverse proxy mode and doesn't need any special permissions or DNS. `proxy` is a special mode that binds a specific ziti service to a TCP port as a raw socket proxy.

---

<div class="post-metadata">

**Author:** ![berndinox](https://avatars.discourse-cdn.com/v4/letter/b/0ea827/32.png) [@berndinox](https://openziti.discourse.group/u/berndinox)\
**Post date:** [May 14, 2024, 5:13pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/5 "2024-05-14T17:13:30Z")

</div>

@fre4ki X86 - would be great if you can share your docs 🙂

@qrkourier thanks for your replay!

So if i‘d like to create a „base Network“ with some POPs, for getting short paths and high resilience i would configure those nodes as Fabric Routers. One of those also holds the controller.

At the Location (my homelab) where i would like to Access differen services i would join as Private Router with tunnel Mode (Host Mode).

The Clients accessing the services will just need the Tunnel Client (eg ZitMobile Edge)

Does this makes sense?  
BR Bernd

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 14, 2024, 5:17pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/6 "2024-05-14T17:17:54Z")

</div>

[The auto enroll tool](https://github.com/netfoundry/ziti_router_auto_enroll?tab=readme-ov-file#readme) is another way to generate a router config. It's intended for use on a Linux VM.

If you decide to use it, ensure bootstrapping is disabled in service.env, i.e., `ZITI_BOOSTRAP=false`.

Instead of bootstrapping, you'll need to run the auto enroll tool with the `--installDir /var/lib/ziti-router` option to place the generated config in the ziti-controller.service working directory.

---

<div class="post-metadata">

**Author:** ![berndinox](https://avatars.discourse-cdn.com/v4/letter/b/0ea827/32.png) [@berndinox](https://openziti.discourse.group/u/berndinox)\
**Post date:** [May 14, 2024, 5:23pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/7 "2024-05-14T17:23:17Z")

</div>

Whats the recommended way?  
Please also see my Response above 🙂

Thanks a lot for your Input!!

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 14, 2024, 5:34pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/8 "2024-05-14T17:34:38Z")

</div>

> [@berndinox](#):
>
> Whats the recommended way?

Let's start with generating a basic config from env vars with the Linux package's built-in bootstrapper. You can always tailor the generated config in `/var/lib/ziti-router/config.yml` no matter what you used to generate that file, but the auto enroll tool is predates and is mutually exclusive to the Linux router package (DEB/RPM). I just raised [this GitHub issue](https://github.com/netfoundry/ziti_router_auto_enroll/issues/37) to explore maybe using the auto enroll tool together with the Linux package. For now, I recommend that you use the Linux package described in the deployment guide.

> [@berndinox](#):
>
> So if i‘d like to create a „base Network“ with some POPs, for getting short paths and high resilience i would configure those nodes as Fabric Routers. One of those also holds the controller.

That's a good idea: place a ziti router strategically to short-circuit the data paths.

No problem running controller and router on the same host as long as you use separate TCP ports. They're separate by default.

> [@berndinox](#):
>
> At the Location (my homelab) where I would like to Access different services, I would join as a Private Router with tunnel Mode (Host Mode).
> 
> The Clients accessing the services will just need the Tunnel Client (eg, ZitMobile Edge)

Right, the router in your homelab network with tunnel mode "host" gives you a reverse proxy into that private network.

Correct: the clients can run any Ziti tunneler to reach the private services in your homelab.

---

<div class="post-metadata">

**Author:** ![berndinox](https://avatars.discourse-cdn.com/v4/letter/b/0ea827/32.png) [@berndinox](https://openziti.discourse.group/u/berndinox)\
**Post date:** [May 14, 2024, 6:13pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/9 "2024-05-14T18:13:23Z")

</div>

Great, thanks for your recommendation.  
Just one last question, whats the impact / happening when switching a Router to „Fabric“?

„ Not including the `edge` section will start the controller in "fabric only" mode and will not support any edge functionality or concepts (edge SDK connectivity).“

> **[Router Configuration Reference | OpenZiti](https://openziti.io/docs/reference/configuration/router/)**
>
> OpenZiti uses configuration files for controllers that are in the YAML format.

What does „edge“ functionality provide me?

When i want to connect a native App outside of my homelab this reads like „i need edge service on my main mesh network“ - is that assumption right?

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 14, 2024, 6:28pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/10 "2024-05-14T18:28:24Z")

</div>

> [@berndinox](#):
>
> whats the impact / happening when switching a Router to „Fabric“?
> 
> „ Not including the `edge` section will start the controller in "fabric only" mode and will not support any edge functionality or concepts (edge SDK connectivity).“

If you remove the `edge` config section, the router will only serve as an intermediary fabric node in the data mesh. It will not provide any service dialing or termination for identities because those are functions of the ziti edge.

Everything will work if all routers provide both fabric and edge and all identities are allowed by policy to use all routers. The reasons for disabling fabric link or edge listeners or limiting which identities can use which routers are nuanced and probably aren't important for small scale deployments.

---

<div class="post-metadata">

**Author:** ![berndinox](https://avatars.discourse-cdn.com/v4/letter/b/0ea827/32.png) [@berndinox](https://openziti.discourse.group/u/berndinox)\
**Post date:** [May 14, 2024, 6:51pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/11 "2024-05-14T18:51:54Z")

</div>

Thanks!  
And sorry for my stupid questions 😅

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 14, 2024, 7:58pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/12 "2024-05-14T19:58:25Z")

</div>

Are you kidding!? Bring it on. There are no stupid questions here.

---

<div class="post-metadata">

**Author:** ![fre4ki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/fre4ki/32/2051_2.png) [@fre4ki](https://openziti.discourse.group/u/fre4ki)\
**Post date:** [May 15, 2024, 4:59am UTC](https://openziti.discourse.group/t/howto-install-router/2556/13 "2024-05-15T04:59:36Z")

</div>

Good morning,

is it useful to install crowdsec or other IDS/IPS systems to the Controller/Public Router?

Or is it not necessary?

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 15, 2024, 1:04pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/14 "2024-05-15T13:04:22Z")

</div>

IDS and IDP are still relevant tools for a ziti system. I'd be interested if you feel like sharing your configs in a new post about using ziti with a popular open-source IDS like Snort or Suricata.

For example, ziti has a configurable rate limit for TLS negotiations. You could program the IDS to alarm when the limit is breached.

```yaml
tls: 
  handshakeTimeout: 15s

  rateLimiter:
    # if disabled, no tls handshake rate limiting with be enforced
    enabled: true
    # the smallest window size for tls handshakes
    minSize: 5
    # the largest allowed window size for tls handshakes
    maxSize: 5000
    # after how long to consider a handshake abandoned if neither success nor failure was reported
    timeout: 30s

```

---

<div class="post-metadata">

**Author:** ![fre4ki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/fre4ki/32/2051_2.png) [@fre4ki](https://openziti.discourse.group/u/fre4ki)\
**Post date:** [May 15, 2024, 2:39pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/15 "2024-05-15T14:39:04Z")

</div>

@berndinox here is my manual.

## Set Hostname and Timezone

```auto
hostnamectl set-hostname my.fqdn.de
timedatectl set-timezone Europe/Berlin

```

## Optional Tools

`apt install nano mc htop btop iputils-ping net-tools tcpdump nmap iptraf-ng iperf3 -y`

## Ziti requirements

`apt install tar hostname jq curl iptables -y`

## Variables

```auto
export EXTERNAL_DNS="$HOSTNAME"
export EXTERNAL_IP="$(curl -s eth0.me)"

```

## Installation : Controller

```auto
export ZITI_HOME="/etc/ziti/ct"
export ZITI_CTRL_EDGE_IP_OVERRIDE="${EXTERNAL_IP}"
export ZITI_ROUTER_IP_OVERRIDE="${EXTERNAL_IP}"
export ZITI_CTRL_EDGE_ADVERTISED_ADDRESS="${EXTERNAL_DNS:-${EXTERNAL_IP}}"
export ZITI_ROUTER_ADVERTISED_ADDRESS="${EXTERNAL_DNS:-${EXTERNAL_IP}}"

```

## Using Public-Ports for Edge-Clients

```auto
export ZITI_CTRL_ADVERTISED_PORT=8440
export ZITI_CTRL_EDGE_ADVERTISED_PORT=443
export ZITI_ROUTER_PORT=443

```

## Start the Installation

`source /dev/stdin <<< "$(wget -qO- https://get.openziti.io/ziti-cli-functions.sh)"; expressInstall`

## Install Service Controller

```auto
createControllerSystemdFile
stopController 
sudo mv "${ZITI_HOME}/${ZITI_CTRL_NAME}.service" /etc/systemd/system/ziti-controller.service
sudo systemctl daemon-reload
sudo systemctl enable --now ziti-controller

```

# check Service Controller

`sudo systemctl -q status ziti-controller --lines=0 --no-pager`

## Installation : Public-Router

```auto
cd ~
wget https://github.com/netfoundry/ziti_router_auto_enroll/releases/latest/download/ziti_router_auto_enroll.tar.gz
tar xf ziti_router_auto_enroll.tar.gz

```

## Register Router and start Onboarding Process

```auto
export ROUTER_NAME="MyRouterName"
export ADM_PW="MyControllerAdminPassword"
export EXTERNAL_IP="$(curl -s eth0.me)"

sudo ./ziti_router_auto_enroll -f \
--controller MyControllerFQDN \
--controllerFabricPort 45880 \
--controllerMgmtPort 443 \
--adminUser admin \
--adminPassword $ADM_PW \
--routerName $ROUTER_NAME \
--installDir /etc/ziti/pr \
--ctrlPingCheckInterval 10 \
--heartbeatIntervalSeconds 10 \
--autoTunnelListener \
--csrCountry DE \
--csrProvince BY \
--csrLocality 'MyLocation' \
--csrOrganization 'MyOrg' \
--csrOrganizationalUnit 'MyOrgUnit'

```

## Services Reload

`systemctl daemon-reload`

## Reboot

`reboot`

## Check Service after Reboot

`systemctl status ziti-router`

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 15, 2024, 2:44pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/16 "2024-05-15T14:44:27Z")

</div>

Thanks for sharing your manual, @fre4ki .

For context, this shows a way to install both the controller and router in Linux with the `expressInstall()` quickstart which predates and is mutually exclusive to installing the production Linux packages. The packages provide the binary, systemd service, and optionally generate a config, and they probably were not yet available when most people started using the quickstart(s).

The auto-enroll tool is also mutually exclusive to the Linux router package because it installs the binary and a systemd service.

Here are the production deployment guides for Linux: [Deploying on Linux | OpenZiti](https://openziti.io/docs/category/linux)

In that category are migration guides for [controller](https://openziti.io/docs/guides/deployments/linux/controller/migrate) and [router](https://openziti.io/docs/guides/deployments/linux/router/migrate). Follow the migration examples if you started with the `expressInstall()` quickstart and want to migrate to the production Linux package and service.

---

<div class="post-metadata">

**Author:** ![fre4ki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/fre4ki/32/2051_2.png) [@fre4ki](https://openziti.discourse.group/u/fre4ki)\
**Post date:** [May 15, 2024, 2:48pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/17 "2024-05-15T14:48:24Z")

</div>

for me it was the simplest way to start. It is already described in the quickstart but maybe it helps.

My Design was a own Controller VM, 2 Public Routers (all Ubuntu 24.04, Controller with arm64 and 2 Public-Routers with x86).

---

<div class="post-metadata">

**Author:** ![fre4ki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/fre4ki/32/2051_2.png) [@fre4ki](https://openziti.discourse.group/u/fre4ki)\
**Post date:** [May 15, 2024, 5:13pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/18 "2024-05-15T17:13:33Z")

</div>

Regarding to my manual, is there a way to use also the IPv6 address in the certificate?

At the moment just the IPv4 address will be in the certificate.

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [May 15, 2024, 6:03pm UTC](https://openziti.discourse.group/t/howto-install-router/2556/19 "2024-05-15T18:03:45Z")

</div>

x509's SAN extension permits an IPv4 or IPv6 value for an IP subject alternative name, but I recommend using a DNS SAN instead, so you're never locked into a specific IP address.

Since IPv6 is allowed in IP SANs, the next question is how I can use an IPv6 address for my controller.

The answer depends on how you create your controller configuration. All controller deployments I've seen have some helper script that issues the controller's certificate.

Most use an env var like `ZITI_CTRL_ADVERTISED_ADDRESS` or `EXTERNAL_DNS` that set the DNS SAN on the controller's server certificate. Some have a separate var specifically for setting an IP SAN.

* * *

The configuration generators of the Linux controller and router production deployments do not currently support IP SAN, only DNS SAN.

If there's no other way to create a DNS record, you can work around that with a "magic wildcard" DNS SAN like `ZITI_CTRL_ADVERTISED_ADDRESS=ctrl1.2a01-4f8-c17-b8f--2.sslip.io`, which resolves an AAAA request for any subdomain, e.g., "ctrl1", to IPv6 address `2a01:4f8:c17:b8f::2`.

Here's another example that works with local IPv6 address `::1`: `ZITI_CTRL_ADVERTISED_ADDRESS=ctrl1.0000-0000-0000-0000-0000-0000-0000-0001.sslip.io`

Let me know if IP SAN support is important to your use case. I have an idea for making that possible in the production deployments.

EDIT: disclaimer about [sslip.io](http://sslip.io): always use a DNS name you control for something important. This magic wildcard DNS provider is great for testing, and fine for labs when not using any publicly routable IP addresses.
