If your team already runs Nagios Core, you do not need the InfraCue Collector as well. Nagios can forward its host and service notifications to Network Pulse as signed webhooks, and those become device status, tickets and SLA timers alongside everything else.
InfraCue never connects into Nagios and never stores a Nagios credential. Traffic only ever goes outbound, from your Nagios host to us.
This has been tested end to end against Nagios Core 4.5. The handler needs curl and openssl on the Nagios host. It uses jq when it is available and falls back to plain shell when it is not, so a minimal box is fine.
Step 1 — Create the connection in InfraCue
- Open the Integrations tabNetwork Pulse → Integrations.
- Name the integrationSomething you will recognise, such as Nagios — DC1.
- Choose Nagios as the sourceThen select Create signed endpoint.
- Copy the credentials before you leave the pageThe endpoint, the integration key and the signing secret. The secret is shown once and is never displayed again.
Step 2 — Install the notification handler
Save the script below on the Nagios host as /opt/infracue/infracue-notify.sh and make it executable with chmod +x /opt/infracue/infracue-notify.sh.
#!/bin/sh
# InfraCue notification handler for Nagios Core.
#
# Posts a signed host or service notification to a workspace's Network Pulse ingest
# endpoint. The JSON keys below are the ones NetworkProviderAdapter::fromNagios()
# reads; keep the two in step or a real notification normalizes to nothing and is
# silently dropped.
#
# Signing matches NetworkPulseService::authenticateRequest():
# X-InfraCue-Signature: sha256=HMAC_SHA256(timestamp + "." + rawBody, secret)
#
# Usage (from a Nagios command definition - see README.md):
# infracue-notify.sh host "$HOSTNAME$" "$HOSTADDRESS$" "$HOSTSTATE$" \
# "$NOTIFICATIONTYPE$" "$HOSTOUTPUT$" "$LONGDATETIME$"
# infracue-notify.sh service "$HOSTNAME$" "$HOSTADDRESS$" "$SERVICEDESC$" \
# "$SERVICESTATE$" "$NOTIFICATIONTYPE$" "$SERVICEOUTPUT$" \
# "$LONGDATETIME$"
#
# Configuration comes from the environment so the secret never appears in a Nagios
# config file, in `ps`, or in a notification log line:
# INFRACUE_ENDPOINT, INFRACUE_KEY, INFRACUE_SECRET
set -eu
: "${INFRACUE_ENDPOINT:?INFRACUE_ENDPOINT is not set}"
: "${INFRACUE_KEY:?INFRACUE_KEY is not set}"
: "${INFRACUE_SECRET:?INFRACUE_SECRET is not set}"
kind=$1
# Plugin output is arbitrary text: it routinely contains quotes, backslashes and, for
# a long-output plugin, newlines. jq is correct by construction; the fallback exists
# because a minimal Nagios box often has no jq, and unescaped output would produce a
# body that is not JSON at all - which fails as a 400 long after the alert mattered.
json_string() {
if [ -n "${HAVE_JQ:-}" ]; then
printf '%s' "$1" | jq -Rs .
else
printf '%s' "$1" \
| sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/\r/\\r/g' -e 's/\t/\\t/g' \
| awk 'BEGIN{ORS=""; print "\""} {if (NR>1) print "\\n"; print} END{print "\""}'
fi
}
command -v jq >/dev/null 2>&1 && HAVE_JQ=1 || HAVE_JQ=
if [ "$kind" = "service" ]; then
hostname=$2; hostaddress=$3; servicedesc=$4; state=$5; notificationtype=$6; output=$7; when=$8
body=$(printf '{"hostname":%s,"hostaddress":%s,"servicedesc":%s,"servicestate":%s,"notificationtype":%s,"output":%s,"longdatetime":%s}' \
"$(json_string "$hostname")" "$(json_string "$hostaddress")" "$(json_string "$servicedesc")" \
"$(json_string "$state")" "$(json_string "$notificationtype")" "$(json_string "$output")" \
"$(json_string "$when")")
else
hostname=$2; hostaddress=$3; state=$4; notificationtype=$5; output=$6; when=$7
body=$(printf '{"hostname":%s,"hostaddress":%s,"hoststate":%s,"notificationtype":%s,"output":%s,"longdatetime":%s}' \
"$(json_string "$hostname")" "$(json_string "$hostaddress")" "$(json_string "$state")" \
"$(json_string "$notificationtype")" "$(json_string "$output")" "$(json_string "$when")")
fi
timestamp=$(date +%s)
# openssl only accepts the HMAC key as an argument, so it is briefly visible in `ps`
# on the Nagios host. That is the same exposure as any openssl -hmac use and is why
# the secret comes from the environment rather than a Nagios config file - the config
# is world-readable on a default install, `ps` is not persistent.
signature=$(printf '%s.%s' "$timestamp" "$body" | openssl dgst -sha256 -hmac "$INFRACUE_SECRET" -r | cut -d' ' -f1)
curl -sS --max-time 15 -X POST "$INFRACUE_ENDPOINT" \
-H 'Content-Type: application/json' \
-H "X-InfraCue-Integration-Key: $INFRACUE_KEY" \
-H "X-InfraCue-Timestamp: $timestamp" \
-H "X-InfraCue-Signature: sha256=$signature" \
-d "$body"
Step 3 — Give Nagios the credentials
The script reads the three values from its environment rather than from a Nagios configuration file, because Nagios configuration is world-readable on a default install. On a systemd host, add an override with systemctl edit nagios:
[Service]
Environment="INFRACUE_ENDPOINT=https://<your-workspace>/api/network-pulse/ingest.php?company=<slug>"
Environment="INFRACUE_KEY=<integration key>"
Environment="INFRACUE_SECRET=<signing secret>"
Then systemctl daemon-reload && systemctl restart nagios. In a container, set the same three as environment variables.
Step 4 — Define the commands and the contact
Add this to your Nagios objects configuration, then reload Nagios:
define command {
command_name notify-host-by-infracue
command_line /opt/infracue/infracue-notify.sh host "$HOSTNAME$" "$HOSTADDRESS$" "$HOSTSTATE$" "$NOTIFICATIONTYPE$" "$HOSTOUTPUT$" "$LONGDATETIME$"
}
define command {
command_name notify-service-by-infracue
command_line /opt/infracue/infracue-notify.sh service "$HOSTNAME$" "$HOSTADDRESS$" "$SERVICEDESC$" "$SERVICESTATE$" "$NOTIFICATIONTYPE$" "$SERVICEOUTPUT$" "$LONGDATETIME$"
}
define contact {
contact_name infracue
alias InfraCue Network Pulse
host_notification_period 24x7
service_notification_period 24x7
host_notification_options d,u,r,s
service_notification_options w,u,c,r,s
host_notification_commands notify-host-by-infracue
service_notification_commands notify-service-by-infracue
}
define contactgroup {
contactgroup_name infracue-admins
alias InfraCue
members infracue
}
Then add infracue-admins to the contact_groups of the hosts and services you want forwarded. Start with a small group and widen it once you are happy with the signal.
What each Nagios state becomes
| In Nagios | InfraCue severity | Device status |
|---|---|---|
| host DOWN or UNREACHABLE, service CRITICAL | critical | down |
| service WARNING | warning | degraded |
| host UP, service OK | info | up |
| service UNKNOWN | info | unknown |
| notification type contains DOWNTIMESTART | info | maintenance |
Two behaviours worth knowing
A service is its own device. edge-router-01 and edge-router-01 / WAN link appear as two rows in Network Pulse. That is deliberate: a host check and a service check are different signals, and collapsing them would let one quietly overwrite the other's status.
UNKNOWN is not an outage. A plugin that failed to return data tells you something about the check, not about the device, so it maps to unknown at info severity and cannot raise a ticket.
Before you rely on it
- Run the test command from the Integrations screen and confirm a device appears.
- Remember that Nagios only notifies on HARD states. With the default
max_check_attemptsof 3, a problem has to persist for three checks before anything is sent — which is usually what you want, but explains an apparently silent integration during testing. - Check the Nagios host clock. Signed requests are rejected if the timestamp is more than five minutes away from ours.
- Confirm recovery notifications are enabled (
rin the options above), or devices will go down in InfraCue and never come back up.
If you have customised your notifications heavily
The commands above pass the standard Nagios macros. If you would rather build your own payload, use the Generic signed webhook source instead and map your fields to the documented shape — see forwarding any monitoring tool with a signed webhook.