Netmond V2. Configuration examples

Here are several configuration examples with comments.


Remote host accessibility checking

Usually host accessibility and connectivity quality is checked with ping system utility. Sending a number of packets user estimate integral connectivity quality by reply times and packet loss.

At first, declare polling method with special parameters to use it late, in objects definition.

RootDir "/var/netmon"
Polling 120  # launch checking sequence every 2 minutes.
TimeFmt "%H:%M:%S" #  $TIME output format

Method "test" {
  ICMP      # use ICMP-echo a-la ping
  Size 512  # 512 bytes packet size
  Send 10   # send 10 packets 
  Timeout 1 # wait 1 sec for every reply packet
  Retries 1 # no repetitions
}

Second, declare suitable saving method to report host status by polling results:

Save "test" {
  Pipe "mail2staff" # generate e-mail message 
  State "$TIME $Name $STATE $test.send/$test.recv $test"
                    # example: "14:20:00 host-1 UP 10/10 15.432"
}

Now, apply above mentioned methods to host in a network:

Object "host-1" {
  Address "host.foo.bar"
  Method "test"
  Save "test"
}

Check firewalls and routers configuration to enable ICMP messages passing.


Object inquiring using Remote Shell

To monitor server load user can use uptime system utility on a remote UNIX host.

At first, declare polling method to use it late in objects definition. Username will supply via method argument - different servers may have different uses:

RootDir "/var/netmon"
Polling 60 # once per minute

Method "get-loadave" {
  TCP Port 514       # standard rshd tcp port
  Localport 512 1023 # choose local port from this range
  ChatScript {
    Send "0"         # stderr unused
    Send "$1"        # here will local username
    Send "$1"        # remote username - the same as local
    Send "uptime"    # execute this command on a remote host
    Expect "^$"      # wait for 0 ( rsh protocol )
    Expect "averages: ([0-9]+\.[0-9]*)" # extract needed numbers 
      { $LoadAve }   # and store it to this variable
  }
}

Second, declare saving method, to check current load average on a host and report threshold exceeding. Thresholds will supply via method argument.

Save "check-loadave" {
  Pipe "mail2staff"     # generate e-mail message
  When "$LoadAve >= $1" # check load average against threshold
    180                 # if this is true during 3 minutes.
   "$Name too heave loaded: $LoadAve" # send this message to admins
}

Now, apply above-mentioned methods to a host:

Object "server-1" {
  Address "host.foo.bar"
  Method "get-loadave" "john" # username is john
  Save "check-loadave" "3.5"  # check loadave 
}

Additional variable will be created in object context - $get-loadave will keep conversation results or error message if method fail.
Variable $WHEN will created in object context when "check-loadave" method have trigger. It will keep resulting message string like this: ""server-1" too heave loaded: 8.3".
These additional variables may be useful for operator frontend using NetState service.

Of course, you have to configure rshd on a remote server to enable remote command execution for specified user on a monitoring server.


Simple network services checking

Declare simple script-based methods for a well-known network services:

RootDir "/var/netmon"
Polling 60
TimeFmt "%H:%M:%S"

Method "ftp" {
  TCP Port 21
  ChatScript { Send "" Expect "^220 " Send "QUIT\r\n" Expect "" }
}
Method "ssh" {
  TCP Port 22
  ChatScript { Send "" Expect "^SSH-" Send "QUIT\r\n" Expect "" }
}
Method "smtp" {
  TCP Port 25
  ChatScript { Send "" Expect "^220-" Send "QUIT\r\n" Expect "" }
}
Method "pop3" {
  TCP Port 110
  ChatScript { Send "" Expect "^\\+OK " Send "QUIT\r\n" Expect "" }
}
Method "http" {
  TCP Port 80
  ChatScript {
    Send   "GET $1 HTTP/1.0\r\n\r\n" # $1 - document name
    Expect "^HTTP/1.1 200 OK$"
  }
}

Declare universal saving method to report as if any service status changed:

# arguments: $1 - server name, $2 - service name
Save "state-alarm" {
  Pipe "mail -s \"$1/$2 $0\" root" # send e-mail
  State "$TIME $1/$2 $STATE $$2"   # message body
}

Apply above mentioned methods to a host:

Object "server-1" {
  Address "server.foo.bar"
  Method Ping    # is the server accessible
  Save "state-alarm" "server-1 ping" # arguments to substitute $1 and $2

  Service "pop3" {
    Method "pop3"
    Save "state-alarm" "server-1 pop3"
  }
  Service "http" {
    Method "http" "/index.html" # argument is a document name
    Save "state-alarm" "server-1 http"
  }
  Service "dns" {
    Method dns "foo.bar" # built-in DNS method will check specified zone
    Save "state-alarm" "server-1 dns"
  }
}

