Skip to main content

Host agent

The agent runs on every managed host. It opens every connection itself (no listening port), registers with the manager with a bootstrap token and the sha256 fingerprint of the manager CA, then sends heartbeats, facts and metrics and runs the tasks of the manager one at a time. The protocol, the task types and the security rules are in navin-manager/CONTRACT.md sections 8 and 9.

Which agent to install​

AgentPackageWhen
Go agent (shipped)navin-manager-agent-go (RPM x86_64 and aarch64, DEB amd64 and arm64, tar.gz)Every host. One static binary: no Python, no OpenSSL, no shared library. Certified systems: RHEL 8/9/10, Rocky Linux 8/9/10, AlmaLinux 8/9/10, Oracle Linux 8/9, CentOS Stream 9/10, Ubuntu 22.04/24.04, Debian 12, Arch Linux (rolling). It also starts on an end of life system such as RHEL 7 to report its facts, where the preflight blocks every installation.
Python agent (reference)navin-manager-agent (RPM noarch, DEB all, tar.gz)Kept for compatibility and as the reference implementation. Needs Python 3.9 or newer (RHEL 8: dnf install python39).

Both agents use the same command (/usr/bin/nm-agent), the same configuration file (/etc/navin-manager-agent/agent.json), the same state directory (/var/lib/navin-manager-agent) and the same systemd unit (navin-manager-agent.service). The Go packages declare Provides and Conflicts on navin-manager-agent: installing one replaces the other, and a registered host keeps its identity because the state directory is kept.

The Go agent reports agent_impl: "go" in its facts. Its python fact is the version of the system python3 (or null): Python is only needed on hosts that run a python.venv component.

Supported systems​

The single list lives in navin_manager/os_support.py and is published by GET /api/v1/system/supported-os (any signed in user); the System page of the Manager shows it in the "Supported systems" card. Certified systems: RHEL 8/9/10, Rocky Linux 8/9/10, AlmaLinux 8/9/10, Oracle Linux 8/9, CentOS Stream 9/10, Ubuntu 22.04/24.04, Debian 12, Arch Linux (rolling). Packages: dnf on the RHEL family, apt on the Debian family, pacman on the Arch Linux family.

VerdictExamplePreflight
certifiedRocky Linux 10pass
not certified (newer release or other distribution of a known family)Ubuntu 26.04, Fedorawarning, never blocking
end of lifeCentOS 7, RHEL 7, Ubuntu 20.04, Debian 11blocking
not supported (unknown family)SUSE Linux Enterprise Serverblocking

Corporate proxy​

When the hosts reach the package mirrors through a proxy, set it in Settings, card "Corporate proxy" (setting proxy of PUT /api/v1/settings: http_proxy, https_proxy, no_proxy). The URLs are http:// or https:// only, without user name, password or path; a wrong value is refused with the error proxy_invalid (422). The SSH bootstrap applies it:

  • package manager: apt-get -o Acquire::http::Proxy=... -o Acquire::https::Proxy=..., dnf --setopt=proxy=... (the https proxy when set, else the http proxy);
  • agent unit: Environment="HTTP_PROXY=...", Environment="HTTPS_PROXY=..." and Environment="NO_PROXY=...". NO_PROXY always holds localhost, 127.0.0.1, ::1 and the address of the Manager, so the agent never reaches its Manager through the proxy.

Empty fields mean a direct access: the unit then has no proxy line.

Facts​

nm-agent facts prints, and the facts heartbeat sends, the facts of CONTRACT.md section 9: os, kernel, arch, cpu_count, cpu_model, memory_mb, swap_mb, disks, network, selinux, firewall, time_sync, timezone, python, podman, systemd, listening_ports, sysctl, ulimits, gpus, platform, binaries, fs_prefix, rootless, agent_user, service_driver.

platform tells where the machine runs: virtualization (none on bare metal, else the name of systemd-detect-virt: kvm, vmware, microsoft, xen, amazon, wsl, docker...), container, cloud.provider (aws, azure, gcp, ibm, ovh, openstack, oracle, alibaba, scaleway, outscale, hetzner, digitalocean, exoscale, none on premises, unknown) with cloud.source (dmi, virt, none), instance_type (EC2 Nitro, such as m5.large), and the vendor, product, bios_vendor and chassis_asset_tag of the DMI. Both agents give the same answer from local files only (/sys/class/dmi/id, systemd-detect-virt with a 2 s timeout when it exists, /proc): they never call an instance metadata service. OVHcloud Public Cloud shows as openstack; the host labels provider, region and zone (for example provider=ovh region=gra) complete the inventory, and the manager labels win.

