Skip to content

Passive Monitoring with NSCA/NRDP

Goal: Have NSClient++ run checks on a schedule and push the results to your monitoring server — without the monitoring server needing to poll each machine.

Tip

Passive monitoring is ideal when the monitored machines are behind a firewall, are in a DMZ, or when you want to distribute the check workload across many agents rather than centralising it on the monitoring server.


How Passive Monitoring Works

In active (NRPE) monitoring, the monitoring server initiates contact and polls the agent:

Monitoring Server ──check_nrpe──► NSClient++ → runs check → returns result

In passive monitoring, the agent runs checks on its own schedule and pushes results to the server:

NSClient++ (Scheduler) → runs check → NSCAClient ──────► Monitoring Server (NSCA daemon)

The monitoring server simply waits for results. If no result arrives within the expected time window, the monitoring server raises a "freshness" alert.


Prerequisites

Enable these modules in nsclient.ini:

[/modules]
CheckSystem  = enabled   ; provides check_cpu, check_memory, etc.
CheckDisk    = enabled   ; provides check_drivesize
Scheduler    = enabled   ; runs checks on a timer
NSCAClient   = enabled   ; pushes results to the NSCA server

Step 1 — Verify the NSCA Connection

Before configuring scheduled checks, verify that NSClient++ can send a test result to the NSCA server.

nscp nsca --host <nagios-server-ip> ^
    --password secret-password ^
    --encryption aes256 ^
    --command "service check" ^
    --result 2 ^
    --hostname "my-windows-host" ^
    --message "Hello from NSClient++"

Note

