nscatools

package module
v0.0.0-...-ca8ef6b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2017 License: Apache-2.0 Imports: 13 Imported by: 1

README

Nsca tools library

GoDoc TravisBuild

Introduction

This library is based Nagios's NSCA server but written in Go.

The goal is to have a library to receive the nsca calls and do whatever you want with the data you receive. Working on that for another application I'm writing.

The technical documentation is available on godoc: https://godoc.org/github.com/tubemogul/nscatools

Prerequisites

For now, due to libmcrypt specificities, this library uses directly the C bindings of libmcrypt, so you will need the libmcrypt4 and libmcrypt-dev packages installed (at least that's their names on Debian-based systems).

Usage examples

Create a NSCA server

This example shows how to use this library to the detail of every packets you receive. Not very useful as is but simple enough for everybody to understand it.

package main

import (
  nsca "github.com/tubemogul/nscatools"
  "log"
  "os"
)

var dbg *log.Logger

func printData(p *nsca.DataPacket) error {
  dbg.Printf("version: %d\n", p.Version)
  dbg.Printf("crc: %d\n", p.Crc)
  dbg.Printf("timestamp: %d\n", p.Timestamp)
  dbg.Printf("state: %d\n", p.State)
  dbg.Printf("hostname: %s\n", p.HostName)
  dbg.Printf("service: %s\n", p.Service)
  dbg.Printf("Plugin output: %s\n", p.PluginOutput)
  return nil
}

func main() {
  debugHandle := os.Stdout
  dbg = log.New(debugHandle, "[DEBUG] ", log.Ldate|log.Ltime|log.Lshortfile)

  cfg := nsca.NewConfig("localhost", 5667, nsca.EncryptXOR, "toto", printData)
  nsca.StartServer(cfg, true)
}

To do functionnal testing, you can, for example, use the following send_nsca.cfg file:

password=toto
encryption_method=1

And use the following command:

echo "myhost mysvc 1 mymessage" | sudo /usr/sbin/send_nsca -H 127.0.0.1 -p 5667 -d ' ' -c send_nsca.cfg
Create a NSCA client

This example shows how to implement a nsca client using this library. You can use it directly with the running server you created in the previous example.

package main

import (
  "fmt"
  nsca "github.com/tubemogul/nscatools"
)

func main() {
  cfg := nsca.NewConfig("localhost", 5667, nsca.EncryptXOR, "toto", nil)
  err := nsca.SendStatus(cfg, "myHost", "my service", nsca.StateWarning, "You'd better fix me before I go critical")
  if err != nil {
    fmt.Printf("SendStatus returned an error: %s\n", err)
  } else {
    fmt.Println("Packet sent successfuly")
  }
}

Using the Makefile

  • make lint: runs golint on your files (requires github.com/golang/lint/golint installed)
  • make fmt: checks that the files are compliant with the gofmt format
  • make vet: runs go tool vet on your files to ensure there's no problems
  • make test: runs make lint, make fmt, make vet before running all the test, printing also the percentage of code coverage
  • make race: runs the tests with the -race option to detect race conditions
  • make bench: runs the benchmarks
  • make gocov: runs a gocov report (requires github.com/axw/gocov/gocov)
  • make install: runs make test before running a clean and install
  • make / make all: run make test, make race and make bench

Contributions

Contributions to this project are welcome, though please file an issue. before starting work on anything major as someone else could already be working on it.

Contributions that do not provide the corresponding tests will not be accepted. Contributions that do not pass the basic gofmt, vet and other basic checks provided in the Makefile will not be accepted. It's just a question of trying to keep a basic code standard. Thanks for your help! :)

Documentation

Overview

Package nscatools is a flexible library that allows you to easily create a custom NSCA (Nagios Service Check Acceptor) client and server in pure Go. Note: the package requires libmcrypt to work for now (under Debian-based systems, the packages are named libmcrypt4 and libmcrypt-dev)

Index

Constants

View Source
const (
	EncryptNone        = iota // no encryption
	EncryptXOR                // Simple XOR  (No security, just obfuscation, but very fast)
	EncryptDES                // DES
	Encrypt3DES               // 3DES or Triple DES
	EncryptCAST128            // CAST-128
	EncryptCAST256            // CAST-256
	EncryptXTEA               // xTEA
	Encrypt3WAY               // 3-WAY
	EncryptBLOWFISH           // SKIPJACK
	EncryptTWOFISH            // TWOFISH
	EncryptLOKI97             // LOKI97
	EncryptRC2                // RC2
	EncryptARCFOUR            // RC4
	EncryptRC6                // RC6 - Unsupported in standard NSCA
	EncryptRIJNDAEL128        // AES-128
	EncryptRIJNDAEL192        // AES-192
	EncryptRIJNDAEL256        // AES-256
	EncryptMARS               // MARS - Unsupported in standard NSCA
	EncryptPANAMA             // PANAMA - Unsupported in standard NSCA
	EncryptWAKE               // WAKE
	EncryptSERPENT            // SERPENT
	EncryptIDEA               // IDEA - Unsupported in standard NSCA
	EncryptENIGMA             // ENIGMA (Unix crypt)
	EncryptGOST               // GOST
	EncryptSAFER64            // SAFER-sk64
	EncryptSAFER128           // SAFER-sk128
	EncryptSAFERPLUS          // SAFER+
)

Encrypt* are the encryptions supported by the standard NSCA configuration

View Source
const (
	StateOK = iota
	StateWarning
	StateCritical
	StateUnknown
)

State* are the states understood by NSCA

View Source
const LongPacketLength = 4304

LongPacketLength - long one:

View Source
const MaxPacketAge = 30

MaxPacketAge is the number of seconds difference allowed between the initialization packet epoch and the epoch of the data packet received

View Source
const ShortPacketLength = 720

ShortPacketLength - short one:

Variables

This section is empty.

Functions

func HandleClient

func HandleClient(conf *Config, conn net.Conn, logErr *log.Logger) error

HandleClient takes care of a client connection. Use the PacketHandler parameter to define what you want to do with the DataPacket once it is decrypted and trasformed to a DataPacket struct. Only the errors will be logged via the logger parameter

func MCrypt

func MCrypt(algo string, blocks, key, iv []byte, decrypt bool) error

MCrypt uses libmcrypt to decrypt/encrypt the data received from the send_nsca client. When I have some more time I'll dig to find out why I'm not able to decrypt directly using the NewCFBDecrypter To decrypt, set the decrypt parameter to true, else it will encrypt.

func SendStatus

func SendStatus(conf *Config, clientHost string, service string, status int16, message string) error

SendStatus connects to the nsca server and sends the provided data in the right format. If you want to send a host status (as opposed to a service status), just let the "service" parameter empty

func StartServer

func StartServer(conf *Config, debug bool)

StartServer starts an NSCA server

Types

type Config

type Config struct {
	// When initiating a server, Host is the IP to listen on
	// When initiating a client, Host is the target nsca host
	Host string
	// When initializing a server, Port is the port to listen on
	// When initializing a client, Port is the port of the target nsca server
	Port uint16
	// Encryption methid to use based on the standard NSCA encryptions list
	EncryptionMethod int
	// Password is used to encypt and decrypt the messages if EncryptionMethod is
	// not set to 0.
	Password string
	// Max size of each fields
	MaxHostnameSize     uint16
	MaxDescriptionSize  uint16
	MaxPluginOutputSize uint16
	// PacketHandler is the function that will handle the DataPacket in the
	// HandleClient function. You define waht you want to do with the DataPacket
	// once decrypted and transformed to a DataPacket struct.
	// This function should follow this: func(*dataPacket) error
	PacketHandler dataHandler
}

Config manages the configuration of the client and server objects

func NewConfig

func NewConfig(host string, port uint16, encryption int, password string, handler dataHandler) *Config

NewConfig initiates a Config object (with default values if zero values given)

type DataPacket

type DataPacket struct {
	Version      int16
	Crc          uint32
	Timestamp    uint32
	State        int16
	HostName     string
	Service      string
	PluginOutput string
	Ipkt         *InitPacket
	Password     []byte
	Encryption   int
}

DataPacket stores the data received for the client-server communication

func NewDataPacket

func NewDataPacket(encryption int, password []byte, ipkt *InitPacket) *DataPacket

NewDataPacket initializes a new blank data packet

func (*DataPacket) CalculateCrc

func (p *DataPacket) CalculateCrc(buffer []byte) uint32

CalculateCrc returns the Crc of a packet ready to be sent over the network, ignoring the Crc data part of it as it's done in the original nsca code

func (*DataPacket) Decrypt

func (p *DataPacket) Decrypt(buffer []byte) error

Decrypt decrypts a buffer

func (*DataPacket) Encrypt

func (p *DataPacket) Encrypt(buffer []byte) error

Encrypt encrypts a buffer

func (*DataPacket) Read

func (p *DataPacket) Read(conn io.Reader) error

Read gets the data packet and populates the attributes of the DataPacket according. When encountering an error, it returns the error and don't process further.

func (*DataPacket) Write

func (p *DataPacket) Write(w io.Writer) error

Write generates the buffer to write to the writer based on the populated fields of the DataPacket instance encrypts it if needed and send it to the writer. When encountering an error, it returns the error and don't process further.

type InitPacket

type InitPacket struct {
	// initialization vector is a 128 bytes array
	Iv        []byte
	Timestamp uint32
}

InitPacket is used during the handshake with the client

func NewInitPacket

func NewInitPacket() (*InitPacket, error)

NewInitPacket initialize an InitPacket by creating a random initialization vector and filling the timestamp attribute with the current epoch time

func (*InitPacket) Read

func (p *InitPacket) Read(r io.Reader) error

Read fetches the init packet from an io.Reader such as a TCPConnection and fills the current InitPacket instance attributes with it

func (*InitPacket) Write

func (p *InitPacket) Write(w io.Writer) error

Write writes the current InitPacket to an io.Writer such as a TCPConnection

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL