Skip to content

Remote Plugin Install

The Updating page covers the device-side flow — an operator on the firewall runs pkg upgrade. This page covers the inverse: a central operator pushes a plugin (re)install out to a specific device without touching the firewall directly. This is the path you use when you need to remediate a critical bug or security issue across the fleet without coordinating an on-device admin for each one.

The mechanism is a new task type — PLUGIN_INSTALL — that the device’s NDAgent receives over its WebSocket and acts on by re-invoking the FreeBSD pkg manager against itself.

Critical fix

A new plugin version contains a security or correctness fix and needs to land on a known-affected device immediately.

Pin to a known-good version

Roll a specific device back (or forward) to a specific semver — useful when a recent build behaves badly on one site but is fine elsewhere.

Fleet rollout (future)

Today this is a per-device operation triggered manually. A fleet-wide policy (“auto-upgrade everything below min_required_version”) is on the roadmap.

  1. Operator triggers a PLUGIN_INSTALL task for a specific device, optionally pinned to a semver:

    Terminal window
    # Upgrade to the latest in the device's installed channel
    ndcli task create murphy01 PLUGIN_INSTALL
    # Pin to a specific version (forward, backward, or reinstall)
    ndcli task create murphy01 PLUGIN_INSTALL --version 1.4.5

    The task is also visible in NDWeb under Tasks and routable via the REST API.

  2. The NetDefense Control Plane records the device’s current version as previous_version in the task payload and sets a 15-minute timeout.

  3. The NetDefense Hub dispatches the task over the device’s WebSocket connection.

  4. NDAgent forks a detached helper script (/usr/local/sbin/ndagent-plugin-install.sh) that runs pkg install against the configured NetDefense repo (repo.netdefense.io) for the device’s installed channel (prod / qa / dev).

  5. The agent process exits cleanly; pkg’s post-install restarts ndagent on the new binary.

  6. The new agent reconnects and reports its version in its WebSocket auth handshake. The NetDefense Hub compares the reported version against the task’s target_version and previous_version to close the task lifecycle.

Task ends asReason
COMPLETEDThe agent reconnected with the requested version.
FAILED — landed on X, expected Ypkg install resolved to a different version than requested (e.g. you asked for 1.6.0 but the repo only had 1.5.2).
FAILED — plugin install did not occurThe agent reconnected on the previous version. The most common cause is the requested version not existing in the channel, or the device having lost network access to repo.netdefense.io mid-transaction.
FAILED — agent did not reconnectThe 15-minute timeout elapsed without the agent reauthenticating. The device may be offline or the install may have left it in a broken state requiring on-device recovery.

If a PLUGIN_INSTALL ends in FAILED — agent did not reconnect, the device’s pkg state should still be consistent (FreeBSD pkg transactions are atomic) — but the agent may not be running. SSH to the device and check:

Terminal window
service ndagent status
pkg info os-netdefense<channel-suffix>
tail /var/log/ndagent-plugin-install.log

The helper script logs each install attempt with pkg’s full output, so post-mortem diagnosis is usually a single tail away. Restart the service if needed:

Terminal window
service ndagent restart

You can re-issue the same task once the agent is back online.

The plugin’s distribution channel (prod / qa / dev) is fixed at the time of initial installation — the channel is encoded in the package name (os-netdefense / os-netdefense-qa / os-netdefense-dev) and cannot be overridden by the PLUGIN_INSTALL task. To switch a device between channels, you still need an on-device pkg delete + pkg install against the new channel’s repo. See Updating for that flow.

  • Updating — device-side pkg upgrade flow (the “pull” model)
  • Troubleshooting — when the agent isn’t reconnecting at all