This commit is contained in:
Jonas Bengtsson
2026-10-07 07:40:56 +02:00
parent c8b655111e
commit 9f3272094e
17 changed files with 2243 additions and 89 deletions
+32
View File
@@ -0,0 +1,32 @@
# Host-side agent config for the web UI's host network settings page
# (spec §15, FR-15.2.7). Used by `wago-sim hostnet-agent --config ...`.
#
# This file lives on the DOCKER HOST (not inside the container), e.g.
# /etc/wago-sim/hostnet.yaml. The agent must run as root or with
# CAP_NET_ADMIN; the whitelist is the safety rail that keeps the
# privileged surface as small as the FAT bench needs.
#
# socket: the Unix domain socket the container connects through.
# docker-compose.yml mounts /run/wago-sim read-write into the
# simulator container, which is why this path is fixed by default.
# The agent refuses to start with an empty whitelist.
socket: /run/wago-sim/hostnet.sock
# whitelist: interfaces the settings page may manipulate. Operations
# on any other interface are refused by the agent and surfaced as
# errors on the page (FR-15.2.5). List the bench NIC(s) only.
whitelist:
- enp3s0
- eth0
# backend: how the agent performs changes on the host.
# iproute2 — the `ip` tool (+ pyroute2 for reads when installed);
# the production backend for Linux bench hosts (v1)
# fake — in-memory model: rehearses FAT cases and demos the page
# without touching any real interface
backend: iproute2
# audit_path: optional file for the single-line audit trail in
# addition to the service log (stdout/journald, FR-12.2.6). The
# directory is created if missing; leave out to log only.
audit_path: /var/log/wago-sim/hostnet-audit.log
+52
View File
@@ -0,0 +1,52 @@
# systemd unit for the host-side hostnet agent (spec §15, FR-15.2.7).
#
# This runs ON THE DOCKER HOST — not in the container. It is the only
# component that holds the privileges to change host interface
# addresses (root or CAP_NET_ADMIN), scoped by the whitelist in its
# config file.
#
# Install:
# sudo cp wago-sim-hostnet-agent.service /etc/systemd/system/
# sudo cp hostnet-agent.yaml /etc/wago-sim/hostnet.yaml
# sudo systemctl daemon-reload
# sudo systemctl enable --now wago-sim-hostnet-agent
#
# Logs: journalctl -u wago-sim-hostnet-agent -f
# (the agent's audit lines appear here AND on the web page)
#
# The simulator container connects through /run/wago-sim/hostnet.sock —
# docker-compose.yml mounts /run/wago-sim into the container. The
# socket is created 0660 (root:wago-sim by the directives below); put
# the container's non-root user in the same group (compose passes the
# host group via group_add).
[Unit]
Description=WAGO simulator hostnet agent (host IP settings page)
Documentation=file:///opt/wago-sim/docs/spec/software-spec.md
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# root keeps netlink + `ip` simple; hardening still applies below.
# Alternative: a dedicated user + AmbientCapabilities=CAP_NET_ADMIN.
User=root
Environment=WAGO_SIM_HOSTNET_AGENT_CONFIG=/etc/wago-sim/hostnet.yaml
ExecStart=/opt/wago-sim/.venv/bin/wago-sim hostnet-agent \
--config /etc/wago-sim/hostnet.yaml
Restart=on-failure
RestartSec=2
# Hardening: the agent needs network-admin on whitelisted interfaces
# and nothing else. The filesystem is locked down except for its
# config (read), socket directory and audit file (write). CAP_NET_RAW
# is included because netlink socket ops request it.
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/run/wago-sim /var/log/wago-sim
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
[Install]
WantedBy=multi-user.target