Network Checks
Goal: Monitor network connectivity and service availability — host reachability (ping), TCP port connectivity, and HTTP endpoint health.
Prerequisites
Enable the CheckNet module in nsclient.ini:
[/modules]
CheckNet = enabled
NRPEServer = enabled ; if using NRPE
Or load it temporarily in the test shell:
load CheckNet
Ping (ICMP Reachability)
Use check_ping to verify that a host responds to ICMP echo requests.
Command
check_ping host=192.168.0.1
Expected output (healthy)
OK: All 1 hosts are ok
'192.168.0.1_loss'=0%;5;10 '192.168.0.1'=2ms;60;100
Expected output (alert)
CRITICAL: CRITICAL: 192.168.0.1: loss 100%
'192.168.0.1_loss'=100%;5;10 '192.168.0.1'=0ms;60;100
Default thresholds: - Warning: response time > 60 ms or packet loss > 5% - Critical: response time > 100 ms or packet loss > 10%
Common scenarios
Ping multiple hosts at once:
check_ping host=192.168.0.1 host=8.8.8.8 host=google.com total
Tighter thresholds:
check_ping host=8.8.8.8 count=4 timeout=300 "warn=time > 30 or loss > 0%" "crit=time > 80 or loss > 25%"
Custom output showing each host's latency:
check_ping host=192.168.0.1 host=192.168.0.2 "top-syntax=%(status): %(list)" "detail-syntax=%(host)=%(time)ms"
OK: 192.168.0.1=2ms, 192.168.0.2=22ms
Via NRPE:
check_nrpe -H <agent-ip> -c check_ping --argument "host=192.168.0.1"
TCP Port Connectivity
Use check_tcp to verify that a TCP port is open and accepting connections.
Command
check_tcp host=192.168.0.1 port=443
Expected output (healthy)
OK: Connected to 192.168.0.1:443
'time'=5ms;100;500
Expected output (alert — port closed or refused)
CRITICAL: CRITICAL: Failed to connect to 192.168.0.1:443
Common scenarios
Check multiple services:
check_tcp host=myserver.example.com port=80 ; HTTP
check_tcp host=myserver.example.com port=443 ; HTTPS
check_tcp host=myserver.example.com port=3306 ; MySQL
check_tcp host=myserver.example.com port=1433 ; SQL Server
Set a tighter connection timeout:
check_tcp host=myserver.example.com port=443 timeout=2000 "warn=time > 200" "crit=time > 1000"
Use a service preset (sets the port and validates the greeting) — ftp, pop, imap, smtp, ssh, and the implicit-TLS variants spop, simap, ssmtp:
check_tcp host=mail.example.com service=smtp
check_tcp host=mail.example.com service=ssmtp ; SMTP-over-TLS on port 465
Wrap the connection in TLS and (optionally) verify the server certificate or
pin a minimum protocol version (tls-version accepts tlsv1.0…tlsv1.3, sslv3):
check_tcp host=secure.example.com port=443 ssl=true
check_tcp host=secure.example.com port=443 ssl=true verify=peer ca=/etc/ssl/certs/ca-certificates.crt
check_tcp host=secure.example.com port=443 ssl=true tls-version=tlsv1.2+
Match the peer's banner/response with a regex via the response keyword:
check_tcp host=mail.example.com port=25 "crit=response not regexp '^220'"
Via NRPE:
check_nrpe -H <agent-ip> -c check_tcp --argument "host=myserver.example.com" --argument "port=443"
SSH Service Check
Use check_ssh to confirm an SSH server is up and presenting a valid banner. It
connects (default port 22), reads the greeting and requires it to start with
SSH-. Nothing is written to the peer, so no key exchange or authentication
takes place.
Command
check_ssh host=192.168.0.10
Expected output (healthy)
OK: 192.168.0.10:22 ok in 3ms
A port that answers but is not SSH yields no_match (CRITICAL); a closed port
yields refused. Use a non-standard port with port=2222, and tighten timing
with "crit=time > 1000 or result != 'ok'".
HTTP / HTTPS Endpoint Health
Use check_http to verify that a web endpoint is reachable, returns the expected HTTP status code, and responds within a given time.
Command
check_http url=https://myapp.example.com/health
Expected output (healthy)
OK: https://myapp.example.com/health -> 200 ok (1234B in 45ms)
'https://myapp.example.com/health_code'=200;0;200 'https://myapp.example.com/health_size'=1234B;0;0 'https://myapp.example.com/health'=45ms;5000;0
Expected output (alert — HTTP 500)
CRITICAL: https://myapp.example.com/health -> 500 http_500 (512B in 23ms)
Expected output (alert — connection failure)
CRITICAL: https://myapp.example.com/health -> 0 error: resolve: host not found
Common scenarios
Check an HTTPS endpoint with explicit host and path components:
check_http protocol=https host=myapp.example.com port=443 path=/health
Require a specific string in the response body:
check_http url=https://myapp.example.com/health expected-body="status: ok"
If the string is absent, the check goes CRITICAL.
Check multiple URLs:
check_http url=https://myapp.example.com/ url=https://myapp.example.com/api/status
Tighter latency and error thresholds:
check_http url=https://myapp.example.com/ timeout=10000 \
"warn=time > 500 or code >= 400" \
"crit=time > 2000 or code >= 500 or result != 'ok'"
Custom output format:
check_http url=https://myapp.example.com/ \
"top-syntax=%(status): %(list)" \
"detail-syntax=%(url) -> %(code) in %(time)ms"
OK: https://myapp.example.com/ -> 200 in 45ms
Send custom headers (e.g., for API authentication):
check_http url=https://myapp.example.com/api header="Authorization: Bearer mytoken"
Use HTTP Basic authentication:
check_http url=https://myapp.example.com/private username=admin password=secret
Use a different HTTP method / POST a body (post-data implies POST):
check_http url=https://myapp.example.com/health method=HEAD
check_http url=https://myapp.example.com/api method=POST post-data="ping=1" content-type="application/json"
Follow redirects (by default a 3xx is reported as-is; onredirect=follow chases the Location):
check_http url=http://myapp.example.com/ onredirect=follow
Accept a set of status codes / match the body with a regex (via the code and body keywords):
check_http url=https://myapp.example.com/ "warn=code not in (200,301,302)" "crit=body not regexp 'Welcome'"
Warn before the TLS certificate expires (ssl_expiry_days):
check_http url=https://myapp.example.com/ "warn=ssl_expiry_days < 30" "crit=ssl_expiry_days < 7"
Verify the certificate and control the TLS version. By default check_http
verifies the server certificate against the system CA bundle (verify=peer)
and requires TLS 1.2 or newer (tls-version=tlsv1.2+), so a handshake
against an untrusted or expired chain fails the check. Point ca= at a private
CA, relax verification for a self-signed endpoint, override the SNI/verification
hostname, or tighten the negotiated protocol:
check_http url=https://internal.example.com/ ca=/etc/ssl/private/corp-ca.pem
check_http url=https://self-signed.example.com/ verify=none
check_http url=https://myapp.example.com/ tls-version=tlsv1.3 ; CRITICAL if the server can't negotiate TLS 1.3
check_http url=https://vhost.example.com/ sni=canonical.example.com
Accepted tls-version values are tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.2+
(default), tlsv1.3 and sslv3. Combine with ssl_expiry_days to catch an
expiring and an untrusted or weak-protocol certificate in one check.
Assert on values inside a JSON response body (--json-path). Each
alias:path extracts a value from the parsed JSON and turns it into a filter
keyword you can threshold on (and it is emitted as perfdata). Numeric path
segments index into arrays; single-quote a segment that itself contains a dot:
check_http url=https://api.example.com/health "json-path=qlen:data.queue.length" "crit=qlen > 100"
check_http url=https://api.example.com/health "json-path=st:status" "crit=st != 'ok'"
check_http url=https://api.example.com/health "json-path=err:metrics.error_rate" "warn=err > 0.01" "crit=err > 0.05"
check_http url=https://api.example.com/health "json-path=first:items.0.name" "json-path=cfg:'a.b'.c"
Numeric values keep full precision (so err > 0.05 works on 0.06), string
values compare and render as strings, and booleans read as 1/0. A path that
is missing (or a body that is not JSON) leaves the alias empty rather than
failing the check. Multiple --json-path options can be combined with the usual
warning=/critical= boolean expressions.
Via NRPE:
check_nrpe -H <agent-ip> -c check_http --argument "url=https://myapp.example.com/health"
Warning
Passing arguments via NRPE requires allow arguments = true in the NRPE server configuration. See NRPE security.
DNS Resolution Check
Use check_dns to verify that a hostname resolves to the expected IP address.
Command
check_dns host=myapp.example.com
Require a specific resolution result:
check_dns host=myapp.example.com server=8.8.8.8 "crit=address != '93.184.216.34'"
Query a specific record type (A, AAAA, MX, TXT, CNAME, NS, SOA, PTR):
check_dns host=example.com type=MX server=8.8.8.8
OK: example.com -> 10 smtp.example.com (1) in 9ms [ok]
A/AAAA lookups without server= use the system resolver; any other record type,
or an explicit server=, uses a direct DNS-over-UDP query. Add port= for a
non-standard resolver port and norecursion=true to query an authoritative
server directly.
Remote Agent Availability
Use check_nsclient_web_online from a central host to confirm that a remote
NSClient++ agent's REST API is online, or to run a check on it and pass the result
through.
Command
check_nsclient_web_online url=https://192.168.0.10:8443 password=secret
Expected output
OK: REST API reachable on https://192.168.0.10:8443
Run a remote check and mirror its result locally with command=:
check_nsclient_web_online url=https://192.168.0.10:8443 password=secret command=check_cpu
A wrong password reports Authentication failed (HTTP 403); an unreachable
agent is CRITICAL. The remote certificate is not verified by default
(verify=none) since agents usually present a self-signed certificate — set
verify=peer with ca= to enforce it.
Configuration Example
[/modules]
CheckNet = enabled
NRPEServer = enabled
[/settings/NRPE/server]
allowed hosts = 10.0.0.1
port = 5666
allow arguments = true ; needed to pass host/url as arguments
Next Steps
- Windows Server Health — combine network checks with system health checks
- External Scripts — run custom network checks via scripts
- Checks In Depth: Filters — understand filter and threshold expressions
- Reference: CheckNet — full command reference