fix check_openwrt_bssid

This commit is contained in:
Cyberes 2024-03-19 20:03:37 -06:00
parent 7ec527199e
commit 31043bd979
1 changed files with 97 additions and 62 deletions

View File

@ -3,6 +3,7 @@ import argparse
import json import json
import re import re
import sys import sys
import time
import traceback import traceback
import paramiko import paramiko
@ -11,19 +12,27 @@ from checker import nagios
from checker.result import quit_check from checker.result import quit_check
from checker.types import try_int, try_float from checker.types import try_int, try_float
WIFI_2 = list(range(1, 12))
WIFI_5 = list(range(32, 178))
def main(args): def main(args):
command = 'iwinfo scan0 scan' command = f'iwinfo {args.interface} scan'
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for _ in range(args.retries + 1):
try: try:
ssh.connect(args.host, username='root') ssh.connect(args.host, username='root')
except paramiko.ssh_exception.AuthenticationException: except paramiko.ssh_exception.AuthenticationException:
print(f'SSH authentication to {args.host} failed! Make sure your key exists on the remote system or copy it over with ssh-copy-id') quit_check(f'SSH authentication to root@{args.host} failed! Make sure your key exists on the remote system or copy it over with ssh-copy-id', nagios.STATE_UNKNOWN)
sys.exit(1) sys.exit(nagios.STATE_UNKNOWN)
except paramiko.ssh_exception.NoValidConnectionsError:
quit_check(f'SSH connection failed to {args.host}', nagios.STATE_UNKNOWN)
stdin, stdout, stderr = ssh.exec_command(command) stdin, stdout, stderr = ssh.exec_command(command)
if stdout.channel.recv_exit_status() != 0:
quit_check(f'command failed:\nSTDOUT: {"".join(stdout.readlines())}\nSTDERR: {"".join(stderr.readlines())}', nagios.STATE_UNKNOWN)
output = [str(x).strip('\n').strip(' ') for x in stdout.readlines()] output = [str(x).strip('\n').strip(' ') for x in stdout.readlines()]
cells = {} cells = {}
@ -40,9 +49,24 @@ def main(args):
cells[list(cells.keys())[-1]]['ssid'] = ssid cells[list(cells.keys())[-1]]['ssid'] = ssid
elif line.startswith('Mode: '): elif line.startswith('Mode: '):
m = re.search(r'Mode: .*?\s\sFrequency: ([0-9.]*) GHz\s\sBand: ([0-9.]*) GHz\s\sChannel: ([0-9]*)$', line) m = re.search(r'Mode: .*?\s\sFrequency: ([0-9.]*) GHz\s\sBand: ([0-9.]*) GHz\s\sChannel: ([0-9]*)$', line)
cells[list(cells.keys())[-1]]['freq'] = try_float(m.group(1)) if not m:
cells[list(cells.keys())[-1]]['band'] = try_float(m.group(2)) # Older OpenWRT versions display this info differently.
cells[list(cells.keys())[-1]]['chan'] = try_int(m.group(3)) m = re.search(r'Mode: .*?\s\sChannel: ([0-9]*)$', line)
chan = try_int(m.group(1))
if chan in WIFI_2:
band = 2.4
elif chan in WIFI_5:
band = 5
else:
raise Exception
freq = -1
else:
freq = try_float(m.group(1))
band = try_float(m.group(2))
chan = try_int(m.group(3))
cells[list(cells.keys())[-1]]['freq'] = freq
cells[list(cells.keys())[-1]]['band'] = band
cells[list(cells.keys())[-1]]['chan'] = chan
elif line.startswith('Encryption: '): elif line.startswith('Encryption: '):
enc = re.search(r'Encryption: (.*?)$', line).group(1) enc = re.search(r'Encryption: (.*?)$', line).group(1)
cells[list(cells.keys())[-1]]['enc'] = enc cells[list(cells.keys())[-1]]['enc'] = enc
@ -59,17 +83,24 @@ def main(args):
sys.exit(nagios.STATE_UNKNOWN) sys.exit(nagios.STATE_UNKNOWN)
if args.target_mac not in list(cells.keys()): if args.target_mac not in list(cells.keys()):
quit_check(f'AP address not found: {args.target_mac}', nagios.STATE_CRIT) time.sleep(10)
continue
ap_data = cells[args.target_mac] ap_data = cells[args.target_mac]
computed_quality = int(try_float(ap_data['quality'][0]) / try_float(ap_data['quality'][1]) * 100) computed_quality = int(try_float(ap_data['quality'][0]) / try_float(ap_data['quality'][1]) * 100)
chan_width = ap_data['chan_width'].strip(' MHz')
if re.search(r'[a-zA-Z]', chan_width):
# OpenWRT may be unsure about the channel width.
chan_width = -1
perfdata = { perfdata = {
'signal': {'value': try_int(ap_data['signal']), 'warn': args.signal_warn, 'crit': args.signal_crit}, 'signal': {'value': try_int(ap_data['signal']), 'warn': args.signal_warn, 'crit': args.signal_crit},
'quality': {'value': int(computed_quality), 'warn': args.quality_warn, 'crit': args.quality_crit, 'unit': '%'}, 'quality': {'value': int(computed_quality), 'warn': args.quality_warn, 'crit': args.quality_crit, 'unit': '%'},
'freq': {'value': ap_data['freq']}, 'freq': {'value': ap_data['freq']},
'band': {'value': ap_data['band']}, 'band': {'value': ap_data['band']},
'chan': {'value': ap_data['chan']}, 'chan': {'value': ap_data['chan']},
'chan_width': {'value': ap_data['chan_width']}, 'chan_width': {'value': chan_width},
} }
if ap_data['ssid'] != args.expected_ssid: if ap_data['ssid'] != args.expected_ssid:
@ -91,10 +122,14 @@ def main(args):
nagios.STATE_OK, nagios.STATE_OK,
perfdata=perfdata) perfdata=perfdata)
quit_check(f'AP address not found: {args.target_mac}', nagios.STATE_CRIT)
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--host', required=True, help='The host to SSH into.') parser.add_argument('--host', required=True, help='The host to SSH into.')
parser.add_argument('--interface', required=True, help='The wireless interface to use (example: `wlan0`).')
parser.add_argument('--retries', default=3, help='If the target AP is not found, do this many retries.')
parser.add_argument('--print', action='store_true', help='Print the found APs.') parser.add_argument('--print', action='store_true', help='Print the found APs.')
parser.add_argument('--target-mac', required=True, help='The MAC address of the target AP.') parser.add_argument('--target-mac', required=True, help='The MAC address of the target AP.')
parser.add_argument('--expected-ssid', required=True, help="The AP's expected SSID.") parser.add_argument('--expected-ssid', required=True, help="The AP's expected SSID.")