sensu-plugins-network-checks 0.0.1.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-ports
4
+ #
5
+ # DESCRIPTION:
6
+ # Fetch port status using nmap. This check is good for catching bad network ACLs
7
+ # or service down events for network resources.
8
+ #
9
+ # OUTPUT:
10
+ # plain text
11
+ #
12
+ # PLATFORMS:
13
+ # Linux, Windows, BSD, Solaris, etc
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ # gem: open3
18
+ # gem: json
19
+ # nmap
20
+ #
21
+ # USAGE:
22
+ # $ ./check-ports.rb --host some_server --ports 5671,5672 --level crit
23
+ #
24
+ # NOTES:
25
+ # #YELLOW
26
+ # Look at rewriting this using the namp library to not depend on external tools
27
+ #
28
+ # LICENSE:
29
+ # Copyright 2013 GoDaddy.com, LLC <jjmanzer@godaddy.com>
30
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
31
+ # for details.
32
+ #
33
+
34
+ require 'open3'
35
+ require 'sensu-plugin/check/cli'
36
+ require 'json'
37
+
38
+ # CheckPorts
39
+ class CheckPorts < Sensu::Plugin::Check::CLI
40
+ option :host,
41
+ description: 'Resolving name or IP address of target host',
42
+ short: '-h HOST',
43
+ long: '--host HOST',
44
+ default: 'localhost'
45
+
46
+ option :ports,
47
+ description: 'TCP port(s) you wish to get status for',
48
+ short: '-t PORT,PORT...',
49
+ long: '--ports PORT,PORT...'
50
+
51
+ option :level,
52
+ description: 'Alert level crit(critical) or warn(warning)',
53
+ short: '-l crit|warn',
54
+ long: '--level crit|warn',
55
+ default: 'WARN'
56
+
57
+ def run # rubocop:disable all
58
+ stdout, stderr = Open3.capture3(
59
+ ENV,
60
+ "nmap -P0 -p #{ config[:ports] } #{ config[:host] }"
61
+ )
62
+
63
+ case stderr
64
+ when /Failed to resolve/
65
+ critical 'cannot resolve the target hostname'
66
+ end
67
+
68
+ port_checks = {}
69
+ check_pass = true
70
+
71
+ stdout.split("\n").each do |line|
72
+ line.scan(/(\d+).tcp\s+(\w+)\s+(\w+)/).each do |status|
73
+ port_checks[status[1]] ||= []
74
+ port_checks[status[1]].push status[0]
75
+ check_pass = false unless status[1]['open']
76
+ end
77
+ end
78
+
79
+ result = port_checks.map { |state, ports| "#{ state }:#{ ports.join(',') }" }.join(' ')
80
+
81
+ if check_pass
82
+ ok result
83
+ elsif config[:level].upcase == 'WARN'
84
+ warning result
85
+ elsif config[:level].upcase == 'CRIT'
86
+ critical result
87
+ else
88
+ unknown "Unknown alert level #{config[:level]}"
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,102 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-rbl
4
+ #
5
+ # DESCRIPTION:
6
+ # Checks if a ip is blacklisted in the common dns blacklists. You can
7
+ # add a list
8
+ #
9
+ # OUTPUT:
10
+ # plain text
11
+ #
12
+ # PLATFORMS:
13
+ # Linux
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ # gem: dnsbl-client
18
+ #
19
+ # USAGE:
20
+ #
21
+ # NOTES:
22
+ # A list of DNS blacklists to not be checked can be passed with -I as a
23
+ # comma-separated list.
24
+ #
25
+ # LICENSE:
26
+ # Copyright 2012 Sarguru Nathan <sarguru90@gmail.com>
27
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
28
+ # for details.
29
+ #
30
+
31
+ require 'sensu-plugin/check/cli'
32
+ require 'dnsbl-client'
33
+ require 'set'
34
+
35
+ #
36
+ # Rbl Check
37
+ #
38
+ class RblCheck < Sensu::Plugin::Check::CLI
39
+ option :ip,
40
+ short: '-i IPADDRESS',
41
+ long: '--ip IPADDRESS',
42
+ description: 'IP of the server to check'
43
+
44
+ option :ignored_bls,
45
+ short: '-I BLACKLISTNAME',
46
+ long: '--ignored_bls BLACKLISTNAME',
47
+ description: 'Comma Separated String of ignored blacklists from default list',
48
+ default: 'null'
49
+
50
+ option :critical_bls,
51
+ short: '-C BLACKLISTNAME',
52
+ long: '--critical_bls BLACKLISTNAME',
53
+ description: 'Comma Separated String of critical blacklists from default list',
54
+ default: 'null'
55
+
56
+ def run # rubocop:disable all
57
+ c = DNSBL::Client.new
58
+
59
+ if config[:ip]
60
+ ip_add = config[:ip]
61
+ else
62
+ critical 'plugin failed. Required Argument -i (ip address of the client)'
63
+ end
64
+
65
+ if config[:ignored_bls]
66
+ ignored_bls = config[:ignored_bls]
67
+ ignored_bls_set = ignored_bls.split(',').to_set
68
+ end
69
+
70
+ if config[:critical_bls]
71
+ critical_bls = config[:critical_bls]
72
+ critical_bls_set = critical_bls.split(',').to_set
73
+ end
74
+
75
+ dnsbl_ret = c.lookup("#{ip_add}")
76
+ msg_string = ''
77
+ criticality = 0
78
+
79
+ # #YELLOW
80
+ dnsbl_ret.each do |dnsbl_result| # rubocop:disable Style/Next
81
+ if dnsbl_result.meaning =~ /spam/i || dnsbl_result.meaning =~ /blacklist/i
82
+ unless ignored_bls_set.member?(dnsbl_result.dnsbl)
83
+ msg_string = "#{msg_string} #{dnsbl_result.dnsbl}"
84
+ end
85
+
86
+ criticality += 1 if critical_bls_set.member?(dnsbl_result.dnsbl)
87
+ end
88
+ end
89
+
90
+ # YELLOW
91
+ unless msg_string.empty? # rubocop:disable UnlessElse
92
+ if criticality > 0
93
+ critical "#{ip_add} Blacklisted in#{msg_string}"
94
+ else
95
+ warning "#{ip_add} Blacklisted in#{msg_string}"
96
+ end
97
+ else
98
+ msg_txt = "All is well. #{ip_add} has good reputation."
99
+ ok "#{msg_txt}"
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,83 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ #
4
+ # interface-metrics
5
+ #
6
+ # DESCRIPTION:
7
+ #
8
+ # OUTPUT:
9
+ # metric data
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ # gem: socket
17
+ #
18
+ # USAGE:
19
+ #
20
+ # NOTES:
21
+ #
22
+ # LICENSE:
23
+ # Copyright 2012 Sonian, Inc <chefs@sonian.net>
24
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
25
+ # for details.
26
+ #
27
+
28
+ require 'sensu-plugin/metric/cli'
29
+ require 'socket'
30
+
31
+ #
32
+ # Interface Graphite
33
+ #
34
+ class InterfaceGraphite < Sensu::Plugin::Metric::CLI::Graphite
35
+ option :scheme,
36
+ description: 'Metric naming scheme, text to prepend to metric',
37
+ short: '-s SCHEME',
38
+ long: '--scheme SCHEME',
39
+ default: "#{Socket.gethostname}.interface"
40
+
41
+ option :excludeinterface,
42
+ description: 'List of interfaces to exclude',
43
+ short: '-x INTERFACE[,INTERFACE]',
44
+ long: '--exclude-interface',
45
+ proc: proc { |a| a.split(',') }
46
+
47
+ def run # rubocop:disable all
48
+ # Metrics borrowed from hoardd: https://github.com/coredump/hoardd
49
+
50
+ metrics = %w(rxBytes
51
+ rxPackets
52
+ rxErrors
53
+ rxDrops
54
+ rxFifo
55
+ rxFrame
56
+ rxCompressed
57
+ rxMulticast
58
+ txBytes
59
+ txPackets
60
+ txErrors
61
+ txDrops
62
+ txFifo
63
+ txColls
64
+ txCarrier
65
+ txCompressed)
66
+
67
+ File.open('/proc/net/dev', 'r').each_line do |line|
68
+ interface, stats_string = line.scan(/^\s*([^:]+):\s*(.*)$/).first
69
+ next if config[:excludeinterface] && config[:excludeinterface].find { |x| line.match(x) }
70
+ next unless interface
71
+ if interface.is_a?(String)
72
+ interface = interface.gsub('.', '_')
73
+ end
74
+
75
+ stats = stats_string.split(/\s+/)
76
+ next if stats == ['0'].cycle.take(stats.size)
77
+
78
+ metrics.size.times { |i| output "#{config[:scheme]}.#{interface}.#{metrics[i]}", stats[i] }
79
+ end
80
+
81
+ ok
82
+ end
83
+ end
@@ -0,0 +1,92 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # metrics-net
4
+ #
5
+ # DESCRIPTION:
6
+ # Simple plugin that fetchs metrics from all interfaces
7
+ # on the box using the /sys/class interface.
8
+ #
9
+ # Use the data with graphite's `nonNegativeDerivative()` function
10
+ # to construct per-second graphs for your hosts.
11
+ #
12
+ # Loopback iface (`lo`) is ignored.
13
+ #
14
+ # Compat
15
+ # ------
16
+ #
17
+ # This plugin uses the `/sys/class/net/<iface>/statistics/{rx,tx}_*`
18
+ # files to fetch stats. On older linux boxes without /sys, this same
19
+ # info can be fetched from /proc/net/dev but additional parsing
20
+ # will be required.
21
+ #
22
+ # OUTPUT:
23
+ # metric data
24
+ #
25
+ # PLATFORMS:
26
+ # Linux
27
+ #
28
+ # DEPENDENCIES:
29
+ # gem: sensu-plugin
30
+ # gem: <?>
31
+ #
32
+ # USAGE:
33
+ # $ ./metrics-packets.rb --scheme servers.web01
34
+ # servers.web01.eth0.tx_packets 982965 1351112745
35
+ # servers.web01.eth0.rx_packets 1180186 1351112745
36
+ # servers.web01.eth1.tx_packets 273936669 1351112745
37
+ # servers.web01.eth1.rx_packets 563787422 1351112745
38
+ #
39
+ # NOTES:
40
+ # Does it behave differently on specific platforms, specific use cases, etc
41
+ #
42
+ # LICENSE:
43
+ # Copyright 2012 Joe Miller <https://github.com/joemiller>
44
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
45
+ # for details.
46
+ #
47
+
48
+ require 'sensu-plugin/metric/cli'
49
+ require 'socket'
50
+
51
+ #
52
+ # Linux Packet Metrics
53
+ #
54
+ class LinuxPacketMetrics < Sensu::Plugin::Metric::CLI::Graphite
55
+ option :scheme,
56
+ description: 'Metric naming scheme, text to prepend to metric',
57
+ short: '-s SCHEME',
58
+ long: '--scheme SCHEME',
59
+ default: "#{Socket.gethostname}.net"
60
+
61
+ def run # rubocop:disable all
62
+ timestamp = Time.now.to_i
63
+
64
+ Dir.glob('/sys/class/net/*').each do |iface_path|
65
+ next if File.file?(iface_path)
66
+ iface = File.basename(iface_path)
67
+ next if iface == 'lo'
68
+
69
+ tx_pkts = File.open(iface_path + '/statistics/tx_packets').read.strip
70
+ rx_pkts = File.open(iface_path + '/statistics/rx_packets').read.strip
71
+ tx_bytes = File.open(iface_path + '/statistics/tx_bytes').read.strip
72
+ rx_bytes = File.open(iface_path + '/statistics/rx_bytes').read.strip
73
+ tx_errors = File.open(iface_path + '/statistics/tx_errors').read.strip
74
+ rx_errors = File.open(iface_path + '/statistics/rx_errors').read.strip
75
+
76
+ begin
77
+ if_speed = File.open(iface_path + '/speed').read.strip
78
+ rescue
79
+ if_speed = 0
80
+ end
81
+
82
+ output "#{config[:scheme]}.#{iface}.tx_packets", tx_pkts, timestamp
83
+ output "#{config[:scheme]}.#{iface}.rx_packets", rx_pkts, timestamp
84
+ output "#{config[:scheme]}.#{iface}.tx_bytes", tx_bytes, timestamp
85
+ output "#{config[:scheme]}.#{iface}.rx_bytes", rx_bytes, timestamp
86
+ output "#{config[:scheme]}.#{iface}.tx_errors", tx_errors, timestamp
87
+ output "#{config[:scheme]}.#{iface}.rx_errors", rx_errors, timestamp
88
+ output "#{config[:scheme]}.#{iface}.if_speed", if_speed, timestamp
89
+ end
90
+ ok
91
+ end
92
+ end
@@ -0,0 +1,55 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # netif-metrics
4
+ #
5
+ # DESCRIPTION:
6
+ # Network interface throughput
7
+ #
8
+ # OUTPUT:
9
+ # metric data
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ # gem: socket
17
+ #
18
+ # USAGE:
19
+ # #YELLOW
20
+ #
21
+ # NOTES:
22
+ #
23
+ # LICENSE:
24
+ # Copyright 2014 Sonian, Inc. and contributors. <support@sensuapp.org>
25
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
26
+ # for details.
27
+ #
28
+
29
+ require 'sensu-plugin/metric/cli'
30
+ require 'socket'
31
+
32
+ #
33
+ # Netif Metrics
34
+ #
35
+ class NetIFMetrics < Sensu::Plugin::Metric::CLI::Graphite
36
+ option :scheme,
37
+ description: 'Metric naming scheme, text to prepend to .$parent.$child',
38
+ long: '--scheme SCHEME',
39
+ default: "#{Socket.gethostname}"
40
+
41
+ def run # rubocop:disable all
42
+ # #YELLOW
43
+ `sar -n DEV 1 1 | grep Average | grep -v IFACE`.each_line do |line| # rubocop:disable Style/Next
44
+ stats = line.split(/\s+/)
45
+ unless stats.empty?
46
+ stats.shift
47
+ nic = stats.shift
48
+ output "#{config[:scheme]}.#{nic}.rx_kB_per_sec", stats[2].to_f if stats[3]
49
+ output "#{config[:scheme]}.#{nic}.tx_kB_per_sec", stats[3].to_f if stats[3]
50
+ end
51
+ end
52
+
53
+ ok
54
+ end
55
+ end
@@ -0,0 +1,110 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # metrics-netstat-tcp
4
+ #
5
+ # DESCRIPTION:
6
+ # Fetch metrics on TCP socket states from netstat. This is particularly useful
7
+ # on high-traffic web or proxy servers with large numbers of short-lived TCP
8
+ # connections coming and going.
9
+ #
10
+ # OUTPUT:
11
+ # metric data
12
+ #
13
+ # PLATFORMS:
14
+ # Linux
15
+ #
16
+ # DEPENDENCIES:
17
+ # gem: sensu-plugin
18
+ # gem: <?>
19
+ #
20
+ # USAGE:
21
+ # $ ./metrics-netstat-tcp.rb --scheme servers.hostname
22
+ # servers.hostname.UNKNOWN 0 1350496466
23
+ # servers.hostname.ESTABLISHED 235 1350496466
24
+ # servers.hostname.SYN_SENT 0 1350496466
25
+ # servers.hostname.SYN_RECV 1 1350496466
26
+ # servers.hostname.FIN_WAIT1 0 1350496466
27
+ # servers.hostname.FIN_WAIT2 53 1350496466
28
+ # servers.hostname.TIME_WAIT 10640 1350496466
29
+ # servers.hostname.CLOSE 0 1350496466
30
+ # servers.hostname.CLOSE_WAIT 7 1350496466
31
+ # servers.hostname.LAST_ACK 1 1350496466
32
+ # servers.hostname.LISTEN 16 1350496466
33
+ # servers.hostname.CLOSING 0 1350496466
34
+ #
35
+ # NOTES:
36
+ # - Code for parsing Linux /proc/net/tcp from Anthony Goddard's ruby-netstat:
37
+ # https://github.com/agoddard/ruby-netstat
38
+ #
39
+ # LICENSE:
40
+ # Copyright 2012 Joe Miller <https://github.com/joemiller>
41
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
42
+ # for details.
43
+ #
44
+
45
+ require 'sensu-plugin/metric/cli'
46
+ require 'socket'
47
+
48
+ TCP_STATES = {
49
+ '00' => 'UNKNOWN', # Bad state ... Impossible to achieve ...
50
+ 'FF' => 'UNKNOWN', # Bad state ... Impossible to achieve ...
51
+ '01' => 'ESTABLISHED',
52
+ '02' => 'SYN_SENT',
53
+ '03' => 'SYN_RECV',
54
+ '04' => 'FIN_WAIT1',
55
+ '05' => 'FIN_WAIT2',
56
+ '06' => 'TIME_WAIT',
57
+ '07' => 'CLOSE',
58
+ '08' => 'CLOSE_WAIT',
59
+ '09' => 'LAST_ACK',
60
+ '0A' => 'LISTEN',
61
+ '0B' => 'CLOSING'
62
+ }
63
+
64
+ #
65
+ # Netstat TCP Metrics
66
+ #
67
+ class NetstatTCPMetrics < Sensu::Plugin::Metric::CLI::Graphite
68
+ option :scheme,
69
+ description: 'Metric naming scheme, text to prepend to metric',
70
+ short: '-s SCHEME',
71
+ long: '--scheme SCHEME',
72
+ default: "#{Socket.gethostname}.tcp"
73
+
74
+ option :port,
75
+ description: 'Port you wish to get metrics for',
76
+ short: '-p PORT',
77
+ long: '--port PORT',
78
+ proc: proc(&:to_i)
79
+
80
+ def netstat(protocol = 'tcp') # rubocop:disable all
81
+ state_counts = Hash.new(0)
82
+ TCP_STATES.each_pair { |_hex, name| state_counts[name] = 0 }
83
+
84
+ # #YELLOW
85
+ File.open('/proc/net/' + protocol).each do |line| # rubocop:disable Style/Next
86
+ line.strip!
87
+ if m = line.match(/^\s*\d+:\s+(.{8}):(.{4})\s+(.{8}):(.{4})\s+(.{2})/) # rubocop:disable AssignmentInCondition
88
+ connection_state = m[5]
89
+ connection_port = m[2].to_i(16)
90
+ connection_state = TCP_STATES[connection_state]
91
+ if config[:port] && config[:port] == connection_port
92
+ state_counts[connection_state] += 1
93
+ elsif !config[:port]
94
+ state_counts[connection_state] += 1
95
+ end
96
+ end
97
+ end
98
+ state_counts
99
+ end
100
+
101
+ def run
102
+ timestamp = Time.now.to_i
103
+ netstat('tcp').each do |state, count|
104
+ graphite_name = config[:port] ? "#{config[:scheme]}.#{config[:port]}.#{state}" :
105
+ "#{config[:scheme]}.#{state}"
106
+ output "#{graphite_name}", count, timestamp
107
+ end
108
+ ok
109
+ end
110
+ end