Systemd Guide
This guide documents the systemd deployment story for Virtnosis.
Support boundary#
Virtnosis supports two local deployment models:
- direct-bind services, where
virtnosis-agentcreates and owns the control socket - socket-activated services, where
systemdcreates the control socket and passes one inherited listener fd to the agent
Socket-activation support is intentionally narrow:
- exactly one inherited listener fd
- UNIX domain sockets only
- filesystem-backed absolute paths only
.socketunits must useAccept=no
Multiple inherited fds, abstract UNIX sockets, and remote control-plane listeners are still outside the supported surface.
Example files#
Example units live in:
deploy/systemd/system/virtnosis-agent.servicedeploy/systemd/user/virtnosis-agent.servicedeploy/systemd/system/virtnosis-agent.socketdeploy/systemd/system/virtnosis-agent-socket-activated.servicedeploy/systemd/user/virtnosis-agent.socketdeploy/systemd/user/virtnosis-agent-socket-activated.servicedeploy/systemd/tmpfiles.d/virtnosis.confdeploy/systemd/sysusers.d/virtnosis.conf
These are examples, not a promise that the exact paths or gids match your environment.
Direct-bind system service#
Use the direct system service when:
- the host should expose a shared local control socket
- the agent should manage stale-socket cleanup itself
- multiple trusted local users need access through a controlled gid
Typical flow:
- review
deploy/systemd/system/virtnosis-agent.service - adjust
ExecStart=and--listen-gid - install the unit under
/etc/systemd/system/ - run
systemctl daemon-reload - run
systemctl enable --now virtnosis-agent.service
Direct-bind user service#
Use the user service when:
- you want a per-user control plane
- you want
vnactlto work withoutsudo - the user account already has access to the target libvirt socket
Typical flow:
- review
deploy/systemd/user/virtnosis-agent.service - adjust
ExecStart= - install the unit under
~/.config/systemd/user/ - run
systemctl --user daemon-reload - run
systemctl --user enable --now virtnosis-agent.service
Socket-activated system service#
Use the socket-activated system pair when:
- you want
systemdto own socket creation and permissions - you want lazy startup on first client connection
- you want the service and the socket configured separately
Typical flow:
- review
deploy/systemd/system/virtnosis-agent.socket - set
SocketGroup=andListenStream= - review
deploy/systemd/system/virtnosis-agent-socket-activated.service - adjust
ExecStart= - install both units under
/etc/systemd/system/ - run
systemctl daemon-reload - run
systemctl enable --now virtnosis-agent.socket
Important behavior:
- the
.socketunit controls socket mode, gid, and directory mode virtnosis-agent --listen-modeand--listen-gidare ignored when the socket is inherited fromsystemdvnactl statusreportsresult.listen.socket_activation: truewhen the agent is serving from an inherited listener
Packaging assets#
The repo now also ships packaging-oriented examples:
deploy/systemd/sysusers.d/virtnosis.confcreates the shared local control-socket group used by the example socket-activated system deploymentdeploy/systemd/tmpfiles.d/virtnosis.confoptionally materializes/run/virtnosisbefore first service start
The tmpfiles asset is optional with the shipped unit files because:
- the direct-bind system service already uses
RuntimeDirectory=virtnosis - the socket-activated system unit pair already uses
DirectoryMode=in the.socketunit
Use it when your packaging or wrapper conventions require the runtime directory to exist independently of those units.
For repo-side validation of the staged units, run:
cd virtnosis
make systemd-verify
That path stages the example assets into a temporary tree, rewrites ExecStart= to a temporary stub binary, runs systemd-analyze verify on the units, and validates the tmpfiles.d / sysusers.d assets with the native systemd tools when they are available on the host.
Socket-activated user service#
Use the rootless socket-activated pair when:
- you want rootless on-demand startup
- you want the control socket under
%t/virtnosis/agent.sock - you want
systemd --userto own socket lifecycle
Typical flow:
- review
deploy/systemd/user/virtnosis-agent.socket - review
deploy/systemd/user/virtnosis-agent-socket-activated.service - adjust
ExecStart= - install both units under
~/.config/systemd/user/ - run
systemctl --user daemon-reload - run
systemctl --user enable --now virtnosis-agent.socket
Hardening notes#
The shipped service examples include a conservative baseline:
NoNewPrivileges=yesPrivateTmp=yesProtectSystem=strictProtectHome=restrictionsProtectKernelTunables=yesProtectKernelModules=yesProtectKernelLogs=yesLockPersonality=yesMemoryDenyWriteExecute=yesRestrictAddressFamilies=AF_UNIX AF_INET AF_INET6- empty
CapabilityBoundingSet=andAmbientCapabilities=
The address-family allowlist includes AF_INET and AF_INET6 intentionally so the scan engine can still reach remote libvirt TCP/TLS URIs when operators use them.
If your deployment is strictly local-libvirt-only, you can narrow that directive to AF_UNIX.
Important operational caveat#
The control socket and the libvirt socket are separate concerns.
Even if vnactl can reach virtnosis-agent, the scan still fails if the agent process does not have access to the target libvirt socket or remote libvirt URI you asked it to inspect.
Where to go next#
- broader deployment guidance: Deployment Guide
- installable docs layout: Install and Package
- deeper design target: Repository documents
Source repository · Edit this page · View Markdown