Skip to main content

Install the connector

The Vesper Connector is a single static Go binary that runs on a Wazuh server node and gives the agent its hands and eyes. It is strictly outbound. It dials Vesper over mTLS and keeps that session alive. Nothing ever connects into the customer's network, and the Wazuh credentials it uses never leave the machine.

Wazuh Fleet is the way a host gets a connector. Wazuh Fleet installs its own connector on each host once, and on a host where Vesper is allowed it delivers Vesper's plugin. Each connector reports what kind of node its host is, so nothing about the topology is typed by hand.

Install​

  1. Install the Wazuh Fleet connector on the hosts of the Wazuh environment.
  2. In Wazuh Fleet, allow Vesper on each host from the host's Services panel.
  3. In Vesper, open Environments and choose Add. The panel lists the hosts Wazuh Fleet governs, one checkbox each.
  4. Tick the hosts the environment groups. A manager, its indexers, its dashboard and an agent host can all be in one environment, and the agent works on every one of them.
  5. Type a name for the environment and choose Add and connect. Vesper adds the environment and Wazuh Fleet installs the plugin on each ticked host.

The Add panel lists only the hosts Vesper can be installed on. Wazuh Cloud environments are not listed, because Vesper is not available on them. A host where Wazuh Fleet does not allow Vesper is listed greyed, with the sentence "Not allowed in Wazuh Fleet". Allow Vesper on the host's Services panel in Wazuh Fleet, then open the panel again. A host already in another Vesper environment is listed greyed with that environment's name, because a host is in one environment at a time.

If Wazuh Fleet does not accept some of the hosts, the environment is added with the ones it accepted and the panel stays open. The hosts it did not accept stay ticked, each with Wazuh Fleet's reason under it, and pressing the button again retries only those.

A distributed Wazuh needs every server-side node in the environment: the manager master, each worker, each indexer node and the dashboard node. A cluster member Wazuh lists with no connector on it appears in the node list as No connector, and the agent can neither read nor fix anything there until Wazuh Fleet installs one and the host is added.

Add and remove hosts​

Add hosts, on the environment's Wazuh Fleet card, opens the same panel for an environment that already exists. It lists only the hosts that are not in that environment yet.

Disconnect this host, on a host's node, takes it out of the environment. Wazuh Fleet removes Vesper's plugin from the host on its next check in, the host's connector is revoked and its node leaves the environment. Conversations and changes that name it keep their history. The host is then free to add to this environment or to another one. It does not keep its Wazuh login: added again, it asks for the login again. Disconnect from Vesper, on the card, does the same for every host of the environment, and the environment stays until it is deleted.

Shell commands on a Wazuh Fleet node​

The Add panel has one checkbox, off by default:

  • Let the agent run shell commands on these hosts. Off, the agent reads and advises. This asks for a root shell on every host ticked in the panel.

Wazuh Fleet's own permission and the choice in Vesper are two different things, and both have to say yes, host by host. Wazuh Fleet grants the permission when a Fleet administrator allows a root shell for Vesper on a host. The checkbox is the request. A shell runs only on a host where the permission is granted and the request is on. A granted permission with the request off still reads and advises. A request on a host Wazuh Fleet has not allowed is refused.

After the connection each host's node carries a Shell commands switch, and an admin changes the request for that host there. Some hosts with a shell and some without is a normal state. Beside the switch the node says what the host runs now:

WordMeaning
OnRequested, and the host runs shell commands.
OffNot requested. The agent reads and advises on this host.
SendingThe change is on its way to the host, which takes about a minute.
Not allowed in Wazuh FleetRequested, and Wazuh Fleet has not allowed a root shell for Vesper on this host.
Turning offTurned off in Vesper, and the host still reports shell commands.

The Wazuh login on a Wazuh Fleet node​

A hand-installed connector reads its Wazuh login from its own configuration file on the node. A Wazuh Fleet node has no such file, so the login is typed in Vesper, host by host. The Add panel asks for no login. Each host's node has a Set Wazuh credentials button, highlighted when the node is waiting for a login or reports one that was refused, and a login typed there goes to that host only.

The form shows both logins, and each one is optional. The Indexer login is what alerts are read with. The Wazuh API login is what the manager's own state is read with. A host may need one, both or neither. A host that runs only a Wazuh agent has nothing to log in to, and it connects with every field left empty. A manager may take only the Wazuh API login. Each login is all three fields or none of them. Paste a CA certificate to verify the connection, or leave Skip TLS verification ticked for a self-signed one. An address typed as a bare host is completed with https:// and the default port, 9200 for the indexer and 55000 for the Wazuh API, and the completed address is shown under the field before anything is sent.

