Hardening
Run the Arctic agent as a non-root user under a hardened systemd unit
The default installation runs the agent as root. The agent does not actually
need root; it needs a small set of Linux capabilities, chiefly CAP_NET_ADMIN.
This guide replaces the bundled installer with a hand-built systemd unit that
runs the agent as a dedicated unprivileged user with only the capabilities it
uses, plus systemd sandboxing to limit what a compromised agent could touch.
You take over the lifecycle
A hardened unit is incompatible with the bundled lifecycle commands. Do not run
agent install or agent upgrade on a host set up this way: both require root,
and agent upgrade rewrites arctic.service back to the default root unit,
silently undoing your hardening. Once you go down this path, you install,
upgrade, and manage the service by hand. The steps for a manual upgrade are at
the end of this page.
This is an advanced, operator-maintained configuration. It is not the path the installer takes and is not exercised by the project's release testing, so validate it in staging before you rely on it.
What the agent needs
The agent process has no root check; it reads and writes kernel network state through capabilities:
CAP_NET_ADMINis the one that matters. It covers committing firewall rules over netlink, creating MACVLAN and TUN devices, managingiprules and routes, the transparent-proxy socket option, and the traffic-shaping queues used for QoS.CAP_NET_RAWis needed only on hosts that fall back to the legacy xtables path because nftables is unavailable. Most hosts never use it.- No privileged ports are involved. The API (8080), TProxy (61000), and IP
tunnel (51840) all bind above 1024, so
CAP_NET_BIND_SERVICEis not required.
The in-process IP tunnel uses per-peer TUN devices rather than network
namespaces, so CAP_SYS_ADMIN is not required either. That is what makes a
non-root agent practical.
At runtime the agent writes to two locations only: its data directory
(/opt/tillered by default, holding the database and peer.key) and
/etc/arctic (the per-boot recovery token). Everything else it does is kernel
state, not files on disk.
Manual setup
1. Create a service user
sudo groupadd --system arctic
sudo useradd --system --gid arctic --no-create-home \
--shell /usr/sbin/nologin arctic2. Install the binary
Download the agent binary and place it where the unit expects it. Keep root as the owner so the service user cannot replace its own binary:
sudo mkdir -p /opt/tillered/bin
sudo curl -fsSL https://release.tillered.com/arctic/latest/agent_amd64 \
-o /opt/tillered/bin/arctic-agent
sudo chmod 0755 /opt/tillered/bin/arctic-agentUse agent_arm64 on ARM hosts. Verify the binary signature before trusting it;
see Installation.
3. Create and own the writable directories
The service user owns the data directory and the recovery-token directory.
Pre-creating /etc/arctic matters: the agent cannot create it itself as a
non-root user, and without it the recovery token is disabled.
sudo mkdir -p /opt/tillered
sudo chown arctic:arctic /opt/tillered
sudo mkdir -p /etc/arctic
sudo chown arctic:arctic /etc/arctic
sudo chmod 0700 /etc/arctic4. Kernel modules for QoS
QoS relies on the kernel's traffic-shaping modules. Under CAP_NET_ADMIN the
kernel loads them on demand, so a typical host needs no action here. On hosts
that block on-demand module loading, make sure the traffic-shaping modules your
kernel uses are available at boot.
5. Write the systemd unit
Create /etc/systemd/system/arctic.service:
[Unit]
Description=Arctic Network Routing Agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=arctic
Group=arctic
ExecStart=/opt/tillered/bin/arctic-agent
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/tillered /etc/arctic
DeviceAllow=/dev/net/tun rw
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
Environment=DATA_DIR=/opt/tillered
Environment=LOG_FORMAT=json
[Install]
WantedBy=multi-user.targetOn hosts without nftables that need the xtables fallback, add CAP_NET_RAW to
both AmbientCapabilities and CapabilityBoundingSet.
6. Enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now arctic7. Bootstrap
Bootstrapping is unchanged; it is an API call to the running agent:
arctic bootstrap --url http://localhost:8080 \
--license-file license.json --name node-aVerify
Confirm the agent answers and is running as the unprivileged user:
curl http://localhost:8080/livez
systemctl show arctic --property User --property MainPID
ps -o user= -p "$(systemctl show arctic --property MainPID --value)"The ps output should read arctic, not root. Check that the recovery token
was written under the service user:
sudo ls -l /etc/arctic/recovery.tokenIf the token is missing, the agent could not write /etc/arctic; recovery is
disabled but the agent otherwise runs normally. Re-check the directory's owner
and permissions from step 3.
Upgrading by hand
Because you cannot use agent upgrade, upgrade by replacing the binary and
restarting. Your unit file is left untouched:
sudo systemctl stop arctic
sudo curl -fsSL https://release.tillered.com/arctic/latest/agent_amd64 \
-o /opt/tillered/bin/arctic-agent
sudo chmod 0755 /opt/tillered/bin/arctic-agent
sudo systemctl start arcticVerify the new version afterwards:
journalctl -u arctic --since "2 minutes ago"
arctic license statusFor a multi-peer cluster, upgrade one peer at a time and confirm each is healthy before moving on, as in Upgrades.
Caveats
/dev/net/tunmust exist and be accessible. On most distributions it is world-accessible (crw-rw-rw-). If it is missing, load thetunmodule.- Recovery depends on
/etc/arcticbeing writable by the service user. If it is not, break-glass recovery is unavailable on that host. ProtectSystem=strictmakes the filesystem read-only apart fromReadWritePaths. If you move the data directory, update both theDATA_DIRenvironment line andReadWritePaths.- Layer on more sandboxing carefully. Directives such as
RestrictAddressFamiliesorSystemCallFiltercan tighten the unit further, but the agent needs netlink, packet, and inet socket families; test each addition in staging rather than adding them blind. - You own upgrades and unit changes. Nothing in the agent will rewrite or update this unit for you, which is the point, but it also means security updates to the recommended unit are yours to apply.
See also
- Installation - the default root install
- Upgrades - the standard upgrade flow
- Recovery - the recovery token this setup must keep writable