Mini Shell
#!/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