Sérsniðin snmpd framlenging til hafnarprófa

As weird as it sounds, recently I had a task to accomplish port checks without access to the LAN on which daemons listen for connections. Speaking of a monitoring solution, the obvious choice was SNMP, which is the most widespread means of getting health information from network-attached devices, anyway. We perform an “indirect” port check, meaning that it’s sufficient for us to know that a process is listening on a given port without trying to communicate with it.

Ég fann þrjá aðra aðferðir til að ná slíku hafnarprófi í gegnum SNMP. Þeir hafa eitt sameiginlegt: þeir nýta Net SNMP miðlara og / eða viðskiptavinarbinaries.

  • Snmpnetsat gagnsemi.A straightforward answer to our question. Provides a netstat-like listing of active connections on the remote host. But it’s got its flaw. It queries the older MIB-II (RFC1213) objects tcpConnectionTable and udpTable, which don’t support IPv6. As a result, server processes listening on all IPs on an IPv6-enabled system doesn’t show up in the list.
  • tcpListenerTable og udpEndpointTable hlutir.These two were defined as part of TCP-MIB (RFC4022) and UDP-MIB (RFC4113) respectively. As their names suggest, these structures hold all listener processes on the system. Apparently indexes cannot be queried directly, so one needs to walk through the whole table to find a specific port. At least this is the case in Net-SNMP v5.5, but I didn’t investigate any further.
  • Sérsniðin snmpd eftirnafn.Of course we don’t want to develop a new MIB module for the sake of this single task. Several other ways exist to extend snmpd functionality – they are all described in snmpd.conf man page. The basic idea is to collect the listener data with a script and let snmpd transfer it to the client in a simple form.
Mælt með:  Hvernig á að setja upp Proftpd með TLS á Ubuntu 15.04

So we have two viable options here. One is to let the client (monitoring system) extract the information it needs from tcpListenerTable and udpEndpointTable. The other is to leave decision making to the server (monitored host) and let it serve the other party with a simple OK/NOT-OK value. Needless to say, former was the winner in this competition because of the smaller impact on host configurations.

But, surprise-surprise, I created a working POC solution for the other one, too. In memoriam…

Áframhaldandi snmpd

As I already mentioned, my idea of an extension was to run an external script from the daemon and provide the client with a single value it needed. An SNMP-aware solution (denoted as a MIB-Specific Extension Command by the documentation) is what fits. In this scenario the daemon acts lazy and delegates all work to the external command: it transfers object ID and request type (GET, GETNEXT, SET) and expects an object value or a report on the outcome.

Allt sem við þurfum að gera er að úthluta ónotaðri hluta MIB-trésins við handritið með fara directive and grant view rights to the client (“systemview” is “public” by default).

 pass . /path/to/script.sh
 view systemview included .

So it’s now fully up to us, what happens when an object in this subtree is requested. Our script serves objects which have numeric OIDs of the form “ROOT.PORT”, where ROOT is the subtree’s relative root and PORT can be any valid port number. The object value returned corresponds to the number of processes bound to that port. E.g. suppose ROOT is ., if a GET request is received on ., then the response will hold the number of processes listening on port 22. Obviously the value is 0, if there’s no such process. When responding to GETNEXT requests, only those ports are taken into consideration which are bound to a process.

 # Find ports bound to a single IP address. (Empty means ALL.)
 # OID of the subtree root object assigned to this extension (with leading dot).
 # Paths to binaries
 OID=$  2
 # Check wether OID is valid (it's a direct descendant of ROOT or ROOT itself)
 echo $  OID | $  GREP -E ^$  ROOT.?[0-9]*$   > /dev/null || exit
 # Extracting the last portion of the OID
 [ "$  OID" != "$  ROOT" ] && port=`echo $  OID | $  GREP -o "[0-9]*$  "` || port=0
 [ "$  IP" != "" ] && IP="@$  IP"
 case $  1 in
 		# Checking if port is in valid range
 		[ "$  port" -gt "65535" ] && exit
 		[ "$  port" = "0" ] && echo -e "$  OIDnstringn$  0" && exit
 		(( port = $  port + 1 ))
 		# Checking if port is in valid range
 		[ "$  port" -gt "65535" ] && exit
 		# Searching next listener port on the system
 		port=`($  LSOF -i$  IP:$  port-65535 -sTCP:LISTEN -Fnp -P; $  LSOF -iUDP$  IP:$  port-65535 -Fnp -P) | $  GREP "^n" | $  GREP -o "[0-9]*$  " | $  SORT -n | $  HEAD -1`
 		[ "$  port" == "" ] && exit
 		OID="$  ROOT.$  port"
 		# Refusing SET requests
 		echo not-writable; exit
 # Output for snmpd (number of processes)
 echo -e "$  OIDninteger"
 ($  LSOF -iTCP$  IP:$  port -sTCP:LISTEN -Fp; $  LSOF -iUDP$  IP:$  port -Fp) | $  SORT -u | $  WC -l

Just an example on how this can be used from the client side. Let’s add a command to Nagios configuration.

 define command{
         command_name    check_snmp_port
         command_line    $  USER1$  /check_snmp -H $  HOSTADDRESS$   -C public -c 1: -o .$  ARG1$  

Þar sem $ USER1 $ er notendahópur sem geymir slóðina að Nagios tappi möppunni, þar sem check_snmp er staðsettur. Augljóslega er fyrsta rökin ($ ARG1 $) höfnarnúmerið svo að check_command tilskipunin í þjónustu skilgreiningu ætti að vera eitthvað svona: check_snmp_port! 22.

Mælt með:  Uppsetning Apache2 með PHP5 og MySQL stuðningi við Ubuntu 13.10 (LAMP)



Skildu eftir skilaboð

GTranslate Your license is inactive or expired, please subscribe again!