Set Wazuh credentials opens on the address each login was sent with. Vesper does not keep the username, the password or the CA certificate, so they have to be typed again to save. Saving without pasting the CA certificate again sends the login without one.

The login is sent to the node over Wazuh Fleet's own encrypted channel and is not stored in Vesper. It reaches the node within about a minute of being saved, with nobody touching the machine.

Saving does not close the form. Vesper cannot reach your Wazuh from its own side, so the test is the node trying the login and reporting what your Wazuh answered. The form waits for that answer, and either closes because the login works or names the login that was refused so it can be corrected without starting again. Leaving before the answer arrives is what Cancel is for. The node's own card says the same thing afterwards: Waiting for Wazuh credentials until one is set, and Check the Wazuh credentials for one that was refused.

Connectors installed by hand​

Before Wazuh Fleet, the connector was installed on each node with a one-line command from the console. The console no longer shows that command. Connectors installed that way keep working, and the sections below describe them. A hand-installed environment moves onto Wazuh Fleet from the Wazuh Fleet card on its page. Each host then runs Vesper's plugin from Wazuh Fleet beside the hand-installed connector, and both are listed. Uninstall the hand-installed connector on each host, then choose Remove node on its old row.

Requirements​

  • Linux, on the Wazuh deployment itself. The connector targets localhost by default, so it belongs on the Wazuh node, and on every server node of a distributed deployment.
  • x86_64 or arm64. The installer refuses any other architecture.
  • systemd. The installer refuses a host without it.
  • root, both to install and to run. See what the service runs as.
  • curl. Only the binary download falls back to wget. Fetching the connector CA does not, so an install with wget alone fails partway through. Without curl the optional checksum verification is also skipped, silently.
  • Outbound HTTPS and WSS egress to dl.vesper.wazuh.com for downloads and to connect.vesper.wazuh.com for the connector session. No inbound rule is needed.

Behind a proxy, the connector honours the standard HTTPS_PROXY, HTTP_PROXY and NO_PROXY environment variables, both when enrolling and for the long-lived outbound session.

What the installer did​

The installer worked locally and outbound only. It:

  1. downloaded the static vesper-connector binary for the host's architecture, and verified its published SHA-256 checksum when both sha256sum and a published checksum were available,
  2. created the service state directory and staged the connector CA,
  3. wrote /etc/vesper/connector.yaml. On an all in one node the targets are localhost and the credentials are left blank, because the connector discovers them on the host as described in configuration. On a node that has no local source for a credential the installer asked for it on the terminal, see distributed nodes,
  4. enrolled with the environment's enrollment token, which issued the connector's mTLS identity and stored it locally, and
  5. installed and started the vesper-connector systemd service, which from then on runs tokenless.

Distributed nodes: the installer asks for a credential​

Credential discovery is local to the node. The indexer credential is read from the filebeat keystore, which is on the manager. The Wazuh API credential is read from the dashboard configuration, which is on the dashboard. On an all in one node both are present and nothing is asked. On a distributed environment two kinds of node cannot discover one of them, and the installer asks for it before writing the configuration:

NodeWhat is askedWhy
Manager without a dashboard, master or workerWazuh API user and password, usually wazuh-wuiNo dashboard configuration on the host names the API credential.
Indexer without filebeatIndexer user and password, usually adminFilebeat ships alerts from the manager, so its keystore is never on an indexer node.

Both values are in the wazuh-passwords.txt produced by the Wazuh installer. The credential is written into /etc/vesper/connector.yaml on that node only. It is never sent to Vesper and never shared with another node.

On an indexer node the installer also reads network.host from /etc/wazuh-indexer/opensearch.yml and writes that address as indexer.url, because a distributed indexer binds to its network address and refuses localhost.

Typing the credential at the prompt is the default and the recommended way. For an unattended install pass the values as flags and add --unattended. A value passed as a flag is visible in the process list while the installer runs and in the shell history afterwards, so clear the history entry when that matters:

curl -fsSL https://dl.vesper.wazuh.com/install.sh | sudo bash -s -- \
--token=<ENROLLMENT_TOKEN> --connect=wss://connect.vesper.wazuh.com \
--unattended --wazuh-api-user=wazuh-wui --wazuh-api-password='<PASSWORD>'

--indexer-user and --indexer-password are the indexer pair. With --unattended the installer never opens the terminal. When the node needs a value that was not passed as a flag, it aborts before touching the host and names the missing flags. Without --unattended a missing value only degrades the install. When no terminal is available the installer completes with a warning naming the field to set by hand, and the connector answers 401 on that target until it is set. The flags are applied when the configuration file is written, so on a node that already has one, re-run without --keep-config and the rewritten file carries them.

