Containers
Run The OpenZiti Tunneler with Docker
Contents
- Conventions
- Use cases:
Conventions
Configuring the OpenZiti Identity
It is necessary to supply an identity enrollment token or an enrolled identity configuration JSON to the container as a volume-mounted file or as environment variables. The following variable, volumes, and files are common to both container images described below.
Configuration with Environment Variable
ZITI_IDENTITY_JSON
: This is the identity represented as JSON. This variable overrides other methods of supplying the identity JSON. It is not advisable to mount a volume on the container filesystem when using this method because the identity is written to a temporary file and will cause an error if the file already exists.
Configuration with Files from Mounted Volume
You may bind a host directory to the container filesystem in /ziti-edge-tunnel
to supply the token JWT file or configuration JSON file. If you provide a token JWT file, the entrypoint script will enroll the identity during container startup. The entrypoint script will write the identity configuration JSON file in the same directory with a filename like ${ZITI_IDENTITY_BASENAME}.json
.
ZITI_IDENTITY_BASENAME
: the file basename (without the filename suffix) of the enrollment (.jwt) and identity (.json) files the tunneler will useZITI_ENROLL_TOKEN
: Optionally, you may supply the enrollment token JWT as a string if${ZITI_IDENTITY_BASENAME}.jwt
is not mountedZITI_IDENTITY_WAIT
: Optionally, you may configure the container to wait max seconds for the JWT or JSON file to appear in the mounted volume
Use Case: Hosting OpenZiti Services
This use case involves deploying the OpenZiti tunneler as a reverse proxy to publish regular network servers to your OpenZiti Network. You may locate the published servers in a Docker bridge network (use network mode bridge
) or the Docker host's network (use network mode host
). See the Linux tunneler doc for general info about the OpenZiti tunneler. Use the openziti/ziti-host
container image for this case.
Container Image openziti/ziti-host
This image runs ziti-edge-tunnel run-host
to invoke the hosting-only mode of the tunneler. The main difference from the parent image (openziti/ziti-edge-tunnel
) is the command argument and run-as user. This container runs as "nobody" and doesn't require special privileges.
Image Tags for openziti/ziti-host
The openziti/ziti-host
image is published in Docker Hub and automatically updated with new releases. You may subscribe to :latest
(default) or pin a version for stability e.g. :0.19.11
.
Dockerfile for openziti/ziti-host
The Dockerfile for openziti/ziti-host
is ./Dockerfile.ziti-host.
Hosting an OpenZiti Service with openziti/ziti-host
Publish servers that are reachable on the Docker host's network, e.g., tcp:localhost:54321
:
# identity file on Docker host is mounted in container: /opt/openziti/etc/identities/my-ziti-identity.json
docker run \
--name ziti-host \
--rm \
--network=host \
--env ZITI_IDENTITY_BASENAME="my-ziti-identity" \
--volume /opt/openziti/etc/identities:/ziti-edge-tunnel \
openziti/ziti-host
Publish servers inside the same Docker bridge network, e.g., tcp:my-docker-service:80
:
# identity file on Docker host is stuffed in env var: /opt/openziti/etc/identities/my-ziti-identity.json
docker run \
--name ziti-host \
--rm \
--network=my-docker-bridge \
--env ZITI_IDENTITY_JSON="$(< /opt/openziti/etc/identities/my-ziti-identity.json)" \
openziti/ziti-host
This example uses the included Docker Compose project to illustrate publishing a server container to your OpenZiti Network.
Create an OpenZiti Config with type
intercept.v1
.{
"addresses": [
"hello-docker.ziti"
],
"protocols": [
"tcp"
],
"portRanges": [
{
"low": 80,
"high": 80
}
]
}Create an OpenZiti Config with type
host.v1
{
"port": 80,
"address": "hello",
"protocol": "tcp"
}Create a service associating the two configs with a role attribute like "#HelloServices."
Create an identity for your client tunneler named "MyClient" and load the identity.
Create an identity named "DockerHost" and download the enrollment token in the same directory as
docker-compose.yml
, i.e., "DockerHost.jwt."Create a Bind service policy assigning "#HelloServices" to be bound by "@DockerHost."
Create a Dial service policy granting access to "#HelloServices" to your client tunneler's identity "@MyClient."
Run the demo server
docker-compose up --detach hello
Run the tunneler
ZITI_IDENTITY_JSON="$(< /tmp/my-ziti-id.json)" docker-compose up --detach ziti-host
# debug
ZITI_IDENTITY_JSON="$(< /tmp/my-ziti-id.json)" docker-compose run ziti-host run-host --verbose=4Access the demo server via your OpenZiti Network: http://hello-docker.ziti
Troubleshooting openziti/ziti-host
You may pass additional args by supplying the run-host
mode and args when the container is run.
docker run \
--name ziti-host \
--rm \
--network=my-docker-bridge \
--env ZITI_IDENTITY_JSON="$(< /opt/openziti/etc/identities/my-ziti-identity.json)" \
openziti/ziti-host \
run-host --verbose=4
Docker Compose Examples for openziti/ziti-host
Get a single, enrolled identity configuration from an environment variable. You could define the variable with an .env
file in the same directory as docker-compose.yml
.
version: "3.9"
services:
ziti-host:
image: openziti/ziti-host
environment:
- ZITI_IDENTITY_JSON
Configure a single, enrolled identity from the host filesystem directory in the same directory as docker-compose.yml
.
In this example, the file ziti_id.jwt
exists and is used to enroll on the first run, producing ziti_id.json
, the identity configuration file. Subsequent runs will use only the enrolled identity's JSON configuration file.
version: "3.9"
services:
ziti-host:
image: openziti/ziti-host
volumes:
- .:/ziti-edge-tunnel
environment:
- ZITI_IDENTITY_BASENAME=ziti_id
Configure all enrolled identities from a named volume.
This example loads all files named *.json from the mounted volume.
version: "3.9"
services:
ziti-host:
image: openziti/ziti-host
volumes:
- ziti-identities:/ziti-edge-tunnel
volumes:
ziti-identities:
Enroll a single identity with a token from an environment variable and store in a named volume.
version: "3.9"
services:
ziti-host:
image: openziti/ziti-host
volumes:
- ziti-identity:/ziti-edge-tunnel
environment:
- ZITI_IDENTITY_BASENAME=ziti_id
- ZITI_ENROLL_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbSI6Im90dCIsImV4cCI6MTY3MDAwEFQ2NywiaXNzIjoiaHR0cHM6Ly83Y2U3ZTQyNC02YTkyLTRmZjItOTQ1OS1lYmJiYTMyMzQ2ZmEucHJvZHVjdGlvbi5uZXRmb3VuZHJ5LmlvOjQ0MyIsImp0aSI6ImQ0YjczZjFlLTRkOWEtNDk0ZC04NGQxLTQ2OWE1MGQyYzhmMCIsInN1YiI6ImdXdkQwaTd5RDkifQ.R5t2hoH0W1vJUn78_O8azoJ05FWLLSh6J3Q1XaDOidaYgDOWcLm7YiV99rymnjSjRC86IjNsAyZK678_D2dqyefR3VBI8LepamZ5jVSAcDFCF3Swk_jszcHDqcYs2YCucr6qrwsv8NTqEdUAJ8NVOiRaZbGhSuBvXTmWilCkCLcL7R4tXpIHakM_2WA4_tmwdbN8i7SGPPAB6pZOK_xDW10nBjg5Fe3Of_-53Gd-3swm9D3Yms1iIPBfMIQUWNzYaOCBa8UvGo8d9JjvJKgTlkMwZHL3hayzAuVEXoR1-LbA1t1Nhd8FgjvuL-YxN0XLaA3koL-FijL7ehWZoyUYPuO3xi63SQpbO-oDtX89jvGLMVercZBscXQsmCkDcj8OAnTb3Czb8HmsHgfydqvT6epUNFxFe_fSGz-CuGIuFBQwygfpBriGBnwVk8dnIJt7Wl75jPR8v-NImIIv1dKCI_ZajlsJ5l8D4OGnj76pBs3Wu7Hq1zxAbJ8HPJmi_ywTHAHVJVghifRTIR6_SyfeZGsHDY9s8YH5ErYvarBvMxwPCmjMMY3SKM_YOPG0u1c-KKByS3m7x7qia6P1ShWwGkbMmY722iFeVvoGN7SD51CkZiqWHClhBtdDv6_1K7y62KEmiX0D4YHXoikNqMCoPwa4yKyDRzoO8DKcAzaVRRg
volumes:
ziti-identity:
Kubernetes Deployments for openziti/ziti-host
Refer to the workload tunneling guides for Kubernetes.
Use Case: Intercepting Proxy and Nameserver
This use case involves deploying the OpenZiti tunneler as an intercepting proxy with a built-in nameserver. Use the openziti/ziti-edge-tunnel
container image for this case.
The "run" mode requires elevated privileges to configure the OS with a DNS resolver and IP routes.
Container Image openziti/ziti-edge-tunnel
This image runs ziti-edge-tunnel run
, the intercepting proxy mode of the tunneler. The Red Hat 8 Universal Base Image (UBI) is the base image of this container.
See the Linux tunneler doc for general info about the OpenZiti tunneler.
Tags for openziti/ziti-edge-tunnel
The container image openziti/ziti-edge-tunnel
is published in Docker Hub and automatically updated with new releases. You may subscribe to :latest
(default) or pin a version for stability, e.g., :0.19.11
.
Dockerfile for openziti/ziti-edge-tunnel
The Dockerfile for openziti/ziti-edge-tunnel
is ./Dockerfile.base.
Accessing OpenZiti Services with openziti/ziti-edge-tunnel
Intercepting proxy run
mode captures DNS names and layer-4 traffic that match authorized destinations.
# current directory contains enrollment token file ziti_id.jwt
docker run \
--name ziti-tun \
--network host \
--privileged \
--volume ${PWD}:/ziti-edge-tunnel/ \
--volume "/var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket" \
--device "/dev/net/tun:/dev/net/tun" \
--env ZITI_IDENTITY_BASENAME=ziti_id \
openziti/ziti-edge-tunnel
Troubleshooting openziti/ziti-edge-tunnel
You may pass additional args by supplying the run
mode followed by args when the container is run.
docker run \
--name ziti-edge-tunnel \
--network host \
--privileged \
--volume ${PWD}:/ziti-edge-tunnel/ \
--volume "/var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket" \
--device "/dev/net/tun:/dev/net/tun" \
--env ZITI_IDENTITY_BASENAME=ziti_id \
openziti/ziti-edge-tunnel \
run --verbose=4
Docker Compose Examples for openziti/ziti-edge-tunnel
This example uses the Docker Compose project included in this repo.
# enrolled identity file ziti_id.json is in the same directory as docker-compose.yml
ZITI_IDENTITY_BASENAME=ziti_id docker-compose run ziti-tun
This example uses a single, enrolled identity configuration file ziti_id.json
in the same directory as docker-compose.yml
.
version: "3.9"
services:
ziti-tun:
image: openziti/ziti-edge-tunnel
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- .:/ziti-edge-tunnel
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
environment:
- ZITI_IDENTITY_BASENAME=ziti_id
- PFXLOG_NO_JSON=true # suppress JSON logging
network_mode: host
privileged: true