Parent object have to be polled by some method, otherwise its state will unknown - NONE.
Subobjects are checked only if parent object is in UP state.
To set unconditional UP state for object, use ICMP polling method with zero packets count.


Catching specific SNMP trap

Suppose, you need to catch Cisco Enterprise ciscoConfigManMIBNotification traps.

UCD snmptrapd utility dumps such a trap like this:

15:43:27.853: snmp_trap(192.168.1.1): enterprise .1.3.6.1.4.1.9.9.43.2
	Enterprise Specific Trap .1.3.6.1.4.1.9.9.43.2.0.1
	.1.3.6.1.4.1.9.9.43.1.1.6.1.3.1 = 1
	.1.3.6.1.4.1.9.9.43.1.1.6.1.4.1 = 4
	.1.3.6.1.4.1.9.9.43.1.1.6.1.5.1 = 2

Corresponded Netmond configuration fragment is:

Trap "config-notify" {
  Enterprise 1.3.6.1.4.1.9.9.43.2.0 # ciscoConfigManMIBNotificationPrefix
  Specific   1                      # ciscoConfigManEvent trap
  Community "$1"
}

Object "cisco-router" {
  Address "192.168.1.1"
  ...
  $commandSource     1.3.6.1.4.1.9.9.43.1.1.6.1.3.1
  $configSource      1.3.6.1.4.1.9.9.43.1.1.6.1.4.1
  $configDestination 1.3.6.1.4.1.9.9.43.1.1.6.1.5.1
  Trap "config-notify" "router-community"
  ...
}

As defined in a CISCO-CONFIG-MAN-MIB-V1SMI.my document, variables can have values:

$commandSource
the command was issued by: 1 = commandLine, 2 = snmp.
$configSource and $configDestination
data source and output destination: 1 = erase, 2 = commandSource, 3 = running, 4 = startup, 5 = local, 6 = networkTftp and 7 = networkRcp.

So, above-mentioned trap inform as, that show startup-config command was executed on a Cisco router with ip address 192.168.1.1.


Network interfaces statistic accumulation

The standard task for internet provider or large corporate site is to collect traffic statistic.
The industry-standard method is to ask SNMP counters periodically to protocol traffic flows, errors and so on.

Netmond can help to solve this task. You can use built-in Router polling method to collect data. Also, you can use traps catching mechanism to protocol async network events.

In this example we will store data to hierarchically ordered plain text files. Data will be collected by Router polling method. We will not use saving method Interface because it store all data in single file.

Configure to store interface counters and interface events log in separate files:

RootDir "/var/netmon"
Polling 60 # poll once per minute
Saving 600 # save data once per 10 minutes
TimeFmt "%H:%M:%S" # $TIME output format

# save interface counters
Save "IntData" {
  File "%Y.%m.%d" # data based filename like: 2002.08.24. New file for a day.
  Data "$TIME"    # following data will saved in one strung
       " $ifInOctets.delta $ifOutOctets.delta"
       " $ifInUcastPkts.delta $ifOutUcastPkts.delta"
       " $ifInDrops.delta $ifOutDrops.delta"
       " $ifInErrors.delta $ifOutErrors.delta"
}

# log interface events
Save "IntChange" {
  File "%Y.%m.changes" # monthly files, for example: 2002.08.changes
  State "$TIME $ifSpeed $STATE $ciscoIfReason" # status change
  When "$ifSpeed.old && $ifSpeed != $ifSpeed.old" 0
        "$TIME BW $ifSpeed.old -> $ifSpeed"    # interface speed change
}

Apply this methods to client interfaces on our routers and switches:

# border router with client ports
Object "router-1" {
  Address "cisco.foo.bar"   # or IP address
  Trap Generic "community"  # listen for traps
  Method Router "community" # query router counters
  Save Router               # save router events and data
  Interface "FastEthernet0/0.1" {
    DataDir "Customer1"     # non-standard data saving directory
    Save "IntData"
    Save "IntChange"
  }
  Interface "Serial1/0" {
    DataDir "Customer2"
    Save "IntData"
    Save "IntChange"
  }
}

# border switch with client ports
Object "switch-2" {
  Address "catalyst.foo.bar"
  Trap Generic "community"
  Method Router "community" # this method work for switch too
  Save Router
  Interface 12 {            # refer interface by index
    DataDir "Customer3"
    Save "IntData"
    Save "IntChange"
  }
}

As a result, data will saved in this hierarchy:

/var/netmon/
            router-1/Data files for router-1
                     ...
                     Customer1/data for FastEthernet0/0.1 port
                               ...
                     Customet2/data for Serial1/0 port
                               ...
            switch-2/data files for router switch-1
                     ...
                     Customer3/data for port 12
                               ...

If you need to save data to SQL database, for example, replace File keyword with Pipe or Exec in saving method declaration and replace filename with external program full name.


See also:
Netmond design
Configuration statements
Internal variables

© 1998-2002, Rinet Software