Re-running the installer​

Running the installer again on a node that already has a connector replaces the installation. The installer downloads the current binary again, rewrites /etc/vesper/connector.yaml from the flags, the prompts and what it discovers on the host, and restarts the service. The previous configuration file is saved beside it as connector.yaml.bak, one copy, overwritten on the next re-run. A re-run is therefore the way to fix a wrong credential or a stale setting on a node. On a node where a credential was typed at install time, pass the credential flags again on a re-run, or add --keep-config, because the rewritten file only carries what the re-run was given.

The node keeps its identity, so the console keeps showing the same node rather than a new one beside a stale copy of the old one. The installer enrolls again only in two cases:

  • the identity on the host is missing or its certificate has expired, or
  • the command is run with --re-enroll, which is the way back after an admin has revoked the connector.

Both need a --token. A plain re-run on a node whose identity is still valid does not consume the token and works with an expired one. The installer prints which of the two paths it took.

To keep a hand-edited configuration through a re-run, add --keep-config. The file is then preserved as it is, no backup is written, and the credential flags are not applied. The one exception is exec.enabled, which the installer sets on every run to match the --enable-exec flag.

Optional flags​

  • --enable-exec allows the agent to run shell commands on this host. It is off by default. Read the warning below first. The console shows the capability on each node card on the Connector page.
  • --unattended makes the installer non-interactive, for cloud-init, CI and other automation. It never opens the terminal, and it aborts before touching the host when the node needs a credential that was not passed as a flag.
  • --keep-config preserves the existing /etc/vesper/connector.yaml on a re-run instead of rewriting it. Settings edited by hand survive, and the credential flags are not applied. Passing credential flags together with --keep-config under --unattended is refused as contradictory.
  • --re-enroll replaces the identity on a host that already has one. Requires --token. Without it a valid identity is always kept.
  • --wazuh-api-user, --wazuh-api-password, --indexer-user, --indexer-password supply the credential a distributed node cannot discover, for unattended installs. See distributed nodes.
  • VESPER_DOWNLOAD_BASE=<mirror> overrides the download base for staging or air-gapped mirrors.
--enable-exec also removes the service sandbox

The flag does two things, not one. It turns on shell execution, and it installs a systemd drop-in at /etc/systemd/system/vesper-connector.service.d/exec.conf that strips most of the unit's hardening. It has to, because a fix that edits /var/ossec or restarts a service cannot run under a read-only filesystem.

With that drop-in in place the entire filesystem becomes writable by the service, and the private-tmp, private-devices, kernel-tunable, kernel-module, control-group and namespace protections are all switched off. Three hardening directives survive it: the service still cannot gain new privileges, it is still restricted to IPv4 and IPv6 sockets, and LockPersonality stays on.

To undo it, delete that file and set exec.enabled: false. See connector configuration.

What the service runs as​

The service runs as root. It needs that for zero-configuration credential discovery, because the files Wazuh keeps its credentials in are readable only by root: the filebeat keystore on 4.x, and the dashboard's opensearch_dashboards.yml on 5.x.

The systemd unit then narrows what that root process can do. The filesystem is read-only apart from the connector's own state directory, the service cannot gain new privileges, it can open only IPv4 and IPv6 sockets, and kernel tunables, kernel modules, control groups and namespaces are all protected.

A deployment that would rather not run it as root can set the Wazuh credentials explicitly in /etc/vesper/connector.yaml and then change the unit's User and Group. The unit itself records this as a supported alternative. Credential discovery is the only reason root is the default.

Verify​

systemctl status vesper-connector
journalctl -u vesper-connector -f

Within a heartbeat interval of 30 seconds the environment should show Online in the console, along with what the connector discovered about its host. On a distributed deployment repeat the check on each node. What each connector reports about the node it runs on is described in connector configuration.

The environment's header carries a Fix it with Vesper button, which opens a new conversation with the agent on that environment with the composer already set to act.

Troubleshooting enrollment​

enrolment failed (token expired or revoked? ...) means the enrollment token has passed its 60 minutes or an admin revoked it. The console no longer issues enrollment tokens, so a hand-installed node that has to enroll again is connected through Wazuh Fleet instead.

An enrolled connector does not stay valid forever, and it moves to a new build only when somebody asks it to. See Connector lifecycle.

Uninstall​

curl -fsSL https://dl.vesper.wazuh.com/uninstall.sh | sudo bash # keep config
curl -fsSL https://dl.vesper.wazuh.com/uninstall.sh | sudo bash -s -- --purge # remove everything