Product

Network Pulse Incident Operations Asset Lifecycle Engineer & SLA Inventory & Spares Operations Wallboard

Solutions

Manufacturing Healthcare Education Corporate & Multi-location IT

More

Pricing Blog Help Centre FAQ
Start Free Trial Book a Live Demo Sign in to your workspace

Help Center › Visibility and reporting

Forward Nagios alerts to Network Pulse

Forward Nagios Core host and service notifications to InfraCue Network Pulse as signed webhooks: the handler script, command definitions, state mapping and downtime handling.

Updated 28 Sep 2026

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

  1. Open the Integrations tabNetwork Pulse → Integrations.
  2. Name the integrationSomething you will recognise, such as Nagios — DC1.
  3. Choose Nagios as the sourceThen select Create signed endpoint.
  4. 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_attempts of 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 (r in 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.