Agent in a Container

In order for Pro Custodibus to monitor and manage a WireGuard interface that’s running in a Docker (or other OCI) container, the Pro Custodibus agent must also be run in the same container. You can build your own image for this, or you can use our pre-built agent image.

When run this way, the instructions from other parts of the documentation that refer to a WireGuard “host” should be read as referring to the container running WireGuard (and not the container’s own host).

The official Pro Custodibus agent image can be pulled from Docker Hub with the repository name procustodibus/agent. It supports the following platforms: linux/amd64, linux/arm64, linux/arm/v7, and linux/arm/v6. We update the latest version of the image weekly to pick up the latest security fixes for the embedded software.

To use this image, either the container’s host must be running the Linux kernel version 5.6 or newer, or the container’s host itself must have the WireGuard kernel module installed. For old kernels, this often requires compiling the WireGuard kernel module from source on the host.

The agent image is built from our base WireGuard image, which in turn is built from the base Alpine Linux image. The agent image is generated with the docker/agent.dockerfile from the agent source code.

Docker Run

The basic pattern for running the agent image with the docker run command is the following:

$ sudo docker run \
    --cap-add NET_ADMIN \
    --publish 51820:51820/udp \
    --name wireguard \
    --rm \
    --volume /srv/containers/wireguard/conf:/etc/wireguard:Z \
    docker.io/procustodibus/agent

 * /proc is already mounted
 * /run/lock: creating directory
 * /run/lock: correcting owner
   OpenRC 0.43.3.bf57debcde is starting up Linux 5.11.0-1020-aws (x86_64) [DOCKER]

 * Caching service dependencies ... [ ok ]
 * Starting WireGuard interface wg0 ...[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.1/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 10.0.0.2/32 dev wg0
 [ ok ]
 * Starting procustodibus-agent ... [ ok ]

These are what the above command arguments do:

  1. --cap-add NET_ADMIN: Grants the container the NET_ADMIN capability — this is required to start a WireGuard interface inside the container.

  2. --publish 51820:51820/udp: Forwards the public 51820 UDP port on the container’s host to the container’s 51820 UDP port — make sure the latter matches the ListenPort setting in the WireGuard config file (the former can be whatever port you want to expose publicly). When running multiple WireGuard interfaces in the same container, publish one port mapping for each interface.

  3. --name wireguard: Sets the container’s name to wireguard (you can set this to whatever name you want, or omit it entirely if you don’t care how it’s named).

  4. --rm: Deletes the container when it’s shut down (you can omit this if you don’t want to delete the container).

  5. --volume /srv/containers/wireguard/conf:/etc/wireguard:Z: Maps the /srv/containers/wireguard/conf directory on the container’s host to the /etc/wireguard directory within the container (you can change the host directory to whatever you want).

  6. docker.io/procustodibus/agent: Runs the latest version of the Pro Custodibus agent.

If you are going to run a WireGuard interface with an AllowedIPs setting of 0.0.0.0/0 (and using the default routing table), also add the following command flag:

--sysctl net.ipv4.conf.all.src_valid_mark=1

When using Podman, if the container serves as a hub or gateway to other hosts, you may also need to add the following flag:

--sysctl net.ipv4.conf.all.forwarding=1

Place the agent setup files and any existing WireGuard interface configuration files in the container host’s /srv/containers/wireguard/conf directory (or in whatever directory on the container’s host you choose to map to the container’s /etc/wireguard directory). Starting the container will start the Pro Custodibus agent, as well as a WireGuard interface for each wg-quick .conf file contained in this directory.

See the WireGuard Containers guide for examples of how to run this image under a variety of different scenarios.

Docker Compose

The basic pattern for running the agent image with the docker-compose command is to create a docker-compose.yml file like the following:

# /srv/containers/wireguard/docker-compose.yml
services:
  wireguard:
    image: docker.io/procustodibus/agent
    cap_add:
    - NET_ADMIN
    ports:
    - 51820:51820/udp
    volumes:
    - ./conf:/etc/wireguard:Z

These are what the above wireguard service keys do:

  1. image: docker.io/procustodibus/agent: Runs the latest version of the Pro Custodibus agent.

  2. cap_add: ['NET_ADMIN']: Grants the container the NET_ADMIN capability — this is required to start a WireGuard interface inside the container.

  3. ports: ['51820:51820/udp']: Forwards the public 51820 UDP port on the container’s host to the container’s 51820 UDP port — make sure the latter matches the ListenPort setting in the WireGuard config file (the former can be whatever port you want to expose publicly). When running multiple WireGuard interfaces in the same container, include one port mapping for each interface.

  4. volumes: ['./conf:/etc/wireguard:Z']: Maps the conf directory on the container’s host (sibling of the docker-compose.yml file) to the /etc/wireguard directory within the container (you can change the host directory to whatever you want).

If you are going to run a WireGuard interface with an AllowedIPs setting of 0.0.0.0/0 (and using the default routing table), also add the following sysctls entry to the wireguard service:

    sysctls:
    - net.ipv4.conf.all.src_valid_mark=1

When using Podman, if the container serves as a hub or gateway to other hosts, you may also need to add the following sysctls entry:

    - net.ipv4.conf.all.forwarding=1

If you create the docker-compose.yml file in the container host’s /srv/containers/wireguard directory, create a conf subdirectory in that directory, and place the agent setup files and any existing WireGuard interface configuration files there (or wherever you choose to map to the container’s /etc/wireguard directory).

Starting the container from the directory containing the docker-compose.yml file with the following command will start the Pro Custodibus agent, as well as a WireGuard interface for each wg-quick .conf file contained in the conf subdirectory:

$ sudo docker-compose up
Creating network "wireguard_default" with the default driver
Creating wireguard_wireguard_1 ... done
Attaching to wireguard_wireguard_1
wireguard_1  |
wireguard_1  |  * /proc is already mounted
wireguard_1  |  * /run/lock: creating directory
wireguard_1  |  * /run/lock: correcting owner
wireguard_1  |    OpenRC 0.43.3.bf57debcde is starting up Linux 5.11.0-1020-aws (x86_64) [DOCKER]
wireguard_1  |
wireguard_1  |  * Caching service dependencies ... [ ok ]
wireguard_1  |  * Starting WireGuard interface wg0 ...[#] ip link add wg0 type wireguard
wireguard_1  | [#] wg setconf wg0 /dev/fd/63
wireguard_1  | [#] ip -4 address add 10.0.0.1/24 dev wg0
wireguard_1  | [#] ip link set mtu 1420 up dev wg0
wireguard_1  |  [ ok ]
wireguard_1  |  * Starting procustodibus-agent ... [ ok ]

See the WireGuard Containers guide for examples of how to run this image under a variety of different scenarios.

Docker Pull

To upgrade to the latest version of the Pro Custodibus agent, pull the latest agent image to the container’s host with the following command:

$ sudo docker pull procustodibus/agent
Using default tag: latest
latest: Pulling from procustodibus/agent
a9fdca298560: Pull complete
Digest: sha256:1964a71fc1e4d6856849d9f49240c5fb1317dfe86e61d38bc7af74c2bb38690e
Status: Image is up to date for procustodibus/agent:latest
docker.io/procustodibus/agent:latest

List the available versions and tags for the agent image with the following command:

$ sudo docker image ls procustodibus/agent
REPOSITORY            TAG            IMAGE ID       CREATED        SIZE
procustodibus/agent   latest          6f35a14a1c08   4 days ago     286MB
procustodibus/agent   1.2.0           6f35a14a1c08   4 days ago     286MB
procustodibus/agent   1.2.0-i211029   6f35a14a1c08   4 days ago     286MB
procustodibus/agent   1.2.0-i211022   3692f4d38ac3   11 days ago    286MB

If you specified a particular tag or image ID for the agent image in your docker run command or docker-compose.yml config file, update it to use a tag or the ID of the latest image. Then restart the container.

Next Steps

  1. If you run into errors starting the container, check the Troubleshooting section of this page.

  2. Otherwise, check the host’s main page in the app. The Agent panel should show the results of the agent’s latest ping.

  3. If the Agent panel simply reads Set Up Agent, or if the Interfaces panel doesn’t list the WireGuard interfaces you already have running in the container, check the Troubleshooting section.

Troubleshooting

Refer to the same Agent Troubleshooting page both when the agent is running outside of Docker, as well when its running inside of a container.

However, with a container you will need to shell into the running container in order to run the agent test command, or to check the agent status. And to run diagnostic tools on the container’s host that are not present within the container itself, like the dig command, you’ll need to run the tool within the container’s namespace.

Shell Into the Container

If you launched the container with docker run, you can shell into the container with the following command (where wireguard is the name you gave to the container):

$ sudo docker exec -it wireguard sh
/ #

If you launched the container with a docker-compose command, you can shell into the container with the following command from the same directory from which you launched the container (and where the container’s service name is wireguard in your docker-compose.yml file):

$ sudo docker-compose exec wireguard sh
/ #

Once in, you can run the agent test command like the following:

/ # procustodibus-agent --test
... 1 wireguard interfaces found ...
... 192.0.2.0 is pro custodibus ip address ...
... healthy pro custodibus api ...
... can access host record on api for My Test Host ...
All systems go :)

And check the agent status like the following:

/ # rc-service procustodibus-agent status
procustodibus-agent started

You can also attempt ICMP pings from within the container with the following command:

/ # ping -c1 192.0.2.0
PING 192.0.2.0 (192.0.2.0): 56 data bytes
64 bytes from 192.0.2.0: icmp_seq=0 ttl=37 time=10.138 ms
--- 192.0.2.0 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 10.138/10.138/10.138/0.000 ms

Run Commands in the Container Namespace

You can use the nsenter tool on the container’s host to run any command-line diagnostic tools you have installed on the host from within the container’s own network namespace. This allows you to run a command available only outside of the container as if it were actually running within the container.

First, identify the PID (process ID) of the container with the following command (where wireguard is the container’s name):

$ sudo docker container inspect wireguard -f '{{.State.Pid}}'
12345

Then use nsenter with that PID to run any tool installed on the container’s host, like dig:

$ sudo nsenter -t 12345 -n dig +short api.custodib.us
192.0.2.0