#!/usr/libexec/platform-python # # Created by Max.N v.0.0.1 # # Need sudo access to # 1) whmapi1 listaccts # 2) whmapi1 listips # Need read acces to # 1) /etc/reservedipreasons # # need add to sudoers.d # like: # /usr/sbin/whmapi1 listips --output=json,\ # /usr/sbin/whmapi1 listaccts --output=json,\ import argparse as ap import json import re import shelve import socket from subprocess import Popen, PIPE import time sudo = '/usr/bin/sudo' tmp_file_path = "/var/log/nagios/check_ips.conf" whmapi = "/usr/sbin/whmapi1" command = "listaccts --output=json" command2 = "listips --output=json" path_to_reserved_ips = "/etc/reservedipreasons" path_to_outgoing_mail_ip = "/etc/outgoingmailip" status_text = [] hostname = socket.gethostname() exit_code = 0 # list reserved local networks re_int_ip = re.compile(r'^(' r'0\.|' r'10\.|' r'100\.100\.0.|' r'100\.101\.0.|' r'100\.127\.255\.255|' r'127\.|' r'169\.254\.|' r'172\.16\.|' r'172\.(?:1[6-9])?(?:2[0-9])?(?:3[0-1])?\.|' r'172\.31\.255\.255|' r'192\.0\.|' r'192\.88\.99\.|' r'192\.168\.|' r'198\.18\.|' r'198\.19\.255\.255|' r'198\.51\.100\.|' r'198\.51\.100\.255|' r'203\.0\.113\.|' r'224\.0\.0\.0|' r'239\.255\.255\.255|' r'240\.0\.0\.|' r'255\.255\.255\.254|' r'255\.255\.255\.255' r')', re.MULTILINE) # - Parse args - parser = ap.ArgumentParser(description="Help") parser.add_argument("-v", action='store_true', help='enable verbose output') args, leftovers = parser.parse_known_args() if args.v: verbosity = 1 else: verbosity = 0 # - end - def get_mailip(path): with open(path) as file: ip = file.readline().splitlines() return ip def verbo(text): if verbosity > 0: print(text) def check_is_time(ip): result = False ip = str(ip) ip_config = shelve.open(tmp_file_path) unixtime = ip_config.get(ip, None) if unixtime: delta = int(time.time()) - unixtime if delta > (24 * 60 * 60): result = True else: ip_config[ip] = int(time.time()) return result def get_list_users_ips(command): try: run = [sudo, whmapi] run.extend(command.split()) # print " ".join(run) user_ips = [] dediated_ips_raw = json.loads(Popen(run, stdout=PIPE).stdout.read()) accounts = dediated_ips_raw.get("data").get("acct", None) if accounts: for account in accounts: ip = account.get("ip", None) if ip not in user_ips: user_ips.append(ip) else: user_ips = [] except: user_ips = [] return user_ips def get_raw_ips(command): try: run = [sudo, whmapi] run.extend(command.split()) # print " ".join(run) ips_raw = json.loads(Popen(run, stdout=PIPE).stdout.read()).get("data").get('ip') except: ips_raw = None return ips_raw def is_reseller(hostname): if hostname[:4] == 'host': return True else: return False raw_server_ips = get_raw_ips(command2) server_ips = [] ips_in_use = get_list_users_ips(command) ddos_ips = [] ipmi_ips = [] shared_ips = [] mail_ip = get_mailip(path_to_outgoing_mail_ip) # Alarm Vars alarm_in_config = [] # syntax error alarm_is_main = [] # in use main ip as dedicated alarm_in_not_use = [] # ip not in use at all alarm_is_internal = [] # ip is internal but have clients alarm_mailip_in_use = [] # users asing to mail ip with open(path_to_reserved_ips) as file: for line in file.readlines(): line = str(line).upper() # print line if line in ['\n', '\r\n']: continue # Skip blank lines ip = line.split("=") if len(ip) < 2: alarm_in_config.append("wtf with line " + str(line)) continue elif "IPMI" in str(ip[1]).upper(): ipmi_ips.append(ip[0]) elif "DDOS" in str(ip[1]).upper(): ddos_ips.append(ip[0]) elif "SHARED" in str(ip[1]).upper(): shared_ips.append(ip[0]) for row in raw_server_ips: ip = row.get("ip") is_main = row.get("mainaddr") server_ips.append(ip) internal = re.findall(re_int_ip, ip) if ip in ips_in_use: if len(internal) > 0: alarm_is_internal.append(ip) elif is_main == 1: alarm_is_main.append(ip) elif ip in mail_ip and ip not in shared_ips: alarm_mailip_in_use.append(ip) elif len(internal) == 0: if is_main == 1 or ip in ipmi_ips or ip in mail_ip or ip in shared_ips: # skip Main or IPMI or mail ips continue if not check_is_time(ip): verbo("Not this time my friend " + str(ip)) continue alarm_in_not_use.append(ip) if len(alarm_in_config) > 0: exit_code = 1 status_text.append(str(len(alarm_in_config)) + " something wrong in config") verbo("Something wrong in config") verbo(", ".join(alarm_in_config)) if len(alarm_in_not_use) > 0: exit_code = 1 if len(alarm_in_not_use) >= 5: exit_code = 2 text = str(len(alarm_in_not_use)) + " ip not in use" if is_reseller(hostname): text = text + " contact 'Billing Team'" status_text.append(text) verbo("Ip not in use") verbo(", ".join(alarm_in_not_use)) if not mail_ip: exit_code = 2 status_text.append("No mail ip was found on server") verbo("Something wrong in config, No mail ips") if len(alarm_mailip_in_use) > 0: exit_code = 2 status_text.append(str(len(alarm_mailip_in_use)) + " ip is reserved as mail but clients assigned on it") verbo("Ip is reserved as mail but clients assigned on it") verbo(", ".join(alarm_mailip_in_use)) if len(alarm_is_internal) > 0: exit_code = 2 status_text.append(str(len(alarm_is_internal)) + " ip is internal but clients assigned on it") verbo("Ip is internal but clients assign on it") verbo(", ".join(alarm_is_internal)) if len(alarm_is_main) > 0: exit_code = 2 status_text.append(str(len(alarm_is_main)) + " main ip assign as dedicated") verbo("Main ip assign as dedicated") verbo(", ".join(alarm_is_main)) if exit_code > 0: print("result: {}".format(status_text)) else: print("result: OK") exit(exit_code)