zrok frontdoor
zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends.
Overview
zrok frontends are the parts of zrok that proxy incoming public web traffic to zrok backend shares via OpenZiti. When you use zrok with a zrok.io
frontend, you're using zrok frontdoor. zrok.io
is zrok-as-a-service by NetFoundry, the team behind OpenZiti. You need a free account to use zrok frontdoor.
Choose your OS
Choose between installing the Linux package or running zrok with Docker (Linux, macOS, or Windows).
- Linux
- macOS
- Windows
On Linux, zrok frontdoor is implemented natively as a system service provided by the zrok-share
DEB or RPM package.
If you'd prefer to run zrok in Docker instead of installing the package then you can follow the Docker instructions. With Docker, the steps are the same for Linux, macOS, and Windows.
Goal
Proxy a reserved public subdomain to a backend target with an always-on Linux system service.
How it Works
The zrok-share
package creates a zrok-share.service
unit in systemd. The administrator edits the service's configuration file to specify the:
- zrok environment enable token
- target URL or files to be shared and backend mode, e.g.
proxy
- authentication options, if wanted
When the service starts it will:
- enable the zrok environment unless
/var/lib/zrok-share/.zrok/environment.json
exists - reserve a public subdomain for the service unless
/var/lib/zrok-share/.zrok/reserved.json
exists - start sharing the target specified as
ZROK_TARGET
in the environment file
Installation
-
Set up
zrok
's Linux package repository by following the Linux install guide, or run this one-liner to complete the repo setup and install packages.curl -sSLf https://get.openziti.io/install.bash \
| sudo bash -s zrok-share -
If you set up the repository by following the guide, then also install the
zrok-share
package. This package provides the systemd service.Ubuntu, Debiansudo apt install zrok-share
Fedora, Rockysudo dnf install zrok-share
Ansible Playbook
- name: Set up zrok Package Repo
gather_facts: true
hosts: all
become: true
tasks:
- name: Set up apt repo
when: ansible_os_family == "Debian"
block:
- name: Install playbook dependencies
ansible.builtin.package:
name:
- gnupg
state: present
- name: Fetch armored pubkey
ansible.builtin.uri:
url: https://get.openziti.io/tun/package-repos.gpg
return_content: 'yes'
register: armored_pubkey
- name: Dearmor pubkey
ansible.builtin.shell: >
gpg --dearmor --output /usr/share/keyrings/openziti.gpg <<< "{{
armored_pubkey.content }}"
args:
creates: /usr/share/keyrings/openziti.gpg
executable: /bin/bash
- name: Set pubkey filemode
ansible.builtin.file:
path: /usr/share/keyrings/openziti.gpg
mode: a+rX
- name: Install OpenZiti repo deb source
ansible.builtin.copy:
dest: /etc/apt/sources.list.d/openziti-release.list
content: >
deb [signed-by=/usr/share/keyrings/openziti.gpg]
https://packages.openziti.org/zitipax-openziti-deb-stable debian
main
- name: Refresh Repo Sources
ansible.builtin.apt:
update_cache: 'yes'
cache_valid_time: 3600
- name: Set up yum repo
when: ansible_os_family == "RedHat"
block:
- name: Install OpenZiti repo rpm source
ansible.builtin.yum_repository:
name: OpenZitiRelease
description: OpenZiti Release
baseurl: >-
https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch
enabled: 'yes'
gpgkey: >-
https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch/repodata/repomd.xml.key
repo_gpgcheck: 'yes'
gpgcheck: 'no'
- name: Install zrok-share package
gather_facts: false
hosts: all
become: true
tasks:
- name: Install zrok-share
ansible.builtin.package:
name: zrok-share
state: present
- name: Copy env config from Ansible controller to target
copy:
dest: /opt/openziti/etc/zrok/zrok-share.env
src: /opt/openziti/etc/zrok/zrok-share.env
- name: Enable and restart service
systemd:
name: zrok-share
enabled: yes
state: restarted
daemon_reload: yes
- name: Wait for service
systemd:
name: zrok-share
state: started
register: service_status
until: service_status.status.ActiveState == 'active'
retries: 30
delay: 1
Enable
Save the enable token from the zrok console in the configuration file.
ZROK_ENABLE_TOKEN="14cbfca9772f"
Name your Share
This unique name becomes part of the domain name of the share, e.g. https://my-prod-app.in.zrok.io
. A random name is generated if you don't specify one.
ZROK_UNIQUE_NAME="my-prod-app"
Use Cases
You may change the target for the current backend mode, e.g. proxy
, by editing the configuration file and restarting the service. The reserved subdomain will remain the same.
You may switch between backend modes or change authentication options by deleting /var/lib/zrok-share/.zrok/reserved.json
and restarting the service. A new subdomain will be reserved.
Proxy a Web Server
Proxy a reserved subdomain to an existing web server. The web server could be on a private network or on the same host as zrok.
ZROK_TARGET="http://127.0.0.1:3000"
ZROK_BACKEND_MODE="proxy"
If your HTTPS server has an unverifiable TLS server certificate then you must set --insecure
.
ZROK_INSECURE="--insecure"
Serve Static Files
Run zrok's embedded web server to serve the files in a directory. If there's an index.html
file in the directory then visitors will see that web page in their browser, otherwise they'll see a generated index of the files. The directory must be readable by 'other', e.g. chmod -R o+rX /var/www/html
.
ZROK_TARGET="/var/www/html"
ZROK_BACKEND_MODE="web"
Caddy Server
Use zrok's built-in Caddy server to serve static files or as a reverse proxy to multiple web servers with various HTTP routes or as a load-balanced set. A sample Caddyfile is available in the path shown.
ZROK_TARGET="/opt/openziti/etc/zrok/multiple_upstream.Caddyfile"
ZROK_BACKEND_MODE="caddy"
Network Drive
This uses zrok's drive
backend mode to serve a directory of static files as a virtual network drive. The directory must be readable by 'other', e.g. chmod -R o+rX /usr/share/doc
.
ZROK_TARGET="/usr/share/doc"
ZROK_BACKEND_MODE="drive"
Learn more about this feature in this blog post.
Authentication
You can limit access to certain email addresses with OAuth or require a password.
OAuth
You can require that visitors authenticate with an email address that matches at least one of the suffixes you specify. Add the following to the configuration file.
ZROK_OAUTH_PROVIDER="github" # or google
ZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"
Password
Enable HTTP basic authentication by adding the following to the configuration file.
ZROK_BASIC_AUTH="user:passwd"
Start the Service
Start the service, and check the zrok console or the service log for the reserved subdomain.
sudo systemctl enable --now zrok-share.service
sudo systemctl restart zrok-share.service
journalctl -u zrok-share.service
Compatibility
The Linux distribution must have a package manager that understands the .deb
or .rpm
format and be running systemd v232 or newer. The service was tested with:
- Ubuntu 20.04, 22.04, 23.04
- Debian 11 12
- Rocky 8, 9
- Fedora 37, 38
Package Contents
The files included in the zrok-share
package are sourced here in GitHub.
On macOS, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service.
Goal
Proxy a reserved public subdomain to a backend target with an always-on Docker Compose service.
How it Works
The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend target.
When the project runs it will:
- enable a zrok environment unless
/mnt/.zrok/environment.json
exists in thezrok_env
volume - reserve a public subdomain for the service unless
/mnt/.zrok/reserved.json
exists - start sharing the target specified in the
ZROK_TARGET
environment variable
Create the Docker Project
-
Make a folder on your computer to use as a Docker Compose project for your zrok public share with a reserved subdomain and switch to the new directory in your terminal.
-
Download the reserved public share
compose.yml
project file into the same directory. -
Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named
.env
in the same folder like this:.envZROK_ENABLE_TOKEN="8UL9-48rN0ua"
-
Name the Share
This unique name becomes part of the domain name of the share, e.g.
https://my-prod-app.in.zrok.io
. A random name is generated if you don't specify one..envZROK_UNIQUE_NAME="my-prod-app"
-
Run the Compose project to start sharing the built-in demo web server. Be sure to
--detach
so the project runs in the background if you want it to auto-restart when your computer reboots.docker compose up --detach
-
Get the public share URL from the output of the
zrok-share
service or by peeking in the zrok console where the share will appear in the graph.docker compose logs zrok-share
This concludes the minimum steps to begin sharing the demo web server. Read on to learn how to pivot to sharing any website or web service by leveraging additional zrok backend modes.
Proxy Any Web Server
The simplest way to share your existing HTTP server is to set ZROK_TARGET
(e.g. https://example.com
) in the environment of the docker compose up
command. When you restart the share will auto-configure for that URL.
ZROK_TARGET="http://example.com:8080"
docker compose down && docker compose up
Require Authentication
You can require a password or an OAuth login with certain email addresses.
OAuth Email
You can allow specific email addresses or an email domain by setting ZROK_OAUTH_PROVIDER
to github
or google
and
ZROK_SHARE_OPTS
to specify additional command-line options to zrok reserve public
. Read more about the OAuth
features in this blog post.
ZROK_OAUTH_PROVIDER="github"
ZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"
Caddy is Powerful
The reserved public share project uses zrok's default backend mode, proxy
. Another backend mode, caddy
, accepts a path to a Caddyfile as the value of ZROK_TARGET
(zrok Caddyfile examples).
Caddy is the most powerful and flexible backend mode in zrok. You must reserve a new public subdomain whenever you switch the backend mode, so using caddy
reduces the risk that you'll have to share a new frontend URL with your users.
With Caddy, you can balance the workload for websites or web services or share static sites and files or all of the above at the same time. You can update the Caddyfile and restart the Docker Compose project to start sharing the new configuration with the same reserved public subdomain.
-
Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer.
Caddyfilehttp:// {
# zrok requires this bind address template
bind {{ .ZrokBindAddress }}
reverse_proxy /* {
to http://httpbin1:8080 http://httpbin2:8080
lb_policy weighted_round_robin 3 2
}
} -
Create a file
compose.override.yml
. This example adds twohttpbin
containers for load balancing, and mounts the Caddyfile into the container.compose.override.ymlservices:
httpbin1:
image: mccutchen/go-httpbin # 8080/tcp
httpbin2:
image: mccutchen/go-httpbin # 8080/tcp
zrok-share:
volumes:
- ./Caddyfile:/mnt/.zrok/Caddyfile -
Start a new Docker Compose project or delete the existing state volume.
docker compose down --volumes
If you prefer to keep using the same zrok environment with the new share then delete /mnt/.zrok/reserved.json
instead of the entire volume.
-
Run the project to load the new configuration.
docker compose up --detach
-
Note the new reserved share URL from the log.
docker compose logs zrok-share
On Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service.
Goal
Proxy a reserved public subdomain to a backend target with an always-on Docker Compose service.
How it Works
The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend target.
When the project runs it will:
- enable a zrok environment unless
/mnt/.zrok/environment.json
exists in thezrok_env
volume - reserve a public subdomain for the service unless
/mnt/.zrok/reserved.json
exists - start sharing the target specified in the
ZROK_TARGET
environment variable
Create the Docker Project
-
Make a folder on your computer to use as a Docker Compose project for your zrok public share with a reserved subdomain and switch to the new directory in your terminal.
-
Download the reserved public share
compose.yml
project file into the same directory. -
Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named
.env
in the same folder like this:.envZROK_ENABLE_TOKEN="8UL9-48rN0ua"
-
Name the Share
This unique name becomes part of the domain name of the share, e.g.
https://my-prod-app.in.zrok.io
. A random name is generated if you don't specify one..envZROK_UNIQUE_NAME="my-prod-app"
-
Run the Compose project to start sharing the built-in demo web server. Be sure to
--detach
so the project runs in the background if you want it to auto-restart when your computer reboots.docker compose up --detach
-
Get the public share URL from the output of the
zrok-share
service or by peeking in the zrok console where the share will appear in the graph.docker compose logs zrok-share
This concludes the minimum steps to begin sharing the demo web server. Read on to learn how to pivot to sharing any website or web service by leveraging additional zrok backend modes.
Proxy Any Web Server
The simplest way to share your existing HTTP server is to set ZROK_TARGET
(e.g. https://example.com
) in the environment of the docker compose up
command. When you restart the share will auto-configure for that URL.
ZROK_TARGET="http://example.com:8080"
docker compose down && docker compose up
Require Authentication
You can require a password or an OAuth login with certain email addresses.
OAuth Email
You can allow specific email addresses or an email domain by setting ZROK_OAUTH_PROVIDER
to github
or google
and
ZROK_SHARE_OPTS
to specify additional command-line options to zrok reserve public
. Read more about the OAuth
features in this blog post.
ZROK_OAUTH_PROVIDER="github"
ZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"
Caddy is Powerful
The reserved public share project uses zrok's default backend mode, proxy
. Another backend mode, caddy
, accepts a path to a Caddyfile as the value of ZROK_TARGET
(zrok Caddyfile examples).
Caddy is the most powerful and flexible backend mode in zrok. You must reserve a new public subdomain whenever you switch the backend mode, so using caddy
reduces the risk that you'll have to share a new frontend URL with your users.
With Caddy, you can balance the workload for websites or web services or share static sites and files or all of the above at the same time. You can update the Caddyfile and restart the Docker Compose project to start sharing the new configuration with the same reserved public subdomain.
-
Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer.
Caddyfilehttp:// {
# zrok requires this bind address template
bind {{ .ZrokBindAddress }}
reverse_proxy /* {
to http://httpbin1:8080 http://httpbin2:8080
lb_policy weighted_round_robin 3 2
}
} -
Create a file
compose.override.yml
. This example adds twohttpbin
containers for load balancing, and mounts the Caddyfile into the container.compose.override.ymlservices:
httpbin1:
image: mccutchen/go-httpbin # 8080/tcp
httpbin2:
image: mccutchen/go-httpbin # 8080/tcp
zrok-share:
volumes:
- ./Caddyfile:/mnt/.zrok/Caddyfile -
Start a new Docker Compose project or delete the existing state volume.
docker compose down --volumes
If you prefer to keep using the same zrok environment with the new share then delete /mnt/.zrok/reserved.json
instead of the entire volume.
-
Run the project to load the new configuration.
docker compose up --detach
-
Note the new reserved share URL from the log.
docker compose logs zrok-share
Concepts
Overview of zrok reserved shares