zrok/docs/guides/self-hosting/linux/index.mdx

335 lines
14 KiB
Plaintext
Raw Normal View History

---
sidebar_position: 40
2024-04-23 20:33:41 +02:00
title: Self-Hosting Guide for Linux
sidebar_label: Linux
---
## Walkthrough Video
<iframe width="100%" height="315" src="https://www.youtube.com/embed/870A5dke_u4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
## Before you Begin
This will get you up and running with a self-hosted instance of `zrok`. I'll assume you have the following:
* a Linux server with a public IP
* a wildcard DNS record like `*.zrok.quigley.com` that resolves to the server IP
## OpenZiti
2022-12-07 19:58:05 +01:00
OpenZiti (a.k.a. "Ziti") provides secure network backhaul for `zrok` public and private shares. You need a Ziti Controller and a Ziti Router. You can run everything on the same Linux VPS.
2022-12-07 19:58:05 +01:00
1. Install the Ziti Controller package by following the [Linux controller deployment guide](https://openziti.io/docs/category/deployments).
1. Ensure your answer file (`/opt/openziti/etc/controller/bootstrap.env`) has the FQDN of your Linux server and an admin password defined.
1. Ensure your firewall allows the controller port from the answer file.
1. Start the controller service (`ziti-controller.service`) and check the status.
1. Log in to the Ziti Controller
2022-12-07 19:58:05 +01:00
```bash
ziti edge login localhost:1280 -u admin -p <password>
```
1. Administratively Create a Ziti Router
```bash
ziti edge create edge-router "router1" -o /tmp/router1.jwt
```
1. Install the Ziti Router package by following [the Linux router deployment guide](https://openziti.io/docs/category/deployments).
1. Ensure your answer file (`/opt/openziti/etc/router/bootstrap.env`) has the FQDN of your Linux server for both controller and router addresses and the enrollment token from the previous step.
1. Ensure your firewall allows the router port from the answer file.
1. Start the router service (`ziti-router.service`) and check the status.
1. Verify the new router is online.
2022-12-07 19:58:05 +01:00
```bash
ziti edge list edge-routers
```
## Install zrok
Debian and RPM packages are available for `zrok`.
```bash
sudo apt install zrok
```
Follow [the Linux installation guide](/guides/install/linux.mdx) to install the `zrok` package from the repository or manually install the binary for your platform.
2023-01-19 15:53:28 +01:00
## Configure the Controller
Create a `zrok` controller configuration file in `etc/ctrl.yml`. The controller can terminate TLS or you may front the server with a reverse proxy that continually renews the necessary wildcard certificate (e.g., Caddy w/ a DNS provider plugin). This example will expose the non-TLS listener for the controller.
2022-12-07 19:58:05 +01:00
```yaml
# _____ __ ___ | | __
# |_ / '__/ _ \| |/ /
# / /| | | (_) | <
# /___|_| \___/|_|\_\
# controller configuration
2023-04-06 02:20:31 +02:00
v: 3
2022-12-07 19:58:05 +01:00
admin:
# generate these admin tokens from a source of randomness, e.g.
# LC_ALL=C tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32
2022-12-07 19:58:05 +01:00
secrets:
2023-06-13 20:13:39 +02:00
- Q8V0LqnNb5wNX9kE1fgQ0H6VlcvJybB1 # be sure to change this!
2022-12-07 19:58:05 +01:00
endpoint:
host: 0.0.0.0
port: 18080
2023-06-13 20:13:39 +02:00
invites:
invites_open: true
2022-12-07 19:58:05 +01:00
store:
path: zrok.db
type: sqlite3
ziti:
api_endpoint: "https://127.0.0.1:1280"
2022-12-07 19:58:05 +01:00
username: admin
password: "XO0xHp75uuyeireO2xmmVlK91T7B9fpD"
# you can use certbot to renew the wildcard cert for the controller with a DNS provider API token or front this `zrok` # controller with Caddy
#tls:
# cert_path: "/Path/To/Cert/zrok.crt"
# key_path: "/Path/To/Cert/zrok.key"
2022-12-07 19:58:05 +01:00
```
2023-01-19 15:53:28 +01:00
The `admin` section defines privileged administrative credentials and must be set in the `ZROK_ADMIN_TOKEN` environment variable in shells where you want to run `zrok admin`.
2022-12-07 19:58:05 +01:00
2023-06-13 20:13:39 +02:00
The `endpoint` section defines where your `zrok` controller will listen.
2022-12-07 19:58:05 +01:00
The `store` section defines the local `sqlite3` database used by the controller.
The `ziti` section defines how the `zrok` controller should communicate with your OpenZiti installation. When using the OpenZiti quickstart, an administrative password will be generated; the `password` in the `ziti` stanza should reflect this password.
2022-12-07 19:58:05 +01:00
2023-06-23 21:56:20 +02:00
:::note
2024-05-03 16:33:13 +02:00
Be sure to see the [reference configuration at `etc/ctrl.yml`](../../../../etc/ctrl.yml) for the complete documentation of the current configuration file format for the `zrok` controller and service instance components.
2023-06-23 21:56:20 +02:00
2024-05-03 16:33:13 +02:00
See the separate guides on [configuring metrics](/guides/self-hosting/metrics-and-limits/configuring-metrics.md) and [configuring limits](/guides/self-hosting/metrics-and-limits/configuring-limits.md) for details about both of these specialized areas of service instance configuration.
2023-06-23 21:56:20 +02:00
:::
2022-12-07 19:58:05 +01:00
## Environment Variables
The `zrok` binaries are configured to work with the global `zrok.io` service, and default to using `api.zrok.io` as the endpoint for communicating with the service.
To work with a self-hosted `zrok` deployment, you'll need to set the `ZROK_API_ENDPOINT` environment variable to point to the address where your `zrok` controller will be listening, according to `endpoint` in the configuration file above.
2022-12-07 19:58:05 +01:00
In my case, I've set:
2023-01-19 15:53:28 +01:00
```bash
2023-06-13 20:13:39 +02:00
export ZROK_API_ENDPOINT=http://127.0.0.1:18080
2022-12-07 19:58:05 +01:00
```
2023-11-27 21:21:39 +01:00
[Read more about configuring your self-hosted `zrok` instance](/guides/self-hosting/instance-configuration.mdx).
## Bootstrap OpenZiti for zrok
2022-12-07 19:58:05 +01:00
With your OpenZiti network running and your configuration saved to a local file (I refer to mine as `etc/ctrl.yml` in these examples), you're ready to bootstrap the Ziti network.
2022-12-07 19:58:05 +01:00
Use the `zrok admin bootstrap` command to bootstrap like this:
2023-01-19 15:53:28 +01:00
```bash
2024-04-23 22:06:50 +02:00
$ zrok admin bootstrap etc/ctrl.yml
2022-12-07 19:58:05 +01:00
[ 0.002] INFO main.(*adminBootstrap).run: {
...
}
[ 0.002] INFO zrok/controller/store.Open: database connected
[ 0.006] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations
[ 0.006] INFO zrok/controller.Bootstrap: connecting to the ziti edge management api
[ 0.039] INFO zrok/controller.Bootstrap: creating identity for controller ziti access
[ 0.071] INFO zrok/controller.Bootstrap: controller identity: jKd8AINSz
[ 0.082] INFO zrok/controller.assertIdentity: asserted identity 'jKd8AINSz'
[ 0.085] INFO zrok/controller.assertErpForIdentity: asserted erps for 'ctrl' (jKd8AINSz)
[ 0.085] INFO zrok/controller.Bootstrap: creating identity for frontend ziti access
[ 0.118] INFO zrok/controller.Bootstrap: frontend identity: sqJRAINSiB
[ 0.119] INFO zrok/controller.assertIdentity: asserted identity 'sqJRAINSiB'
[ 0.120] INFO zrok/controller.assertErpForIdentity: asserted erps for 'frontend' (sqJRAINSiB)
[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance
2022-12-07 19:58:05 +01:00
[ 0.123] INFO zrok/controller.assertZrokProxyConfigType: found 'zrok.proxy.v1' config type with id '33CyjNbIepkXHN5VzGDA8L'
[ 0.124] INFO zrok/controller.assertMetricsService: creating 'metrics' service
[ 0.126] INFO zrok/controller.assertMetricsService: asserted 'metrics' service (5RpPZZ7T8bZf1ENjwGiPc3)
[ 0.128] INFO zrok/controller.assertMetricsSerp: creating 'metrics' serp
[ 0.130] INFO zrok/controller.assertMetricsSerp: asserted 'metrics' serp
[ 0.134] INFO zrok/controller.assertCtrlMetricsBind: creating 'ctrl-metrics-bind' service policy
[ 0.135] INFO zrok/controller.assertCtrlMetricsBind: asserted 'ctrl-metrics-bind' service policy
[ 0.138] INFO zrok/controller.assertFrontendMetricsDial: creating 'frontend-metrics-dial' service policy
[ 0.140] INFO zrok/controller.assertFrontendMetricsDial: asserted 'frontend-metrics-dial' service policy
[ 0.140] INFO main.(*adminBootstrap).run: bootstrap complete!
```
The `zrok admin bootstrap` command configures the `zrok` database, the necessary OpenZiti identities, and all of the OpenZiti policies required to run a `zrok` service.
2022-12-07 19:58:05 +01:00
Notice this warning:
```
[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance
2022-12-07 19:58:05 +01:00
```
2024-04-23 20:33:41 +02:00
If you find it necessary to re-run the `zrok admin bootstrap` command, you may need to add the `--skip-frontend` flag to avoid re-creating the default `public` frontend's Ziti identity and router policy.
## Run zrok Controller
2022-12-07 19:58:05 +01:00
The `zrok` bootstrap process wants us to create a "public frontend" for our service. `zrok` uses public frontends to allow users to specify where they would like public traffic to ingress from.
The `zrok admin create frontend` command requires a running `zrok` controller, so let's start that up first:
2023-01-19 15:53:28 +01:00
```bash
$ zrok controller etc/ctrl.yml
2022-12-07 19:58:05 +01:00
[ 0.003] INFO main.(*controllerCommand).run: {
...
}
[ 0.016] INFO zrok/controller.inspectZiti: inspecting ziti controller configuration
[ 0.048] INFO zrok/controller.findZrokProxyConfigType: found 'zrok.proxy.v1' config type with id '33CyjNbIepkXHN5VzGDA8L'
[ 0.048] INFO zrok/controller/store.Open: database connected
[ 0.048] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations
[ 0.049] INFO zrok/controller.(*metricsAgent).run: starting
[ 0.064] INFO zrok/rest_server_zrok.setupGlobalMiddleware: configuring
[ 0.064] INFO zrok/ui.StaticBuilder: building
[ 0.065] INFO zrok/rest_server_zrok.(*Server).Logf: Serving zrok at http://[::]:18080
[ 0.085] INFO zrok/controller.(*metricsAgent).listen: started
```
## Create zrok Frontend
2023-01-19 15:53:28 +01:00
With our `ZROK_ADMIN_TOKEN` and `ZROK_API_ENDPOINT` environment variables set, we can create our public frontend like this:
2022-12-07 19:58:05 +01:00
2023-01-19 15:53:28 +01:00
```bash
$ zrok admin create frontend sqJRAINSiB public http://{token}.zrok.quigley.com:8080
2022-12-07 19:58:05 +01:00
[ 0.037] INFO main.(*adminCreateFrontendCommand).run: created global public frontend 'WEirJNHVlcW9'
```
The id of the frontend was emitted earlier in by the `zrok` controller when we ran the bootstrap command. If you don't have that log message the you can find the id again with the `ziti` CLI like this:
```bash
2024-04-23 22:06:50 +02:00
# log in as admin (example)
ziti edge login localhost:1280 -u admin -p XO0xHp75uuyeireO2xmmVlK91T7B9fpD
# list Ziti identities created by the quickstart and bootstrap
ziti edge list identities
```
2024-04-23 20:33:41 +02:00
The id is shown for the frontend identity named "public."
Nice work! The `zrok` controller is fully configured now that you have created the `zrok` frontend.
2022-12-07 19:58:05 +01:00
2023-01-19 15:53:28 +01:00
## Configure the Public Frontend
Create an http frontend configuration file in `etc/http-frontend.yml`.
2023-01-19 15:53:28 +01:00
```yaml
v: 3
host_match: zrok.quigley.com
address: 0.0.0.0:8080
2023-01-19 15:53:28 +01:00
```
This frontend config file has a `host_match` pattern that represents the DNS zone you're using with this instance of `zrok`. Incoming HTTP requests with a matching `Host` header will be handled by this frontend. You may also specify the interface address where the frontend will listen for public access requests.
The frontend does not provide server TLS, but you may front the server with a reverse proxy. The reverse proxy must forward the `Host` header supplied by the viewer. This example will expose the non-TLS listener for the frontend.
2024-05-03 16:33:13 +02:00
You can also specify an `oauth` configuration in this file, full details of are found in [OAuth Public Frontend Configuration](/guides/self-hosting/oauth/configuring-oauth.md#configuring-your-public-frontend).
2022-12-07 19:58:05 +01:00
## Start Public Frontend
In another terminal window, run:
2023-01-19 15:53:28 +01:00
```bash
$ zrok access public etc/http-frontend.yml
2022-12-07 19:58:05 +01:00
[ 0.002] INFO main.(*accessPublicCommand).run: {
...
}
2024-04-23 20:33:41 +02:00
[ 0.002] INFO zrok/endpoints/public_frontend.newMetricsAgent: loaded 'public' identity
2022-12-07 19:58:05 +01:00
```
The `zrok` frontend uses the `public` identity created during the bootstrap process to securely access zrok backends. to provide public access for the `zrok` deployment. It is expected that the configured listener for this frontend corresponds to the DNS template specified when creating the public frontend record above.
## Create a User Account
With our `ZROK_ADMIN_TOKEN` and `ZROK_API_ENDPOINT` environment variables set, we can create our first user account.
```bash
zrok admin create account <email> <password>
```
The output is the account token you will use to enable each device's zrok environment.
```buttonless title="Example output"
SuGzRPjVDIcF
```
## Invite Additional Users
2022-12-07 19:58:05 +01:00
Offer this onboarding method to your users if you have configured an email-sending service in your `zrok` controller configuration.
2022-12-07 19:58:05 +01:00
2023-01-19 15:53:28 +01:00
```bash
2022-12-07 19:58:05 +01:00
$ zrok invite
New Email: user@domain.com
Confirm Email: user@domain.com
invitation sent to 'user@domain.com'!
2022-12-07 19:58:05 +01:00
```
If you look at the console output from your `zrok` controller, you'll see a message like this:
```
[ 238.168] INFO zrok/controller.(*inviteHandler).Handle: account request for 'user@domain.com' has registration token 'U2Ewt1UCn3ql'
2022-12-07 19:58:05 +01:00
```
You can access your `zrok` controller's registration UI by pointing a web browser at:
```
http://localhost:18080/register/U2Ewt1UCn3ql
```
The UI will ask you to set a password for your new account. Go ahead and do that.
After doing that, I see the following output in my controller console:
```
[ 516.778] INFO zrok/controller.(*registerHandler).Handle: created account 'user@domain.com' with token 'SuGzRPjVDIcF'
2022-12-07 19:58:05 +01:00
```
Keep track of the token listed above (`SuGzRPjVDIcF`). We'll use this to enable our shell for this `zrok` deployment.
## Enable Your Environment
On another device that can reach your Linux server by FQDN, configure the API endpoint and enable the environment with the account token you received when you created the first user account.
```bash
export ZROK_API_ENDPOINT=https://zrok.quigley.com
# or
zrok config set apiEndpoint https://zrok.quigley.com
```
2022-12-07 19:58:05 +01:00
```bash
zrok enable SuGzRPjVDIcF
```
```buttonless title="Example output"
2022-12-07 19:58:05 +01:00
zrok environment '2AS1WZ3Sz' enabled for 'SuGzRPjVDIcF'
```
```bash
zrok status --secrets
```
```buttonless title="Example output"
Config:
CONFIG VALUE SOURCE
apiEndpoint https://zrok.quigley.com env
Environment:
PROPERTY VALUE
Secret Token SuGzRPjVDIcF
Ziti Identity 2AS1WZ3Sz
```
2023-01-19 04:44:01 +01:00
Congratulations. You have a working `zrok` environment!