Security properties​

  • No remote shell. command.run, the command checks of health.check, preflight.run and smoke.run, and the process driver only run an absolute argv[0] listed in allowed_commands or whose real path lies inside the allowed roots. The program is started from its argument list, never through a shell: /bin/sh -c ... is refused with command_not_allowed.
  • Path guard. The allowed roots are resolved once at start. Below a root, a path with a symbolic link component, a .. component or outside every root fails with path_not_allowed. Files are opened relative to a directory descriptor obtained with openat2(RESOLVE_NO_SYMLINKS | RESOLVE_BENEATH), or with an openat(O_NOFOLLOW) walk on kernels without openat2 (RHEL 7 and 8), and the final open uses O_NOFOLLOW.
  • Archives. Absolute names, .., devices, FIFOs and links whose target leaves the destination are refused with archive_unsafe before anything is written; an archive declaring more than 200 000 members or 64 GiB is refused with archive_too_large.
  • Downloads. A file is used only after its sha256 matches (checksum_mismatch otherwise); nothing unverified reaches its destination or the cache. A download stops past 64 GiB (download_too_large) or before the disk is full (disk_space_low).
  • Identity. An EC P-256 key and a certificate request are made on the host; the key never leaves it. After the registration every call uses the client certificate (mutual TLS) and an NM-HMAC signature of the request.
  • Secrets. Values of sensitive_env, secrets (smoke tests) and certificate keys are replaced by ****** in every log line and result.

Install from the packages​

Copy the package of the host architecture (from packaging/dist/agent-go/ or the offline bundle) and check it against SHA256SUMS, then install it and register the host with the command shown by the console:

sha256sum -c --ignore-missing SHA256SUMS
dnf install ./navin-manager-agent-go-1.0.0-1.x86_64.rpm
nm-agent register --server https://<manager-host>:8460 --token <token> --ca-sha256 <fingerprint>
systemctl enable --now navin-manager-agent

On aarch64 use navin-manager-agent-go-1.0.0-1.aarch64.rpm; on Ubuntu use apt install ./navin-manager-agent-go_1.0.0_amd64.deb (or _arm64.deb). On a host without a package manager, unpack the tar.gz at the root: tar -xzf navin-manager-agent-go-1.0.0-linux-x86_64.tar.gz -C /, then systemctl daemon-reload.

Offline​

The agent needs nothing from the Internet: the packages hold the whole program. To ship it in the offline bundle, build the packages then give their directory to the bundle builder:

navin-manager/packaging/build-packages.sh agent-go
python3 navin-manager/packaging/offline/build-bundle.py --agent-dir navin-manager/packaging/dist/agent-go ...

build-packages.sh agent-go needs Go 1.26 or newer (NM_GO selects the binary) and the module cache or a Go proxy of the bank (GOPROXY); it builds x86_64 and aarch64 (NM_AGENT_GO_ARCHES), checks that each binary is statically linked and writes SHA256SUMS. The third party components and their licenses are listed in /usr/share/doc/navin-manager-agent/THIRD_PARTY_LICENSES.

Commands​

nm-agent --version
nm-agent [--config FILE] [--lang en|fr] register --server URL --token TOKEN --ca-sha256 HEX [--ca-file FILE]
nm-agent [--config FILE] run
nm-agent [--config FILE] status
nm-agent [--config FILE] facts

Messages follow --lang, else LC_ALL or LANG. Exit codes: 0 success, 1 status of a host not registered, 2 error (invalid configuration, refused registration, wrong CA fingerprint: nothing is stored).

Configuration​

/etc/navin-manager-agent/agent.json keeps the keys of the Python agent: server_url, agent_url, state_dir, log_dir, fs_prefix, allowed_roots, allowed_commands, service_driver (systemd or process), heartbeat_interval_s, poll_wait_s, health_interval_s, stop_timeout_s, log_level, ca_file. The log is written to /var/log/navin-manager-agent/agent.log (20 MB, 5 backups).

Every key, type and default is in the agent configuration reference. Installation on every system, security, daily operations and troubleshooting are in the Navin agent section.