The ^ character is the Windows Command Prompt line-continuation character. In PowerShell use a backtick (`) instead, or write the command on a single line.

Expected output:

Submission successful

If you have set up a test result file on the NSCA server, you should see:

[timestamp] PROCESS_SERVICE_CHECK_RESULT;my-windows-host;service check;2;Hello from NSClient++

NSCA server-side configuration

The NSCA daemon needs the matching cipher and password in its nsca.cfg:

decryption_method = 14
password          = secret-password

If you're troubleshooting the connection, redirect the result file to a path you can tail to see what arrives:

command_file = /tmp/result.txt

Note

The password is a shared secret — both sides must use the same value, and it isn't authenticated in the cryptographic sense (no challenge/response). Use a strong, long password to make brute-force impractical.

NSCA encryption reference

NSClient++ uses Crypto++; NSCA uses libmcrypt. The two libraries don't share a common identifier, so the matching is by table:

NSClient++ value NSCA method Security
none 0 ⚠️ Not secure — avoid
xor 1 ⚠️ Not secure — avoid
des 2 ⚠️ Insecure
3des 3 ⚠️ Legacy
cast128 4 🟡 Moderate
xtea 6 🟡 Moderate
blowfish 8 🟡 Moderate
twofish 9 🟢 Very secure
rc2 11 ⚠️ Insecure
aes256 14 ✅ Industry standard (default)
serpent 20 🟢 Paranoid
gost 23 ⚠️ Questionable

AES naming gotcha

NSCA names ciphers by block size, NSClient++ names them by key size. NSCA's RIJNDAEL-128 (method 14) is what NSClient++ calls aes256 — same algorithm, different label. NSCA only supports AES with a 128-bit block, so the other AES-named NSCA values are not valid choices.


Step 2 — Configure the Scheduler

The Scheduler module runs your checks at regular intervals and sends results to a channel (NSCA by default).

Set default parameters for all scheduled jobs:

[/settings/scheduler/schedules/default]
channel  = NSCA    ; which channel to send results to
interval = 5m      ; how often to run each check
report   = all     ; send results regardless of status (OK, WARN, CRIT)

Add scheduled checks:

[/settings/scheduler/schedules]
; Format: check_name = check_command [arguments...]
host_check = check_ok
cpu        = check_cpu
memory     = check_memory
disk_c     = check_drivesize drive=C: "warn=free < 20%" "crit=free < 10%"

Each key becomes the service name that Nagios/Icinga will see in the passive check result.

Note

The default schedule section applies its settings to all schedules that do not override them. You can override any setting per schedule by creating a dedicated section:

[/settings/scheduler/schedules/disk_c]
command  = check_drivesize drive=C: "warn=free < 20%" "crit=free < 10%"
interval = 15m   ; check disk less often than cpu/memory
channel  = NSCA
report   = all

Schedule options reference

Option Description
interval How often the check runs (e.g. 30s, 5m, 1h). Apply via the default template.
schedule Cron-style alternative to interval (see below). Use one or the other, not both.
command The check command to execute. With short-form (name = command) this is the value.
alias Name reported back to Nagios. Defaults to the schedule key, so usually omitted.
channel Target channel for the result. Defaults to NSCA; set this to fan out to other channels.
report Filter on which results are sent: all, ok, warning, critical, or comma-combinations.

Cron-style schedules

When you need finer control than "every N minutes" — e.g. "47 minutes past every hour", "weekdays at 06:00", or "every Sunday at midnight" — use schedule instead of interval. The five fields are the standard cron form: minute hour day-of-month month day-of-week.

[/settings/scheduler/schedules/disk_c]
command  = check_drivesize drive=C: "warn=free < 20%" "crit=free < 10%"
schedule = 47 * * * *      ; 47 minutes past every hour
channel  = NSCA

[/settings/scheduler/schedules/nightly_full]
command  = check_drivesize
schedule = 0 2 * * *       ; every day at 02:00
channel  = NSCA

[/settings/scheduler/schedules/weekday_office]
command  = check_cpu
schedule = */15 8-18 * * 1-5  ; every 15 min, 08:00–18:00, Mon–Fri
channel  = NSCA

Use interval for the simple recurring case; reach for schedule when you need a specific wall-clock time or weekday filter.

Short-form vs. long-form schedules

The [/settings/scheduler/schedules] block supports two equivalent shapes:

; Short form — the key is the alias, the value is the command.
[/settings/scheduler/schedules]
cpu  = check_cpu
mem  = check_memory
; Long form — one section per schedule, more knobs available.
[/settings/scheduler/schedules/cpu]
command  = check_cpu
interval = 30s

[/settings/scheduler/schedules/mem]
command  = check_memory
interval = 5m

Short form is concise but only carries command. Switch to long form when you need per-schedule overrides (interval, channel, alias, report).

Real-time channels

The Scheduler isn't the only thing that can publish into the NSCA channel. CheckLogFile and CheckEventLog can both publish results in real time — useful for surfacing log/event hits without waiting for the next scheduler tick. They share the same channel mechanism, so a result from CheckEventLog is indistinguishable from a scheduled one on the receiving side.

[/settings/eventlog/real-time/filters/critical-app]
log     = Application
filter  = level = 'error' AND source = 'MyApp'
channel = NSCA

Multiple targets

A single NSCAClient instance handles one target, but you can fan results out to multiple servers (or channels) by combining target sections with the channel knob on each schedule. The receiver matches by channel name.


Step 3 — Configure the NSCA Client

[/settings/NSCA/client/targets/default]
address    = <nagios-server-ip>
encryption = aes256
password   = secret-password

The password must match the password in the NSCA server's nsca.cfg.


Step 4 — Set the Hostname

NSClient++ must send results using the hostname as it is known in Nagios/Icinga. By default it uses the Windows computer name which may not match.

Auto-detect hostname:

[/settings/NSCA/client]
hostname = auto

Use a specific hostname:

[/settings/NSCA/client]
hostname = win-server-01.example.com

Build the hostname from system variables:

[/settings/NSCA/client]
hostname = ${host_lc}.${domain_lc}

Variables can be combined with literal text — for example to add a win_ prefix on Windows hosts that share a Linux-host naming convention:

[/settings/NSCA/client]
hostname = win_${host_lc}.${domain_lc}

Supported variables:

Variable Meaning
${host} Windows computer name (mixed case)
${host_lc} Lowercase
${host_uc} Uppercase
${domain} Windows domain name
${domain_lc} Domain lowercase
${domain_uc} Domain uppercase

Step 5 — Restart NSClient++

net stop nscp
net start nscp

After restart, NSClient++ will start executing scheduled checks and pushing results to the NSCA server. Your monitoring tool should begin receiving passive check results within one interval.


Complete Configuration Example

[/modules]
CheckSystem  = enabled
CheckDisk    = enabled
Scheduler    = enabled
NSCAClient   = enabled

[/settings/NSCA/client]
hostname = ${host_lc}.${domain_lc}

[/settings/NSCA/client/targets/default]
address    = 10.0.0.1
encryption = aes256
password   = s3cr3t_p@ssw0rd

[/settings/scheduler/schedules/default]
channel  = NSCA
interval = 5m
report   = all

[/settings/scheduler/schedules]
host_check = check_ok
cpu        = check_cpu
memory     = check_memory
disk_c     = check_drivesize drive=C: "warn=free < 20%" "crit=free < 10%"

Using NRDP Instead of NSCA

NRDP is a more modern HTTP-based alternative to NSCA. Replace NSCAClient with NRDPClient and update the configuration:

[/modules]
NRDPClient = enabled

[/settings/NRDP/client/targets/default]
address  = http://nagios-server/nrdp/
token    = my-nrdp-token

The scheduler configuration stays the same — just change channel = NSCA to channel = NRDP.


Troubleshooting

NSCA is fire-and-forget — the agent doesn't get a delivery acknowledgement, so a misconfigured client will look fine from NSClient++'s side and silent on the server side. The first place to look is the NSCA daemon log on the monitoring server:

sudo tail -f /var/log/syslog

A successful submission shows up as:

nsca: Connection from 192.168.0.104 port 8198
nsca: Handling the connection...
nsca: SERVICE CHECK -> Host Name: 'win-server-01', Service Description: 'CPU Load',
      Return Code: '0', Output: 'OK CPU Load ok.|...'
nsca: End of connection...

A misconfigured submission usually surfaces as:

nsca: Connection from 192.168.0.104 port 26117
nsca: Handling the connection...
nsca: Received invalid packet type/version from client

That message means almost always one of two things:

  • Wrong password — the shared secret on the agent doesn't match nsca.cfg's password.
  • Wrong encryption — the cipher mismatch (e.g. you set encryption = aes256 but the daemon has decryption_method = 9).

If the daemon log is silent altogether, the connection isn't reaching it — check address, port, firewalls, and allowed_hosts on the NSCA daemon.

To see what NSClient++ is sending, restart it in test mode:

net stop nscp
nscp test

…and watch the trace lines as the scheduler fires.


Monitoring Configuration on the Server Side

In Nagios/Icinga, define your services as passive with a freshness threshold:

define service {
    host_name              win-server-01.example.com
    service_description    CPU Load
    check_command          check_dummy!3!"No data received"
    passive_checks_enabled  1
    active_checks_enabled   0
    check_freshness         1
    freshness_threshold     600   ; seconds (10 minutes)
}

Next Steps