Build precise queries to find exactly what you need
Press ESC to close
@paneologist
Favorites0
Views
Projects0
I created following patch, to support also tcp and tls-transport methods. You can also download the script here: https://www.swabian.net/extern/nagios/check_sip --- check_sip 2016-10-29 05:39:08.000000000 +0200 +++ check_sip 2025-04-24 10:28:37.037230951 +0200 @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # # check_sip plugin for nagios -# $Revision: 1.3 $ +# $Revision: 1.3.1 $ # # Nagios plugin to check SIP servers # @@ -30,21 +30,24 @@ use utils qw($TIMEOUT %ERRORS &print_revision &support); use vars qw($PROGNAME); use IO::Socket::INET; +use IO::Socket::SSL; +use IO::Select; #use Sys::Hostname; use Time::HiRes qw(gettimeofday ualarm); use Net::Domain qw (hostname hostfqdn hostdomain); use Switch; +use Fcntl; $PROGNAME = "check_sip"; -my $VERSION = "1.3.0"; +my $VERSION = "1.3.1"; $ENV{'BASH_ENV'}=''; $ENV{'ENV'}=''; $ENV{'PATH'}=''; $ENV{'LC_ALL'}='C'; -my ($opt_V,$opt_h,$opt_u,$opt_p,$opt_H, $opt_w, $opt_s, $opt_f); -$opt_V = $opt_h = $opt_u = $opt_p = $opt_H = $opt_w = $opt_s = $opt_f = ''; +my ($opt_V,$opt_h,$opt_u,$opt_p,$opt_H, $opt_w, $opt_s, $opt_f, $opt_m); +$opt_V = $opt_h = $opt_u = $opt_p = $opt_H = $opt_w = $opt_s = $opt_f = $opt_m = ''; my $state = 'UNKNOWN'; @@ -58,7 +61,8 @@ "u=s" => $opt_u, "uri=s" => $opt_u, "p=s" => $opt_p, "port=s" => $opt_p, "H=s" => $opt_H, "host=s" => $opt_H, - "w=s" => $opt_w, "warn=s" => $opt_w + "w=s" => $opt_w, "warn=s" => $opt_w, + "m=s" => $opt_m, "method=s" => $opt_m ); # -h displays help @@ -73,8 +77,14 @@ # Check the sip URI is OK unless ($opt_u) { printHelp(); exit $ERRORS{'UNKNOWN'} } -# Port is 5060 unless otherwise specified -unless ($opt_p) { $opt_p = 5060 } +# Port is 5060/5061 unless otherwise specified +unless ($opt_p) { + if ($opt_m =~ /^tls1_.$/) { + $opt_p = 5061; + } else { + $opt_p = 5060; + } +} # Determine the host from the sip URI if it wasn't specified with -H unless ($opt_H) { $opt_H = hostFromURI($opt_u) } @@ -113,30 +123,32 @@ my $localhost = hostfqdn(); $opt_f = getFromURI($opt_f,$localhost,$opt_p); my $user=getUserPart($opt_f); -my $socket = uconnect($opt_H, $opt_p); +my $socket = uconnect($opt_H, $opt_p,$opt_m); my @localinfo = unpack_sockaddr_in($socket->sockname); my $req = buildReq($localinfo[0], $opt_u, $opt_f,$user,$localhost); ($startsec, $starttime) = gettimeofday; my $response; - +my $selector = IO::Select->new($socket); for($TIMEOUT=0,$resend_times=0,$max_resend=11;$resend_timessend($req); -$response=''; -$resend_times++; -# sip retransmission, totally 35.5 seconds. -switch($resend_times){ - case 1 { ualarm(500000); } - case 2 { $TIMEOUT=1; alarm($TIMEOUT); } - case 3 { $TIMEOUT=2; alarm($TIMEOUT); } - else { $TIMEOUT=4; alarm($TIMEOUT); } -} -#print $resend_times."->".$Total_timeout." $TIMEOUTn"; -$socket->recv($response, 1024) or $state = 'CRITICAL'; # TODO: CHECK and show '503 Service Unavailable' when receiving unreachable ICMP packet. -#get rid of the 100 Trying - provisional response ... -if ($response && getResponseCode($response) eq "100"){ - $socket->recv($response, 1024) or $state = 'CRITICAL'; -} -last if ($response); + $socket->write($req); #send + $response=''; + $resend_times++; + # sip retransmission, totally 35.5 seconds. + switch($resend_times){ + case 1 { ualarm(500000); } + case 2 { $TIMEOUT=1; alarm($TIMEOUT); } + case 3 { $TIMEOUT=2; alarm($TIMEOUT); } + else { $TIMEOUT=4; alarm($TIMEOUT); } + } + if ($selector->can_read(5)) { + #print $resend_times."-> $TIMEOUTn"; + $socket->read($response, 1024) or $state = 'CRITICAL'; # TODO: CHECK and show '503 Service Unavailable' when receiving unreachable ICMP packet. + #get rid of the 100 Trying - provisional response ... + if ($response && getResponseCode($response) eq "100"){ + $socket->read($response, 1024) or $state = 'CRITICAL'; + } + } + last if ($response); } ($finishsec, $finishtime) = gettimeofday; $secdiff=$finishsec-$startsec; @@ -155,9 +167,41 @@ sub uconnect { - my ($host, $port) = @_; - my $socket = new IO::Socket::INET->new(PeerPort=>$port, Proto=>'udp', PeerAddr=>$host); + my ($host, $port, $method) = @_; + my $socket; + if ("$method" eq "tcp") { + $socket = new IO::Socket::INET->new(PeerPort=>$port, Proto=>'tcp', PeerAddr=>$host); + } elsif ("$method" eq "tls1_1") { + $socket = new IO::Socket::SSL->new( + PeerAddr => $host, + PeerPort => $port, + Proto => 'tcp', + SSL_version => 'TLSv1_1', + SSL_verify_mode => SSL_VERIFY_PEER, # You can change this + ); + } elsif ("$method" eq "tls1_2") { + $socket = new IO::Socket::SSL->new( + PeerAddr => $host, + PeerPort => $port, + Proto => 'tcp', + SSL_version => 'TLSv1_2', + SSL_verify_mode => SSL_VERIFY_PEER, # You can change this + ); + } elsif ("$method" eq "tls1_3") { + $socket = new IO::Socket::SSL->new( + PeerAddr => $host, + PeerPort => $port, + Proto => 'tcp', + SSL_version => 'TLSv1_3', + SSL_verify_mode => SSL_VERIFY_PEER, # You can change this + ); + } elsif("$method" eq "udp" || "$method" eq "") { + $socket = new IO::Socket::INET->new(PeerPort=>$port, Proto=>'udp', PeerAddr=>$host); + } else { + print "unsupported method: $methodn"; exit $ERRORS{'UNKNOWN'} + } unless ($socket) { print "Unable to connect to $hostn"; exit $ERRORS{'UNKNOWN'} } + fcntl($socket, F_SETFL, O_NONBLOCK); return $socket; } @@ -229,7 +273,7 @@ sub printHelp { print "This plugin tests the sip service on the specified host.nn"; - print "Usage: $PROGNAME -u sip:[email protected] [-H host -p PORT -f sip:[email protected] -w WARNTIME -s]n"; + print "Usage: $PROGNAME -u sip:[email protected] [-H host -p PORT -f sip:[email protected] -w WARNTIME -s -m METHOD]n"; print " $PROGNAME [-h | --help]n"; print " $PROGNAME [-V | --version]nn"; print "Options:n"; @@ -245,6 +289,8 @@ print " Port to connect ton"; print " -f sip:[email protected]"; print " Full SIP uri, will be used for the "From:"-Headern"; + print " -m [tcp,udp,tls1_1,tls1_2,tls1_3]n"; + print " Method to use to connect, default udpn"; print " -sn"; print " Changes default behavior: all SIP-responses will result in an "OK"nn";
Reviewed 5 months ago
I do not know what the correct way is here to publish/suggest patches. I implemented pjsip for this plugin: --- check_asterisk_peers 2025-04-10 08:45:57.319369355 +0200 +++ check_asterisk_peers_pjsip 2025-04-10 09:11:59.703011415 +0200 @@ -3,6 +3,8 @@ # Check asterisk peers plugin for Nagios. # Written by Chad Phillips ([email protected]) # Last Modified: 2009-05-02 +# modified by Paul Neuwirth ([email protected]) to include pjsip +# 2025-04-10 ASTERISK=/usr/sbin/asterisk @@ -13,7 +15,7 @@ print_usage() { echo " -Usage: check_asterisk_peers [--type | -t ] [--peers | -p ] [--registrations | -r ] [--verify-peers] [--verify-registrations] [--config-file ] +Usage: check_asterisk_peers [--type | -t ] [--peers | -p ] [--registrations | -r ] [--verify-peers] [--verify-registrations] [--config-file ] Usage: check_asterisk_peers --help | -h Description: @@ -62,6 +64,7 @@ Default value is based on the --type setting: sip: /etc/asterisk/sip.conf + pjsip: /etc/asterisk/pjsip.conf iax: /etc/asterisk/iax.conf --help | -h Print this help and exit. @@ -227,12 +230,14 @@ done # Make sure we have a valid peer type. -if [ "$peer_type" != "" ] && [ "$peer_type" != "sip" ] && [ "$peer_type" != "iax" ]; then - echo "Peer type must be one of: sip, iax." +if [ "$peer_type" != "" ] && [ "$peer_type" != "sip" ] && [ "$peer_type" != "pjsip" ] && [ "$peer_type" != "iax" ]; then + echo "Peer type must be one of: sip, iax, pjsip." exit $STATE_UNKNOWN # Convert iax type into internal iax2 type for the Asterisk executable. elif [ "$peer_type" = "iax" ]; then peer_type=iax2 +elif [ "$peer_type" = "pjsip" ]; then + peer_type=pjsip # Default type is SIP. else peer_type=sip @@ -247,6 +252,8 @@ if [ "$conf_file" = "" ]; then if [ "$peer_type" = "iax2" ]; then conf_file=/etc/asterisk/iax.conf + elif [ "$peer_type" = "pjsip" ]; then + conf_file=/etc/asterisk/pjsip.conf else conf_file=/etc/asterisk/sip.conf fi @@ -258,10 +265,15 @@ if [ "$registrations" ]; then for r in $registrations do - REGISTRATION_FORMAT_CORRECT=`echo "$r" | grep ".+@.+"` - if [ ! "$REGISTRATION_FORMAT_CORRECT" ]; then - echo "Registration $r is not in the valid username@uri format." - exit $STATE_UNKNOWN + if [ "$peer_type" != "pjsip" ]; then + REGISTRATION_FORMAT_CORRECT=`echo "$r" | grep ".+@.+"` + if [ ! "$REGISTRATION_FORMAT_CORRECT" ]; then + echo "Registration $r is not in the valid username@uri format." + exit $STATE_UNKNOWN + fi + else + #no limitations for pjsip registrations, afaik + REGISTRATION_FORMAT_CORRECT=1 fi done fi @@ -277,31 +289,55 @@ for p in $peers do if [ "$verify_peers" ]; then - peer_verified=`echo "$all_config" | grep "^[${p}]$"` + peer_verified=`echo "$all_config" | grep "^[${p}].*$"` else peer_verified=1 fi if [ "$peer_verified" ]; then # Fetch the data from asterisk. - command_output=`$ASTERISK -rx "$peer_type show peer $p" 2>&1` - check_asterisk_result $? "$command_output" - status=`echo "$command_output" | grep "^[[:space:]]*Status[[:space:]]*:" | awk '{print $3;}'` - if [ "$status" = "OK" ]; then - if [ "$test_ok" ]; then - test_ok="${test_ok}, $p" + if [ "$peer_type" = "pjsip" ]; then + command_output=`$ASTERISK -rx "$peer_type show endpoint $p" 2>&1` + check_asterisk_result $? "$command_output" + status=`echo "$command_output" | grep "^sEndpoint:s*$p.*" | awk -F' +' '{print $3;}'` + if [ "$status" = "Not in use" ] || [ "$status" = "In use" ]; then + if [ "$test_ok" ]; then + test_ok="${test_ok}, $p" + else + test_ok="$p" + fi else - test_ok="$p" + if [ "$status" ]; then + status_error="$status" + else + status_error="Not found" + fi + if [ "$test_errors" ]; then + test_errors="${test_errors}, ${p}: $status_error" + else + test_errors="${p}: $status_error" + fi fi else - if [ "$status" ]; then - status_error="$status" - else - status_error="Not found" - fi - if [ "$test_errors" ]; then - test_errors="${test_errors}, ${p}: $status_error" + command_output=`$ASTERISK -rx "$peer_type show peer $p" 2>&1` + check_asterisk_result $? "$command_output" + status=`echo "$command_output" | grep "^[[:space:]]*Status[[:space:]]*:" | awk '{print $3;}'` + if [ "$status" = "OK" ]; then + if [ "$test_ok" ]; then + test_ok="${test_ok}, $p" + else + test_ok="$p" + fi else - test_errors="${p}: $status_error" + if [ "$status" ]; then + status_error="$status" + else + status_error="Not found" + fi + if [ "$test_errors" ]; then + test_errors="${test_errors}, ${p}: $status_error" + else + test_errors="${p}: $status_error" + fi fi fi else @@ -314,8 +350,8 @@ done fi -# Check registrations. -if [ "$registrations" ]; then +# Check registrations. not pjsip +if [ "$peer_type" != "pjsip" ] && [ "$registrations" ]; then # Fetch the data from asterisk. command_output=`$ASTERISK -rx "$peer_type show registry" 2>&1` check_asterisk_result $? "$command_output" @@ -364,6 +400,50 @@ done fi +# Check registrations. pjsip +if [ "$peer_type" = "pjsip" ] && [ "$registrations" ]; then + # Fetch the data from asterisk. + command_output=`$ASTERISK -rx "$peer_type show registrations" 2>&1` + check_asterisk_result $? "$command_output" + for r in $registrations + do + if [ "$verify_registrations" ]; then + # best what can be done without getting too deep into config file (type=registration might be part of a template...) + registration_verified=`echo "$all_config" | grep "^[${r}].*$"` + else + registration_verified=1 + fi + if [ "$registration_verified" ]; then + # This regex isn't perfect, but it does the trick ok. + status=`echo "$command_output" | grep "^s$r/.*" | awk -F' +' '{ print $3;}'` + if [ "$status" = "Registered" ]; then + if [ "$test_ok" ]; then + test_ok="${test_ok}, $r" + else + test_ok="$r" + fi + else + if [ "$status" ]; then + status_error="$status" + else + status_error="Not found" + fi + if [ "$test_errors" ]; then + test_errors="${test_errors}, ${r}: $status_error" + else + test_errors="${r}: $status_error" + fi + fi + else + if [ "$test_ok" ]; then + test_ok="${test_ok}, $r (not active)" + else + test_ok="$r (not active)" + fi + fi + done +fi + if [ "$test_errors" ]; then output="$output ERROR: $test_errors" set_exit_status $STATE_CRITICAL @@ -379,4 +459,4 @@ fi echo "$output" -exit $exitstatus No newline at end of file +exit $exitstatus
Reviewed 6 months ago
just a two characters fix to make this work with nfsv4 mounts: --- check_nfsmounts.old 2025-04-24 12:38:37.030645151 +0200 +++ check_nfsmounts 2025-04-24 12:32:30.676912073 +0200 @@ -79,7 +79,7 @@ my @dirs=(); my %mountmodes=(); while(my $line=) { - if($line =~ /^[^ ]+ [^ ]+ nfs /) { + if($line =~ /^[^ ]+ [^ ]+ nfs.? /) { my @fields=split(/s+/,$line); my $mountpoint=$fields[1]; push(@dirs,$mountpoint); and it works for me on nrpe, but it needed root priviliges, so added sudo to the command in nrpe.conf and edited /etc/sudoers