The NexoVirt node agent
NexoVirt runs a small agent on each connected Proxmox node. It does the work that the Proxmox API can’t do cleanly on its own: downloading OS images, applying NAT and WireGuard, reading the node firewall and logs, installing package updates, and feeding the panel accurate node facts. The current agent version is 0.24.1.
What it is
Section titled “What it is”The agent is a single PHP script (/opt/nexovirt-agent.php, config in
/etc/nexovirt-agent.conf) run by the nexovirt-agent systemd service. It runs on the stock
Proxmox php-cli and needs no extra PHP extensions (no curl or mbstring extension).
It holds no open inbound port. It sends a heartbeat to the panel over HTTPS about every 15 seconds (every 3 seconds while it has work), picks up queued jobs from the response, runs them and posts the results back. It authenticates with a per-node token issued during onboarding. Nothing outside your panel can reach it.
Required and version-checked
Section titled “Required and version-checked”The panel needs a working agent and checks it on every heartbeat:
- Missing or not responding (no heartbeat for 5 minutes): the panel shows a blocking dialog on every admin page with the one-click fix (Set up agent or Update agent). The dialog clears itself once the agent reports in. Nodes that are down and handled by failover, and nodes where you deliberately used Remove agent, do not trigger it.
- Outdated (the installed version differs from the one bundled with the panel): the agent keeps working. The panel shows a dismissible “node agents need updating” banner once per new agent version, and the Nodes list shows Update available with an Update button.
Some features need a minimum agent version and say so when the agent is older, for example node updates.
What it does
Section titled “What it does”The agent only runs a fixed, allow-listed set of jobs. There is no “run this command” job: the panel can only ask for one of these named operations, each validates its own inputs on the node, and anything else is rejected as an unsupported job type.
| Job | What it does |
|---|---|
| Provision image storage | Creates the managed nexovirt-images directory storage on the node. |
| Image cache | Downloads an OS cloud image once per node into the image cache (detached, resumable, SHA-256 verified), and deletes cached images. Older agents used a per-guest download instead. |
| Write cloud-init snippet | Writes a validated cloud-init vendor snippet (for example to install the QEMU guest agent or enable root SSH). |
| LXC password / root SSH | Runs pct exec in a container to set the root password or enable root SSH (Proxmox has no API for this). |
| Apply / clear NAT | Programs only the dedicated NEXOVIRT-* iptables chains for masquerade and port forwards. Built-in and Proxmox chains are never flushed. |
| Apply / read WireGuard | Manages the wg-nexovirt interface and its own NEXOVIRT-VPN* chains, and reports VPN status and readiness. |
| SDN DHCP and egress | Installs dnsmasq only if absent and enables the per-zone DHCP backend; enables forwarding for SNAT subnets. |
| Set IP forwarding | Turns net.ipv4.ip_forward on or off through its own sysctl.d file. |
| Scan IPs | Ping-sweeps a CIDR (at most 1024 addresses) and reads the ARP table to find addresses in use for IPAM. |
| Probe TCP | Checks that a host and port are reachable (migration pre-flight). |
| Unlock guest | Runs qm unlock / pct unlock for a guest left locked by a migration. |
| Configure DynDNS | Stores the DynDNS token and keeps the node’s DynDNS name updated every 5 minutes. |
| Package updates | Refreshes the package lists, simulates and installs Debian / Proxmox updates. See Node updates. |
What data it reads
Section titled “What data it reads”Separately from the jobs above, the agent reads node facts for the node page, health checks, firewall view and diagnostics. These reads are read-only:
- System: OS release, kernel, CPU, memory, uptime, load average, pending package updates, SMART
disk health, the state of
pve-cluster,pvedaemon,pveproxyandpvestatd, and theip_forwardsetting. - Proxmox VE: version, cluster, HA and Ceph status, and the storage list.
- Firewall: the raw output of the firewall tooling present (iptables, nftables, ufw, firewalld, pve-firewall), which the panel parses into a read-only view.
- Logs: recent system and Proxmox daemon log lines from
journalctl, shown under Diagnostics. - Heartbeat stats: uptime, load, memory, and the image cache contents and free space.
The agent does not read your guests’ disks, your files or any secrets.
Why it’s safe
Section titled “Why it’s safe”The agent runs as root (it needs pct, iptables, sysctl and apt-get), which is why the
design is deliberately narrow: a fixed job list, validated inputs, dedicated firewall chains and
detect-first behaviour.
Lifecycle
Section titled “Lifecycle”- Set up. Add node (or Set up agent on an existing connection) connects once over SSH
(host key pinned), installs
php-cliif missing, installs the script and systemd service, and waits for the first heartbeat. See Nodes & onboarding. - Update. Update agent on the node page (Settings tab) or the Update button in the Nodes list pushes the agent bundled with the panel, restarts the service and waits for a heartbeat at the new version. After a panel update, update the agent on every node.
- Remove. Remove agent uninstalls the service, script and config and revokes the token,
while keeping the node, its inventory and metrics. Deleting the node from the panel can also wipe
the agent and the
nexovirt-imagesstorage.
If SSH credentials are stored for the node, update and remove run without asking for them again.
If the panel server blocks proc_open, run the worker manually; see
CLI & daemons.
Requirements
Section titled “Requirements”- Root SSH access to the node for the one-time setup (password or the panel’s key).
php-clion the node (installed automatically if missing).- Outbound HTTPS from the node to your panel. No inbound port is opened.