golang client for nrpe

What is NRPE

NRPE stands for Nagios Remote Plugin Executor. It’s a nagios plugin widely used to monitor remote Linux/Unix services or network devices. NRPE allows nagios to monitor any local resources like CPU, Memory, Load, etc by communicating with a NRPE daemon running on the remote server and listening to a port. The communication is done over TCP using the NRPE protocol. Here is a nicely put explanation of the protocol. This information can be then used to build custom monitoring tools/dashboards, integration into alerting systems, etc. It is open source and the new version is promised to be there soon with improvements. For examples of typical installation, please checkout the official documentation which I found really well-written.

In order to be able to develop a simple golang webservice that would be able to translate nagios checks into alerting of our choice - be that a text file, an image, an sms or a bell ring, we came up with a need to create a golang client that would be able to communicate with a NRPE daemon running on the remote host.

We wanted to keep the service as simple as possible, so that we would reuse the already setup checks on our nagios systems, and so all we need is a client communicating with a remote host using NRPE protocol. After some research we could not find a decent nrpe library which will work out of the box, and as the NRPE protocol seemed quite easy, we implemented it ourselves.

You can jump straight away to the code.

But if you want to see it in action and also get into some implementation details, follow me!

Bringing NRPE up

Environment used in this example:

  • host: MacOS 10.10.5
  • coreOS: alpha (1000.0.0)
  • Docker: version 1.10.3
  • NRPE: version 2.15

This is a sample Dockerfile that would bring an nrpe server up, as well as install the default command line, so that we can run some examples, before implementing those in our service.


FROM debian:latest

RUN apt-get update
RUN apt-get install -y nagios-nrpe-server
RUN apt-get install -y nagios-nrpe-plugin

EXPOSE 5666

ENTRYPOINT ["/bin/bash", "-c", "/etc/init.d/nagios-nrpe-server start;/bin/bash"]

docker build -t nrpe_image .
Step 1 : FROM debian:latest
 ---> bb5d89f9b6cb
Step 2 : RUN apt-get update
 ---> Using cache
 ---> 7ef3f71357bf
Step 3 : RUN apt-get install -y nagios-nrpe-server
 ---> Using cache
 ---> 9e773d916f1c
Step 4 : RUN apt-get install -y nagios-nrpe-plugin
 ---> Using cache
 ---> 1818ca254163
Step 5 : EXPOSE 5666
 ---> Using cache
 ---> 673f2b1be64b
Step 6 : ENTRYPOINT /etc/init.d/nagios-nrpe-server start;/bin/bash
 ---> Using cache
 ---> b8ba63d2b07d
Successfully built b8ba63d2b07d

docker run -itd --name nrpe nrpe_image

We now have a docker instance that’s running an nrpe server. In order to see the check_nrpe in action, we can run this example command line inside our nrpe docker instance

docker exec nrpe /usr/lib/nagios/plugins/check_nrpe -H 127.0.0.1 -c check_load
OK - load average: 0.03, 0.05, 0.05|load1=0.030;15.000;30.000;0; load5=0.050;10.000;25.000;0; load15=0.050;5.000;20.000;0;

We basically wish to get the same result using go code.

golang client

Let’s start another docker instance from golang as our playground.

docker run -itd --name go-nrpe golang:1.6
docker exec -it go-nrpe /bin/bash
506e02de7123

Now that we have running go environment let’s make a folder for our future monitoing tool and start using the library

mkdir -p /go/src/monitoring-tool

Here is a code example, that uses the library we created to communicate with NRPE server using nrpe protocol


package main

import (
    "fmt"
    "net"
    "os"

    "github.com/envimate/nrpe"
)

func main() {
    conn, err := net.Dial("tcp", "nrpe:5666")
    if err != nil {
        fmt.Println(err)
        return
    }

    command := nrpe.NewCommand("check_load")

    // ssl = true, timeout = 0
    result, err := nrpe.Run(conn, command, true, 0)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(result.StatusLine)
    os.Exit(int(result.StatusCode))
}

Save this into a file called nrpe_monitoring.go.

The code is pretty-much self explanatory: we

  • Open a tcp connection to the NRPE server and the port it listens to (5666 by default)
  • Create required command ( note: the library allows passing arguments to the command, although that needs extra tweaking on NRPE server side)
  • Run the command with specificed ssl flag and timeout. (ssl flag depends on your setup, having a non-ssl daemon is a NRPE compile time option)

As a result we get the output line, which is the same load check as we saw before and the StatusCode.

In order for this example to work we need to make sure that we have access to the docker container running our nrpe server.

For that we will create a docker network and connect both of the containers to it.

docker network create --subnet=176.0.45.0/24 nrpe_network
4f083ad03f25cafac9c09e0dda19d7657c3545569abe7a3902a1cb12015671c2

The subnet can be arbitraty as long as you specify it during the network creation so that we also use it to configure NRPE server.

Next, let’s connect the 2 running docker instances to this network

docker network connect nrpe_network nrpe
docker network connect nrpe_network go-nrpe

Now we are also need to configure the nrpe server to allow clients from the created network to run checks. That’s done using allowed_hosts parameter in nrpe config file

echo "allowed_hosts=176.0.45.0/24" | docker exec -i nrpe tee /etc/nagios/nrpe_local.cfg
allowed_hosts=176.0.45.0/24
docker exec -i nrpe /etc/init.d/nagios-nrpe-server restart
Stopping nagios-nrpe: nagios-nrpe.
Starting nagios-nrpe: nagios-nrpe.

We are now good to go! Get back to the go-nrpe docker. In order to run this example we would also need the package libssl-dev installed and the nrpe client needs to communicate with the server securely.

docker exec -it go-nrpe /bin/bash

cd src/monitoring-tool
apt-get update && apt-get install -y libssl-dev
go get
go run nrpe_monitoring.go
OK - load average: 0.03, 0.07, 0.06|load1=0.030;15.000;30.000;0; load5=0.070;10.000;25.000;0; load15=0.060;5.000;20.000;0;

We see the same output as running from the nagios nrpe client!

The example Dockerfile I used in this post is available in the same repo

We saw how to communicate from our golang service to an NRPE daemon. The next step will be creating the daemon-replacement listener that will allow us implementing custom checks.

More Reading
Older// gomongo part 2