finish check_openwrt_bssid.py

This commit is contained in:
Cyberes 2024-03-19 12:19:17 -06:00
parent 691e471cd8
commit 7ec527199e
2 changed files with 100 additions and 15 deletions

View File

@ -1,28 +1,112 @@
#!/usr/bin/env python3
import argparse
import json
import re
import sys
import traceback
import paramiko import paramiko
from checker import nagios
from checker.result import quit_check
from checker.types import try_int, try_float
def check_bssid():
hostname = 'hostname'
username = 'username'
password = 'password'
specific_bssid = 'specific_bssid'
command = 'iw wlan0 scan | grep BSS'
def main(args):
command = 'iwinfo scan0 scan'
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)
try:
ssh.connect(args.host, username='root')
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')
sys.exit(1)
stdin, stdout, stderr = ssh.exec_command(command) stdin, stdout, stderr = ssh.exec_command(command)
output = stdout.readlines() output = [str(x).strip('\n').strip(' ') for x in stdout.readlines()]
cells = {}
for line in output: for line in output:
if specific_bssid in line: if line.startswith('Cell '):
print(f'BSSID {specific_bssid} is present.') address = re.search(r'Address:\s(.*?)$', line).group(1)
return True cells[address] = {}
elif line.startswith('ESSID: '):
if line == 'ESSID: unknown':
ssid = None
else:
ssid = re.search(r'ESSID:\s"(.*?)"$', line).group(1)
cells[list(cells.keys())[-1]]['ssid'] = ssid
elif line.startswith('Mode: '):
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))
cells[list(cells.keys())[-1]]['band'] = try_float(m.group(2))
cells[list(cells.keys())[-1]]['chan'] = try_int(m.group(3))
elif line.startswith('Encryption: '):
enc = re.search(r'Encryption: (.*?)$', line).group(1)
cells[list(cells.keys())[-1]]['enc'] = enc
elif line.startswith('Channel Width: '):
width = re.search(r'Channel Width: (.*?)$', line).group(1)
cells[list(cells.keys())[-1]]['chan_width'] = width
elif line.startswith('Signal: '):
m = re.search(r'Signal: (-[0-9]*) dBm\s\sQuality: ([0-9]*)/([0-9]*)$', line)
cells[list(cells.keys())[-1]]['signal'] = try_int(m.group(1))
cells[list(cells.keys())[-1]]['quality'] = (try_int(m.group(2)), try_int(m.group(3)))
print(f'BSSID {specific_bssid} is not present.') if args.print:
return False print(json.dumps(cells))
sys.exit(nagios.STATE_UNKNOWN)
if args.target_mac not in list(cells.keys()):
quit_check(f'AP address not found: {args.target_mac}', nagios.STATE_CRIT)
ap_data = cells[args.target_mac]
computed_quality = int(try_float(ap_data['quality'][0]) / try_float(ap_data['quality'][1]) * 100)
perfdata = {
'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': '%'},
'freq': {'value': ap_data['freq']},
'band': {'value': ap_data['band']},
'chan': {'value': ap_data['chan']},
'chan_width': {'value': ap_data['chan_width']},
}
if ap_data['ssid'] != args.expected_ssid:
quit_check(f'AP does not have the right SSID.\n{json.dumps(ap_data)}', nagios.STATE_CRIT, perfdata=perfdata)
if ap_data['signal'] <= args.signal_crit:
quit_check(f'Signal strength is weak: {ap_data["signal"]} dBm', nagios.STATE_CRIT, perfdata=perfdata)
if ap_data['signal'] <= args.signal_warn:
quit_check(f'Signal strength is weak: {ap_data["signal"]} dBm', nagios.STATE_WARN, perfdata=perfdata)
if computed_quality <= args.quality_crit:
quit_check(f'Signal quality is low: {ap_data["quality"][0]}/{ap_data["quality"][1]} ({computed_quality}%)', nagios.STATE_CRIT, perfdata=perfdata)
if computed_quality <= args.quality_warn:
quit_check(f'Signal quality is low: {ap_data["quality"][0]}/{ap_data["quality"][1]} ({computed_quality}%)', nagios.STATE_WARN, perfdata=perfdata)
quit_check(f"{ap_data['ssid']} ({args.target_mac}) is healthy. Signal: {ap_data['signal']} dBm. Quality: {computed_quality}%. Frequency: {ap_data['freq']} GHz. Band: {ap_data['band']} GHz. Channel: {ap_data['chan']} @ {ap_data['chan_width']} width. Encryption: {ap_data['enc']}.",
nagios.STATE_OK,
perfdata=perfdata)
check_bssid() if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--host', required=True, help='The host to SSH into.')
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('--expected-ssid', required=True, help="The AP's expected SSID.")
parser.add_argument('--signal-warn', type=int, required=True, help='If the signal strength is less than this, trigger warn.')
parser.add_argument('--signal-crit', type=int, required=True, help='If the signal strength is less than this, trigger crit.')
parser.add_argument('--quality-warn', type=int, required=True, help='If the signal quality is less than this percentage, trigger warn.')
parser.add_argument('--quality-crit', type=int, required=True, help='If the signal quality is less than this percentage, trigger crit.')
args = parser.parse_args()
try:
main(args)
except Exception as e:
print(f'UNKNOWN - exception "{e}"')
traceback.print_exc()
sys.exit(nagios.STATE_UNKNOWN)

View File

@ -10,3 +10,4 @@ pysnmp==4.4.12
aiofiles==0.6.0 aiofiles==0.6.0
python-magic==0.4.27 python-magic==0.4.27
markdown==3.4.4 markdown==3.4.4
paramiko==3.4.0