Skip to content

Commit fb59f8e

Browse files
authored
Merge pull request #1402 from mickem/feature/installer-fleet-enrollment
feature: Enroll with a fleet server from the installer
2 parents 3e4a8c6 + 638082c commit fb59f8e

9 files changed

Lines changed: 434 additions & 2 deletions

File tree

docs/docs/setup/installing.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ See [Supported platforms](supported-platforms.md) for the Windows and Linux vers
2323
- [Silent install](#silent-install)
2424
- [Debugging](#debugging)
2525
- [Specifying your monitoring tool](#specifying-your-monitoring-tool)
26+
- [Enrolling with a fleet server](#enrolling-with-a-fleet-server)
2627
- [Copy configuration from a HTTP server](#copy-configuration-from-a-http-server)
2728
- [Use configuration from a HTTP server](#use-configuration-from-a-http-server)
2829

@@ -243,6 +244,12 @@ A list of all the MSI options can be found below.
243244
| TLS_CA | The CA file to use for TLS connections (defaults to the Windows ROOT store) |
244245
| CONF_SET | Set a configuration value in the form of section1;key1;value1;section2;key2;value2... |
245246
| IMPORT_CONFIG | URL or file path to a configuration file to copy during install and use as the configuration for NSClient++ |
247+
| FLEET_SERVER | Fleet server url (`https://fleet.example.com`) to enroll this host with during install |
248+
| FLEET_TOKEN | The one-time bootstrap token from the install command generated by the fleet server (required with FLEET_SERVER) |
249+
| FLEET_HOSTNAME | Host name to report to the fleet server (defaults to this machine's host name) |
250+
| FLEET_CA | CA bundle used to verify the fleet server certificate (defaults to the Windows ROOT store) |
251+
| FLEET_VERIFY_MODE | TLS verify mode for the enrollment call (*certificate*, none). `none` requires FLEET_INSECURE=1 |
252+
| FLEET_INSECURE | Set to 1 to allow an unauthenticated enrollment: a plain `http://` FLEET_SERVER, or FLEET_VERIFY_MODE=none |
246253

247254
### Features
248255

@@ -314,6 +321,51 @@ In this case setting `MONITORING_TOOL` is done automatically when ever `OP5_SERV
314321
msiexec /i NSClient++.msi OP5_SERVER=https://op5.com OP5_USER=monitor OP5_PASSWORD=rotinom
315322
```
316323

324+
## Enrolling with a fleet server
325+
326+
If you manage your agents from an NSClient fleet server, the installer can enroll the host while it installs, so the
327+
machine is managed from the moment the service starts. Generate an install command on the fleet server and pass the
328+
server url and the bootstrap token it gives you:
329+
330+
```
331+
msiexec /qn /i NSCP-<version>-x64.msi FLEET_SERVER=https://fleet.example.com FLEET_TOKEN=<bootstrap-token>
332+
```
333+
334+
During the install NSClient++ generates a key pair, sends a certificate request together with the token to
335+
`FLEET_SERVER`, and stores the certificate material it gets back as `agent-state.json` in the `security` folder of the
336+
installation. It also adds an include for the fleet-managed configuration
337+
(`[/includes] fleet = ${shared-path}/fleet/fleet.ini`). The service picks all of this up on the next start and begins
338+
syncing its configuration from the fleet server; there is no module to enable.
339+
340+
A few things worth knowing:
341+
342+
- **Enrollment is required to succeed.** If the fleet server cannot be reached, or rejects the token, the install fails
343+
with an error explaining what went wrong rather than leaving you with an agent that never joined the fleet. Bootstrap
344+
tokens are one-time and are burned on first use, so a rejected token means generating a new install command.
345+
- **The installer has to be allowed to write the configuration.** Enrollment is what adds the include that makes the
346+
host read what the fleet server sends it, so combining `FLEET_SERVER` with `ALLOW_CONFIGURATION=0` - or installing
347+
onto a configuration the installer cannot update - fails the install rather than enrolling a host that then ignores
348+
everything the fleet server tells it. The install log names the reason the configuration was held to be unchangeable.
349+
- **An already enrolled host keeps its identity.** If `agent-state.json` already exists (an upgrade, a repair, or a
350+
re-install over an existing installation) the enrollment is skipped and the existing identity is kept. Delete the file
351+
to enroll again.
352+
- **Uninstalling discards the enrollment.** `agent-state.json` holds this host's private key and client certificate, so
353+
uninstalling removes it along with the other key material. The identity does not survive an uninstall/reinstall cycle,
354+
and because bootstrap tokens are one-time you need a fresh install command from the fleet server to enroll again -
355+
keep the host's registration on the server in mind before uninstalling to reinstall. Upgrading in place is unaffected.
356+
- **The fleet server is verified.** The enrollment response supplies the certificate the agent pins for every later call
357+
and the key it trusts for executable bundles, so the connection is verified against the Windows ROOT store by default.
358+
Use `FLEET_CA=<file>` if the fleet server uses a private CA. `FLEET_INSECURE=1` (with a `http://` url and/or
359+
`FLEET_VERIFY_MODE=none`) opts out of that, which is only reasonable on a trusted network or for testing.
360+
- **Keep the token out of your logs.** The token is hidden from the MSI log, but treat the deployment script that
361+
carries it as a secret; the token is a credential that exchanges for this host's client certificate.
362+
363+
The same enrollment can be done after installation with the command line:
364+
365+
```
366+
nscp enroll --server https://fleet.example.com --token <bootstrap-token>
367+
```
368+
317369
## Copy configuration from a HTTP server
318370

319371
Staring with version 0.10.5 it is possible to download a configuration file from a HTTP server and use that as

include/onboarding/onboarding.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ struct enrollment_request {
8080
std::string ca; // CA bundle used to verify the server
8181

8282
unsigned int max_attempts = 3; // attempts for retryable failures (429/5xx/network)
83+
84+
// Deadline for a single read or write on the enrollment call, in seconds (0
85+
// waits forever). max_attempts does not bound the wait on its own: it only
86+
// counts requests that finished, and a server that accepts the connection
87+
// and then stops answering never produces one. That matters most from the
88+
// installer, where the call runs inside a deferred custom action - an
89+
// unbounded wait wedges msiexec mid-script on an unattended install with
90+
// nobody there to interrupt it. Same default as the fleet sync's `timeout`.
91+
unsigned int timeout_seconds = 60;
8392
};
8493

8594
// Everything a successful enrollment returns plus the locally generated

0 commit comments

Comments
 (0)