Mini Shell

Direktori : /opt/tier1adv/bin/
Upload File :
Current File : //opt/tier1adv/bin/checkip

#!/opt/imh-python/bin/python3
"""Checks if an IP is blocked in the firewall"""

import os
from argparse import ArgumentParser
import sys
import subprocess
import json
import netaddr
import rads

sys.path.insert(0, '/opt/support/lib')
import arg_types
from output import header, print_listed, warn
import firewall_tools as fw


def parse_args():
    """Parse IPs from commandline args"""
    parser = ArgumentParser(description=__doc__)
    parser.add_argument(
        'ips',
        metavar='IP_ADDRESS',
        nargs='+',
        type=arg_types.ipaddress,
        help='IP to check (may be either IPv4 or IPv6)',
    )
    yes_group = parser.add_mutually_exclusive_group()
    yes_group.add_argument(
        '--yes',
        '-y',
        action='store_true',
        help='Auto-YES to the confirmation prompt to check ping and traceroute',
    )
    yes_group.add_argument(
        '--no',
        '-n',
        action='store_true',
        help="Auto-NO to the confirmation prompt to check ping and traceroute",
    )
    args = parser.parse_args()
    for addr in args.ips:
        addr: netaddr.IPAddress
        if addr.is_private():
            warn(
                f'Warning: {addr} is a private IP and therefore cannot route '
                'over the internet.'
            )
        if str(addr).endswith('.255'):
            warn(
                f'Warning: {addr} ends in .255 and therefore may be rejected '
                'as a "bogon" by some routers, even if this is a valid IP.'
            )
    return args


def check_firewall(ips: list[netaddr.IPAddress]):
    header('Checking firewall...')
    fw_name, _, fw_data = fw.fw_info()
    print('This server is using', fw_name)
    for ipaddr in ips:
        if fw_name == 'ipset+fail2ban':
            # this function handles printing already
            fw.ipset_fail2ban_check(fw_data, ipaddr)
        else:  # APF or CSF
            listed = str(ipaddr) in fw_data
            print_listed(ipaddr, listed, f'the {fw_name} deny list')


def check_cphulk_logs(ips: list[netaddr.IPAddress]):
    if os.path.exists("/usr/local/cpanel/logs/cphulkd.log"):
        cph_log = "/usr/local/cpanel/logs/cphulkd.log"
        try:
            cmd = ["whmapi1", "--output=jsonpretty", "cphulk_status"]
            result = subprocess.run(cmd, capture_output=True, text=True)
            if json.loads(result.stdout).get('data', {}).get('is_enabled', False) == 1:
                with open(cph_log) as logfile:
                    for ip in ips:
                        if str(ip) in logfile.read():
                            print(f'{ip} was found in cphulk logs')

        except Exception as e:
            print(f'''
                An error occured while checking CPHulk status.
                If this is a VPS or dedicated server confirm
                that CPHulk is enabled.
                Confirm the path to CPHulk logs:
                {cph_log}
                ''')
    else:
        print('''
              Log file for CPHulk is missing.
              Is CPHulk enabled?
              ''')


def ping(ips: dict[netaddr.IPAddress, bool]):
    header('Running ping tests...')
    for addr, is_v6 in ips.items():
        cmd = ['ping6'] if is_v6 else ['ping']
        cmd.extend(['-c2', str(addr)])
        subprocess.call(cmd)


def trace(ips: dict[netaddr.IPAddress, bool]):
    header('Running traceroute tests...')
    for addr, is_v6 in ips.items():
        cmd = ['traceroute6'] if is_v6 else ['traceroute']
        cmd.append(str(addr))
        subprocess.call(cmd)


def main():
    """Parse args, check firewall"""
    args = parse_args()
    check_firewall(args.ips)
    check_cphulk_logs(args.ips)
    if args.no:
        sys.exit(0)
    if not args.yes and not rads.prompt_y_n(
        'Would you like to proceed with ping and traceroute tests?'
    ):
        sys.exit(0)
    ips = {x: netaddr.valid_ipv6(x) for x in args.ips}
    try:
        ping(ips)
        trace(ips)
    except KeyboardInterrupt:
        sys.exit(0)


if __name__ == '__main__':
    main()

Zerion Mini Shell 1.0