Skip to content

Installation with Docker / Podman (Asset Mode)

XplicitTrust provides an official container image for running the agent in containerized environments such as Docker, Podman, or Kubernetes.

The container image is available at cr-public.xplicittrust.com/xtna-agent and supports amd64, arm64, and armhf architectures.

Prerequisites

Network capabilities

The container must run with elevated network capabilities:

  • NET_ADMIN — required for WireGuard tunnel management and firewall rules
  • NET_RAW — required for raw socket operations

Rootful mode required

The container must run in rootful mode (e.g. with sudo). Rootless Docker/Podman cannot grant real network capabilities outside the user namespace.

The /dev/net/tun device

The agent builds a WireGuard tunnel and therefore needs access to the host's TUN device, /dev/net/tun. Without it the agent starts but fails to bring up the tunnel, logging:

CreateTUN("xt0") failed; /dev/net/tun does not exist

This applies even though the agent uses a userspace WireGuard implementation — the userspace tunnel still attaches to a kernel TUN interface. A missing TUN device is the most common cause of an agent that registers successfully but never connects (and, as a side effect, installs no firewall rules, since those rules are scoped to the tunnel interface).

Two things are required:

  1. The tun kernel module must be loaded on the host. It usually is, but on minimal hosts you may need to load it (and persist it across reboots):

    sudo modprobe tun
    echo tun | sudo tee /etc/modules-load.d/tun.conf
    
  2. The device must be passed into the container with --device /dev/net/tun (Docker/Podman) or the equivalent in your orchestrator. This is included in all the run commands below.

--device requires the host device to already exist

--device /dev/net/tun passes through an existing host device node. If the tun module isn't loaded on the host, /dev/net/tun doesn't exist and the container fails to start with an error like error gathering device information ... no such file or directory. Always ensure the host module (step 1) before relying on --device (step 2).

Installation

sudo docker pull cr-public.xplicittrust.com/xtna-agent:latest
sudo podman pull cr-public.xplicittrust.com/xtna-agent:latest

Configuration

See the xtna-util reference for a complete list of available flags.

The container accepts registration flags directly — no separate xtna-util step is needed.

Use token-based registration for headless or automated deployments:

  1. Go to the Admin Console settings page

  2. Create a new "Asset Creation Token", configure it, download and store it in a secure place

  3. Run the container with the token:

sudo docker run -d --restart unless-stopped \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  --device /dev/net/tun \
  cr-public.xplicittrust.com/xtna-agent:latest \
  -token <token> -domain <tenant-domain>

Registration flags are only used on first start. Once the asset is registered, the configuration is stored inside the container and the flags are ignored on subsequent runs.

Use device flow registration for interactive setups:

sudo docker run -it --restart unless-stopped \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  --device /dev/net/tun \
  cr-public.xplicittrust.com/xtna-agent:latest \
  -user <admin email address>

Open the URL shown in the terminal to authenticate. After successful registration, the container continues running in the foreground.

  1. Go to the Admin Console assets page

  2. Click Create new, fill out the form, click Apply

  3. Click the Download Config icon at the top of the form box:

    Download

  4. Place the configuration file in a host directory and mount it:

sudo mkdir -p /opt/xtna/my-asset
sudo cp xtna-*.xtconfig /opt/xtna/my-asset/
sudo docker run -d --restart unless-stopped \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  --device /dev/net/tun \
  -v /opt/xtna/my-asset:/etc/XplicitTrust \
  cr-public.xplicittrust.com/xtna-agent:latest

Persistent Configuration (Optional)

By default, the agent stores its configuration inside the container. If the container is removed, the configuration (including certificates and registration) is lost and the asset must be re-registered.

To persist configuration across container recreation, mount a host directory:

sudo mkdir -p /opt/xtna/my-asset
sudo docker run -d --restart unless-stopped \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  --device /dev/net/tun \
  -v /opt/xtna/my-asset:/etc/XplicitTrust \
  cr-public.xplicittrust.com/xtna-agent:latest \
  -token <token> -domain <tenant-domain>

Running multiple agents on one host

Each container needs its own configuration directory. Use a unique path per instance:

sudo docker run -d --name office-gw \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  --device /dev/net/tun \
  -v /opt/xtna/office-gw:/etc/XplicitTrust \
  cr-public.xplicittrust.com/xtna-agent:latest \
  -token <token-1> -domain <tenant-domain>

