mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 16:44:39 +00:00
python3: replace subprocess.call in src/opnsense/scripts/filter/* for https://github.com/opnsense/core/issues/3574
This commit is contained in:
parent
2f69282b28
commit
867856733b
@ -35,22 +35,15 @@ import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = []
|
||||
if len(sys.argv) > 2:
|
||||
# always validate if the item is in the pf table before trying to delete
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
# delete an entry from a pf table
|
||||
subprocess.call(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'show'],
|
||||
stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
if sys.argv[2].strip() == 'ALL':
|
||||
if len(output_stream.read().decode().strip().split('\n')) > 0:
|
||||
# delete all entries from a pf table
|
||||
subprocess.call(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'flush'],
|
||||
stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
else:
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
if line.strip() == sys.argv[2].strip():
|
||||
result = []
|
||||
subprocess.call(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'delete', line.strip()],
|
||||
stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
|
||||
sp = subprocess.run(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'show'], capture_output=True, text=True)
|
||||
if sys.argv[2].strip() == 'ALL':
|
||||
if len(sp.stdout.strip().split('\n')) > 0:
|
||||
# delete all entries from a pf table
|
||||
subprocess.run(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'flush'], capture_output=True)
|
||||
else:
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
if line.strip() == sys.argv[2].strip():
|
||||
subprocess.run(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'delete', line.strip()],
|
||||
capture_output=True)
|
||||
|
||||
@ -45,23 +45,17 @@ if __name__ == '__main__':
|
||||
tables = []
|
||||
|
||||
# Fetch tables
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-sT'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
tables.append(line.strip())
|
||||
sp = subprocess.run(['/sbin/pfctl', '-sT'], capture_output=True, text=True)
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
tables.append(line.strip())
|
||||
|
||||
# Fetch IP ranges in this table and check if they match
|
||||
for table in tables:
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-t', table, '-T', 'show'],
|
||||
stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
if line.strip() != "":
|
||||
if ip in IPNetwork(line.strip()):
|
||||
result['matches'].append(table)
|
||||
|
||||
sp = subprocess.run(['/sbin/pfctl', '-t', table, '-T', 'show'], capture_output=True, text=True)
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
if line.strip() != "":
|
||||
if ip in IPNetwork(line.strip()):
|
||||
result['matches'].append(table)
|
||||
print(ujson.dumps(result))
|
||||
|
||||
except AddrFormatError:
|
||||
|
||||
@ -28,28 +28,25 @@
|
||||
--------------------------------------------------------------------------------------
|
||||
drop an existing pf alias table
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-sT'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
tables = list()
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
tables.append(line.strip())
|
||||
# only try to remove alias if it exists
|
||||
if len(sys.argv) > 1 and sys.argv[1] in tables:
|
||||
# cleanup related alias file
|
||||
for suffix in ['txt', 'md5.txt', 'self.txt']:
|
||||
if os.path.isfile('/var/db/aliastables/%s.%s' % (sys.argv[1], suffix)):
|
||||
os.remove('/var/db/aliastables/%s.%s' % (sys.argv[1], suffix))
|
||||
subprocess.call(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'kill'], stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
|
||||
# all good, exit 0
|
||||
sys.exit(0)
|
||||
sp = subprocess.run(['/sbin/pfctl', '-sT'], capture_output=True, text=True)
|
||||
tables = list()
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
tables.append(line.strip())
|
||||
# only try to remove alias if it exists
|
||||
if len(sys.argv) > 1 and sys.argv[1] in tables:
|
||||
# cleanup related alias file
|
||||
for suffix in ['txt', 'md5.txt', 'self.txt']:
|
||||
if os.path.isfile('/var/db/aliastables/%s.%s' % (sys.argv[1], suffix)):
|
||||
os.remove('/var/db/aliastables/%s.%s' % (sys.argv[1], suffix))
|
||||
subprocess.run(['/sbin/pfctl', '-t', sys.argv[1], '-T', 'kill'], capture_output=True)
|
||||
# all good, exit 0
|
||||
sys.exit(0)
|
||||
|
||||
# not found (or other issue)
|
||||
sys.exit(-1)
|
||||
|
||||
@ -36,39 +36,37 @@ import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = dict()
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-vvsI'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
intf = None
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
if line.find('[') == -1 and line[0] not in (' ', '\t'):
|
||||
intf = line.strip()
|
||||
result[intf] = {'inbytespass': 0, 'outbytespass': 0, 'inpktspass': 0, 'outpktspass': 0,
|
||||
'inbytesblock': 0, 'outbytesblock': 0, 'inpktsblock': 0, 'outpktsblock': 0,
|
||||
'inpkts':0, 'inbytes': 0, 'outpkts': 0, 'outbytes': 0}
|
||||
if intf is not None and line.find('[') > -1:
|
||||
packets = int(line.split(' Packets:')[-1].strip().split()[0])
|
||||
bytes = int(line.split(' Bytes:')[-1].strip().split()[0])
|
||||
if line.find('In4/Pass:') > -1 or line.find('In6/Pass:') > -1:
|
||||
result[intf]['inpktspass'] += packets
|
||||
result[intf]['inbytespass'] += bytes
|
||||
result[intf]['inpkts'] += packets
|
||||
result[intf]['inbytes'] += bytes
|
||||
elif line.find('In4/Block:') > -1 or line.find('In6/Block:') > -1:
|
||||
result[intf]['inbytesblock'] += packets
|
||||
result[intf]['inpktsblock'] += bytes
|
||||
result[intf]['inpkts'] += packets
|
||||
result[intf]['inbytes'] += bytes
|
||||
elif line.find('Out4/Pass:') > -1 or line.find('Out6/Pass:') > -1:
|
||||
result[intf]['outpktspass'] += packets
|
||||
result[intf]['outbytespass'] += bytes
|
||||
result[intf]['outpkts'] += packets
|
||||
result[intf]['outbytes'] += bytes
|
||||
elif line.find('Out4/Block:') > -1 or line.find('Out6/Block:') > -1:
|
||||
result[intf]['outpktsblock'] += packets
|
||||
result[intf]['outbytesblock'] += bytes
|
||||
result[intf]['outpkts'] += packets
|
||||
result[intf]['outbytes'] += bytes
|
||||
sp = subprocess.run(['/sbin/pfctl', '-vvsI'], capture_output=True, text=True)
|
||||
intf = None
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
if line.find('[') == -1 and line[0] not in (' ', '\t'):
|
||||
intf = line.strip()
|
||||
result[intf] = {'inbytespass': 0, 'outbytespass': 0, 'inpktspass': 0, 'outpktspass': 0,
|
||||
'inbytesblock': 0, 'outbytesblock': 0, 'inpktsblock': 0, 'outpktsblock': 0,
|
||||
'inpkts':0, 'inbytes': 0, 'outpkts': 0, 'outbytes': 0}
|
||||
if intf is not None and line.find('[') > -1:
|
||||
packets = int(line.split(' Packets:')[-1].strip().split()[0])
|
||||
bytes = int(line.split(' Bytes:')[-1].strip().split()[0])
|
||||
if line.find('In4/Pass:') > -1 or line.find('In6/Pass:') > -1:
|
||||
result[intf]['inpktspass'] += packets
|
||||
result[intf]['inbytespass'] += bytes
|
||||
result[intf]['inpkts'] += packets
|
||||
result[intf]['inbytes'] += bytes
|
||||
elif line.find('In4/Block:') > -1 or line.find('In6/Block:') > -1:
|
||||
result[intf]['inbytesblock'] += packets
|
||||
result[intf]['inpktsblock'] += bytes
|
||||
result[intf]['inpkts'] += packets
|
||||
result[intf]['inbytes'] += bytes
|
||||
elif line.find('Out4/Pass:') > -1 or line.find('Out6/Pass:') > -1:
|
||||
result[intf]['outpktspass'] += packets
|
||||
result[intf]['outbytespass'] += bytes
|
||||
result[intf]['outpkts'] += packets
|
||||
result[intf]['outbytes'] += bytes
|
||||
elif line.find('Out4/Block:') > -1 or line.find('Out6/Block:') > -1:
|
||||
result[intf]['outpktsblock'] += packets
|
||||
result[intf]['outbytesblock'] += bytes
|
||||
result[intf]['outpkts'] += packets
|
||||
result[intf]['outbytes'] += bytes
|
||||
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'json':
|
||||
|
||||
@ -28,21 +28,17 @@
|
||||
--------------------------------------------------------------------------------------
|
||||
list os fingerprints
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = []
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-s', 'osfp'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
data = output_stream.read().decode().strip()
|
||||
if data.count('\n') > 2:
|
||||
for line in data.split('\n')[2:]:
|
||||
result.append(line.replace('\t', ' ').strip())
|
||||
sp = subprocess.run(['/sbin/pfctl', '-s', 'osfp'], capture_output=True)
|
||||
data = sp.stdout.decode().strip()
|
||||
if data.count('\n') > 2:
|
||||
for line in data.split('\n')[2:]:
|
||||
result.append(line.replace('\t', ' ').strip())
|
||||
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'json':
|
||||
|
||||
@ -29,24 +29,20 @@
|
||||
list pfsync info
|
||||
- nodes (unique creator id's from states)
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = {'nodes': []}
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-s', 'state', '-vv'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
data = output_stream.read().decode().strip()
|
||||
if data.count('\n') > 2:
|
||||
for line in data.split('\n'):
|
||||
if line.find('creatorid:') > -1:
|
||||
creatorid = line.split('creatorid:')[1].strip()
|
||||
if creatorid not in result['nodes']:
|
||||
result['nodes'].append(creatorid)
|
||||
sp = subprocess.run(['/sbin/pfctl', '-s', 'state', '-vv'], capture_output=True)
|
||||
data = sp.stdout.decode().strip()
|
||||
if data.count('\n') > 2:
|
||||
for line in data.split('\n'):
|
||||
if line.find('creatorid:') > -1:
|
||||
creatorid = line.split('creatorid:')[1].strip()
|
||||
if creatorid not in result['nodes']:
|
||||
result['nodes'].append(creatorid)
|
||||
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'json':
|
||||
|
||||
@ -28,9 +28,7 @@
|
||||
--------------------------------------------------------------------------------------
|
||||
list pf states
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
import argparse
|
||||
@ -62,47 +60,45 @@ if __name__ == '__main__':
|
||||
inputargs = parser.parse_args()
|
||||
|
||||
result = {'details': [], 'total_entries': 0}
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-s', 'state'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
data = output_stream.read().decode().strip()
|
||||
if data.count('\n') > 2:
|
||||
for line in data.split('\n'):
|
||||
parts = line.split()
|
||||
if len(parts) >= 6:
|
||||
# count total number of state table entries
|
||||
result['total_entries'] += 1
|
||||
# apply filter when provided
|
||||
if inputargs.filter != "" and line.lower().find(inputargs.filter) == -1:
|
||||
continue
|
||||
# limit results
|
||||
if inputargs.limit.isdigit() and len(result['details']) >= int(inputargs.limit):
|
||||
continue
|
||||
record = dict()
|
||||
record['nat_addr'] = None
|
||||
record['nat_port'] = None
|
||||
record['iface'] = parts[0]
|
||||
record['proto'] = parts[1]
|
||||
record['src_addr'] = parse_address(parts[2])['addr']
|
||||
record['src_port'] = parse_address(parts[2])['port']
|
||||
record['ipproto'] = parse_address(parts[2])['ipproto']
|
||||
sp = subprocess.run(['/sbin/pfctl', '-s', 'state'], capture_output=True, text=True)
|
||||
data = sp.stdout.strip()
|
||||
if data.count('\n') > 2:
|
||||
for line in data.split('\n'):
|
||||
parts = line.split()
|
||||
if len(parts) >= 6:
|
||||
# count total number of state table entries
|
||||
result['total_entries'] += 1
|
||||
# apply filter when provided
|
||||
if inputargs.filter != "" and line.lower().find(inputargs.filter) == -1:
|
||||
continue
|
||||
# limit results
|
||||
if inputargs.limit.isdigit() and len(result['details']) >= int(inputargs.limit):
|
||||
continue
|
||||
record = dict()
|
||||
record['nat_addr'] = None
|
||||
record['nat_port'] = None
|
||||
record['iface'] = parts[0]
|
||||
record['proto'] = parts[1]
|
||||
record['src_addr'] = parse_address(parts[2])['addr']
|
||||
record['src_port'] = parse_address(parts[2])['port']
|
||||
record['ipproto'] = parse_address(parts[2])['ipproto']
|
||||
|
||||
if parts[3].find('(') > -1:
|
||||
# NAT enabled
|
||||
record['nat_addr'] = parts[3][1:].split(':')[0]
|
||||
record['nat_port'] = parts[3].split(':')[1][:-1]
|
||||
if parts[3].find('(') > -1:
|
||||
# NAT enabled
|
||||
record['nat_addr'] = parts[3][1:].split(':')[0]
|
||||
record['nat_port'] = parts[3].split(':')[1][:-1]
|
||||
|
||||
record['dst_addr'] = parse_address(parts[-2])['addr']
|
||||
record['dst_port'] = parse_address(parts[-2])['port']
|
||||
record['dst_addr'] = parse_address(parts[-2])['addr']
|
||||
record['dst_port'] = parse_address(parts[-2])['port']
|
||||
|
||||
if parts[-3] == '->':
|
||||
record['direction'] = 'out'
|
||||
else:
|
||||
record['direction'] = 'in'
|
||||
if parts[-3] == '->':
|
||||
record['direction'] = 'out'
|
||||
else:
|
||||
record['direction'] = 'in'
|
||||
|
||||
record['state'] = parts[-1]
|
||||
record['state'] = parts[-1]
|
||||
|
||||
result['details'].append(record)
|
||||
result['details'].append(record)
|
||||
|
||||
result['total'] = len(result['details'])
|
||||
|
||||
|
||||
@ -29,40 +29,33 @@
|
||||
returns the contents of a pf table (optional as a json container)
|
||||
usage : list_table.py [tablename] [optional|json]
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = dict()
|
||||
if len(sys.argv) > 1:
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-t', sys.argv[1], '-vT', 'show'],
|
||||
stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.write(b'\n') # always make sure we have a final line-ending
|
||||
output_stream.seek(0)
|
||||
prev_entry=''
|
||||
statistics=dict()
|
||||
for rline in output_stream:
|
||||
line = rline.decode()
|
||||
if not line.startswith('\t'):
|
||||
this_entry = line.strip()
|
||||
if len(prev_entry) > 0:
|
||||
result[prev_entry] = statistics
|
||||
prev_entry = this_entry
|
||||
statistics=dict()
|
||||
else:
|
||||
parts = line.split()
|
||||
if len(parts) > 6:
|
||||
if parts[3].isdigit() and parts[5].isdigit():
|
||||
pkts=int(parts[3])
|
||||
bytes=int(parts[5])
|
||||
topic = parts[0].lower().replace('/', '_').replace(':', '')
|
||||
if pkts > 0:
|
||||
statistics['%s_p' % topic] = pkts
|
||||
statistics['%s_b' % topic] = bytes
|
||||
sp = subprocess.run(['/sbin/pfctl', '-t', sys.argv[1], '-vT', 'show'], capture_output=True, text=True)
|
||||
prev_entry=''
|
||||
statistics=dict()
|
||||
for line in sp.stdout.split('\n') + []:
|
||||
if not line.startswith('\t'):
|
||||
this_entry = line.strip()
|
||||
if len(prev_entry) > 0:
|
||||
result[prev_entry] = statistics
|
||||
prev_entry = this_entry
|
||||
statistics=dict()
|
||||
else:
|
||||
parts = line.split()
|
||||
if len(parts) > 6:
|
||||
if parts[3].isdigit() and parts[5].isdigit():
|
||||
pkts=int(parts[3])
|
||||
bytes=int(parts[5])
|
||||
topic = parts[0].lower().replace('/', '_').replace(':', '')
|
||||
if pkts > 0:
|
||||
statistics['%s_p' % topic] = pkts
|
||||
statistics['%s_b' % topic] = bytes
|
||||
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 2 and sys.argv[2] == 'json':
|
||||
|
||||
@ -28,20 +28,15 @@
|
||||
--------------------------------------------------------------------------------------
|
||||
returns a list of pf tables (optional as a json container)
|
||||
"""
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = []
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-sT'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
result.append(line.strip())
|
||||
|
||||
sp = subprocess.run(['/sbin/pfctl', '-sT'], capture_output=True, text=True)
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
result.append(line.strip())
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'json':
|
||||
print(ujson.dumps(result))
|
||||
|
||||
@ -29,19 +29,15 @@
|
||||
returns raw pf info (optional packed in a json container)
|
||||
"""
|
||||
import collections
|
||||
import tempfile
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import ujson
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = collections.OrderedDict()
|
||||
for stattype in ['info', 'memory', 'timeouts', 'Interfaces', 'rules']:
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-vvs'+stattype], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
result[stattype] = output_stream.read().decode().strip()
|
||||
sp = subprocess.run(['/sbin/pfctl', '-vvs'+stattype], capture_output=True, text=True)
|
||||
result[stattype] = sp.stdout.strip()
|
||||
|
||||
# handle command line argument (type selection)
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'json':
|
||||
|
||||
@ -33,7 +33,6 @@ import sys
|
||||
from hashlib import md5
|
||||
import argparse
|
||||
import ujson
|
||||
import tempfile
|
||||
import subprocess
|
||||
sys.path.insert(0, "/usr/local/opnsense/site-python")
|
||||
from log_helper import reverse_log_reader, fetch_clog
|
||||
@ -85,19 +84,16 @@ def fetch_rule_details():
|
||||
rule_map[rule_md5] = ''.join(lbl.split('"')[2:]).strip().strip('# : ')
|
||||
|
||||
# use pfctl to create a list per rule number with the details found
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-vvPsr'],
|
||||
stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
if line.startswith('@'):
|
||||
line_id = line.split()[0][1:]
|
||||
if line.find(' label ') > -1:
|
||||
rid = ''.join(line.split(' label ')[-1:]).strip()[1:-1]
|
||||
if rid in rule_map:
|
||||
result[line_id] = {'rid': rid, 'label': rule_map[rid]}
|
||||
else:
|
||||
result[line_id] = {'rid': None, 'label': rid}
|
||||
sp = subprocess.run(['/sbin/pfctl', '-vvPsr'], capture_output=True, text=True)
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
if line.startswith('@'):
|
||||
line_id = line.split()[0][1:]
|
||||
if line.find(' label ') > -1:
|
||||
rid = ''.join(line.split(' label ')[-1:]).strip()[1:-1]
|
||||
if rid in rule_map:
|
||||
result[line_id] = {'rid': rid, 'label': rule_map[rid]}
|
||||
else:
|
||||
result[line_id] = {'rid': None, 'label': rid}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@ -36,40 +36,37 @@ import subprocess
|
||||
if __name__ == '__main__':
|
||||
results = dict()
|
||||
hex_digits = set("0123456789abcdef")
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-sr', '-v'], stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.write(b'\n') # always make sure we have a final line-ending
|
||||
output_stream.seek(0)
|
||||
stats = dict()
|
||||
prev_line = ''
|
||||
for rline in output_stream:
|
||||
line = rline.decode().strip()
|
||||
if len(line) == 0 or line[0] != '[':
|
||||
if prev_line.find(' label ') > -1:
|
||||
lbl = prev_line.split(' label ')[-1]
|
||||
if lbl.count('"') >= 2:
|
||||
rule_md5 = lbl.split('"')[1]
|
||||
if len(rule_md5) == 32 and set(rule_md5).issubset(hex_digits):
|
||||
if rule_md5 in results:
|
||||
# aggregate raw pf rules (a single rule in out ruleset could be expanded)
|
||||
for key in stats:
|
||||
if key in results[rule_md5]:
|
||||
if key == 'pf_rules':
|
||||
results[rule_md5][key] += 1
|
||||
else:
|
||||
results[rule_md5][key] += stats[key]
|
||||
sp = subprocess.run(['/sbin/pfctl', '-sr', '-v'], capture_output=True, text=True)
|
||||
stats = dict()
|
||||
prev_line = ''
|
||||
for rline in sp.stdout.split('\n') + []:
|
||||
line = rline.strip()
|
||||
if len(line) == 0 or line[0] != '[':
|
||||
if prev_line.find(' label ') > -1:
|
||||
lbl = prev_line.split(' label ')[-1]
|
||||
if lbl.count('"') >= 2:
|
||||
rule_md5 = lbl.split('"')[1]
|
||||
if len(rule_md5) == 32 and set(rule_md5).issubset(hex_digits):
|
||||
if rule_md5 in results:
|
||||
# aggregate raw pf rules (a single rule in out ruleset could be expanded)
|
||||
for key in stats:
|
||||
if key in results[rule_md5]:
|
||||
if key == 'pf_rules':
|
||||
results[rule_md5][key] += 1
|
||||
else:
|
||||
results[rule_md5][key] = stats[key]
|
||||
else:
|
||||
results[rule_md5] = stats
|
||||
# reset for next rule
|
||||
prev_line = line
|
||||
stats = {'pf_rules': 1}
|
||||
elif line[0] == '[' and line.find('Evaluations') > 0:
|
||||
parts = line.strip('[ ]').replace(':', ' ').split()
|
||||
for i in range(0, len(parts)-1, 2):
|
||||
if parts[i+1].isdigit():
|
||||
stats[parts[i].lower()] = int(parts[i+1])
|
||||
results[rule_md5][key] += stats[key]
|
||||
else:
|
||||
results[rule_md5][key] = stats[key]
|
||||
else:
|
||||
results[rule_md5] = stats
|
||||
# reset for next rule
|
||||
prev_line = line
|
||||
stats = {'pf_rules': 1}
|
||||
elif line[0] == '[' and line.find('Evaluations') > 0:
|
||||
parts = line.strip('[ ]').replace(':', ' ').split()
|
||||
for i in range(0, len(parts)-1, 2):
|
||||
if parts[i+1].isdigit():
|
||||
stats[parts[i].lower()] = int(parts[i+1])
|
||||
|
||||
# output
|
||||
print (ujson.dumps(results))
|
||||
|
||||
@ -36,7 +36,6 @@ import json
|
||||
import urllib3
|
||||
import xml.etree.cElementTree as ET
|
||||
import syslog
|
||||
import tempfile
|
||||
import subprocess
|
||||
import glob
|
||||
from lib.alias import Alias
|
||||
@ -142,36 +141,30 @@ if __name__ == '__main__':
|
||||
alias_content_txt = ""
|
||||
|
||||
alias_pf_content = list()
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-t', alias_name, '-T', 'show'],
|
||||
stdout=output_stream, stderr=open(os.devnull, 'wb'))
|
||||
output_stream.seek(0)
|
||||
for line in output_stream.read().decode().strip().split('\n'):
|
||||
line = line.strip()
|
||||
if line:
|
||||
alias_pf_content.append(line)
|
||||
sp = subprocess.run(['/sbin/pfctl', '-t', alias_name, '-T', 'show'], capture_output=True, text=True)
|
||||
for line in sp.stdout.strip().split('\n'):
|
||||
line = line.strip()
|
||||
if line:
|
||||
alias_pf_content.append(line)
|
||||
|
||||
if (len(alias_content) != len(alias_pf_content) or alias_changed_or_expired) and alias.get_parser():
|
||||
# if the alias is changed, expired or the one in memory has a different number of items, load table
|
||||
# (but only if we know how to handle this alias type)
|
||||
if len(alias_content) == 0:
|
||||
# flush when target is empty
|
||||
subprocess.call(['/sbin/pfctl', '-t', alias_name, '-T', 'flush'],
|
||||
stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
|
||||
subprocess.run(['/sbin/pfctl', '-t', alias_name, '-T', 'flush'], capture_output=True)
|
||||
else:
|
||||
# replace table contents with collected alias
|
||||
with tempfile.NamedTemporaryFile() as output_stream:
|
||||
subprocess.call(['/sbin/pfctl', '-t', alias_name, '-T', 'replace', '-f',
|
||||
'/var/db/aliastables/%s.txt' % alias_name],
|
||||
stdout=open(os.devnull, 'wb'), stderr=output_stream)
|
||||
output_stream.seek(0)
|
||||
error_output = output_stream.read().decode().strip()
|
||||
if error_output.find('pfctl: ') > -1:
|
||||
result['status'] = 'error'
|
||||
if 'messages' not in result:
|
||||
result['messages'] = list()
|
||||
if error_output not in result['messages']:
|
||||
result['messages'].append(error_output.replace('pfctl: ', ''))
|
||||
sp = subprocess.run(['/sbin/pfctl', '-t', alias_name, '-T', 'replace', '-f',
|
||||
'/var/db/aliastables/%s.txt' % alias_name], capture_output=True, text=True)
|
||||
|
||||
error_output = sp.stdout.strip()
|
||||
if error_output.find('pfctl: ') > -1:
|
||||
result['status'] = 'error'
|
||||
if 'messages' not in result:
|
||||
result['messages'] = list()
|
||||
if error_output not in result['messages']:
|
||||
result['messages'].append(error_output.replace('pfctl: ', ''))
|
||||
# cleanup removed aliases
|
||||
to_remove = dict()
|
||||
for filename in glob.glob('/var/db/aliastables/*.txt'):
|
||||
@ -182,10 +175,7 @@ if __name__ == '__main__':
|
||||
to_remove[aliasname].append(filename)
|
||||
for aliasname in to_remove:
|
||||
syslog.syslog(syslog.LOG_NOTICE, 'remove old alias %s' % aliasname)
|
||||
subprocess.call(
|
||||
['/sbin/pfctl', '-t', aliasname, '-T', 'kill'],
|
||||
stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb')
|
||||
)
|
||||
subprocess.run(['/sbin/pfctl', '-t', aliasname, '-T', 'kill'], capture_output=True)
|
||||
for filename in to_remove[aliasname]:
|
||||
os.remove(filename)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user