sudo docker run -d --name lab-gw \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  --device /dev/net/tun \
  -v /opt/xtna/lab-gw:/etc/XplicitTrust \
  cr-public.xplicittrust.com/xtna-agent:latest \
  -token <token-2> -domain <tenant-domain>

Registration Flags

Flag Description
-token <token> API key/token for unattended registration
-user <email> Admin email for interactive device flow registration
-domain <domain> Tenant domain (required with -token, optional with -user)
-name <name> Asset name (defaults to container hostname)
-api <url> API URL override (for on-premise deployments)

Docker Compose

services:
  xtna-agent:
    image: cr-public.xplicittrust.com/xtna-agent:latest
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - NET_RAW
    devices:
      - /dev/net/tun:/dev/net/tun
    volumes:
      - ./xtna-config:/etc/XplicitTrust
    # Only needed on first run for registration:
    # command: ["-token", "YOUR_TOKEN", "-domain", "your-domain.com"]

Updates

The container includes a self-updating launcher that automatically updates the agent service to the latest version. No manual image pulls are required for agent updates.

To update the launcher itself, pull a new image version:

sudo docker pull cr-public.xplicittrust.com/xtna-agent:latest
sudo docker restart <container-name>
sudo podman pull cr-public.xplicittrust.com/xtna-agent:latest
sudo podman restart <container-name>

Kubernetes

For Kubernetes deployments, use a DaemonSet or Deployment with the required security context:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: xtna-agent
spec:
  replicas: 1
  selector:
    matchLabels:
      app: xtna-agent
  template:
    metadata:
      labels:
        app: xtna-agent
    spec:
      containers:
        - name: xtna-agent
          image: cr-public.xplicittrust.com/xtna-agent:latest
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
                - NET_RAW
          volumeMounts:
            - name: config
              mountPath: /etc/XplicitTrust
            - name: tun
              mountPath: /dev/net/tun
      volumes:
        - name: config
          persistentVolumeClaim:
            claimName: xtna-config
        - name: tun
          hostPath:
            path: /dev/net/tun
            type: CharDevice

Provide the registration token via a Kubernetes Secret or environment variable in your deployment pipeline.

TUN device on Kubernetes

Kubernetes has no direct equivalent of --device, so the example above exposes /dev/net/tun via a hostPath volume of type CharDevice. The node must have the tun kernel module loaded (modprobe tun) and /dev/net/tun present, otherwise the pod will fail to mount the volume. Alternatively, use a TUN/TAP device plugin to avoid hostPath.

Troubleshooting

Container exits immediately

  • Ensure NET_ADMIN and NET_RAW capabilities are granted
  • Ensure the container runs in rootful mode (sudo)
  • Check logs: sudo docker logs <container-name>

"No configuration found" error

  • Provide registration flags (-token or -user) on first run, or mount a directory containing a valid configuration

Tunnel not working / CreateTUN("xt0") failed; /dev/net/tun does not exist

This means the agent registered but cannot create its WireGuard tunnel because the TUN device isn't available inside the container.

  • Confirm the device is present inside the container:
    sudo docker exec <container-name> ls -l /dev/net/tun
    
  • If it's missing, ensure both halves of the TUN prerequisite:
    1. The tun module is loaded on the host: sudo modprobe tun
    2. The container is started with --device /dev/net/tun (recreate the container — devices cannot be added to a running container):
      sudo docker run -d \
        --cap-add NET_ADMIN --cap-add NET_RAW \
        --device /dev/net/tun \
        cr-public.xplicittrust.com/xtna-agent:latest
      
  • If docker run itself fails with error gathering device information ... no such file or directory, the host is missing /dev/net/tun — load the tun module on the host first (step 1).

Reading the agent log

The container's launcher writes a combined log file at /etc/XplicitTrust/logs/xtna-service.log inside the container. This often shows the underlying cause more clearly than docker logs:

sudo docker exec <container-name> tail -f /etc/XplicitTrust/logs/xtna-service.log

VM or container templates

  • When cloning a VM or container that has XplicitTrust installed, make sure to exclude /etc/XplicitTrust/ and /etc/xt-machine-id from the template. Each instance must have its own identity.