|
- # -*- coding: utf-8 -*-
- from os import chmod,remove
- from time import time
- from subprocess import Popen,PIPE
-
- def get_tables(family="ipv4"):
-
- ''' List iptables tables
-
- :param family: iptables ip family version. type: str
-
- '''
-
- if family == "ipv4":
- cmd = 'iptables-save'
- elif family == "ipv6":
- cmd = 'ip6tables-save'
- else:
- return "Invalid ip family specified. Use either ipv4 or ipv6"
-
- tables = []
- try:
- tables_list = Popen(cmd, shell=True, stdout=PIPE)
- while True:
- line = tables_list.stdout.readline().decode()
- if line != '':
- if line[0] == "*":
- tables.append(line.rstrip()[1:])
- else:
- break
- except:
- return "Error getting list of tables"
-
- return tables
-
- def get_chains(family="ipv4", table="filter"):
-
- ''' List iptables chains
-
- :param family: iptables ip family version. type: str
- :param table: Lookup chains for this table. type: str
-
- '''
-
- if family == "ipv4":
- cmd = 'iptables-save'
- elif family == "ipv6":
- cmd = 'ip6tables-save'
- else:
- return "Invalid ip family specified. Use either ipv4 or ipv6"
-
- cmd += ' -t ' + table
-
- chains = []
- try:
- chains_list = Popen(cmd, shell=True, stdout=PIPE)
- while True:
- line = chains_list.stdout.readline()
- if line != '':
- if line[0] == ":":
- chains.append(line.rstrip()[1:].split(' ')[0])
- else:
- break
- except:
- return "Error getting list of chains"
-
- return chains
-
- def get_structure(family="ipv4"):
-
- ''' Get structure of all chains in all tables
-
- :param family: iptables ip family version. type: str
-
- '''
-
- if family == "ipv4":
- cmd = 'iptables-save'
- elif family == "ipv6":
- cmd = 'ip6tables-save'
- else:
- return "Invalid ip family specified. Use either ipv4 or ipv6"
-
- tables = []
- tables_list = Popen(cmd, shell=True, stdout=PIPE)
- while True:
- line = tables_list.stdout.readline()
- if line != '':
- line = line.rstrip().lstrip()
- if line[0] == "*":
- elem = {}
- table_name = line[1:].split(' ')[0]
- elem[table_name] = []
- if line[0] == ":":
- elem[table_name].append(line[1:].split(' ')[0])
- if line == "COMMIT":
- tables.append(elem)
- else:
- break
-
- return tables
-
- def run_script(script):
-
- ''' Execute local script
-
- :param script: script to be executed, storad localy: str
-
- '''
-
- chmod(script, 0o700)
- process = Popen([script],stdout=PIPE,stderr=PIPE)
- process.wait()
- code = process.returncode
- remove(script)
- return code
-
-
- def flush_all(family="ipv4"):
-
- ''' Flush all chains in all tables
-
- :param family: iptables ip family version. type: str
-
- '''
-
- if family == "ipv4":
- cmd = 'iptables'
- rmmod = 'iptable_'
- elif family == "ipv6":
- cmd = 'ip6tables'
- rmmod = 'ip6table_'
- else:
- return "Invalid ip family specified. Use either ipv4 or ipv6"
-
- tables = get_structure(family)
-
- f_name = '/tmp/' + cmd + '-flush-' + str(time()).split('.')[0] + '.sh'
-
- with open(f_name, 'w') as f:
- f.write('#!/bin/sh\n')
- for table in tables:
- for var in enumerate(table):
- t_name = var[1]
- for chain in table[t_name]:
- f.write(cmd + ' -t ' + t_name + " -F " + chain + '\n')
- if chain not in ['INPUT','FORWARD','OUTPUT','PREROUTING','POSTROUTING']:
- f.write(cmd + ' -t ' + t_name + " -X " + chain + '\n')
- f.write('rmmod ' + rmmod + t_name + '\n')
-
- return run_script(f_name)
-
- def set_policy_all(family="ipv4", policy="ACCEPT"):
-
- ''' Set policy for all chains in all tables
-
- :param family: iptables ip family version. type: str
- :param policy: iptables chain policy. type: str
-
- '''
-
- if family == "ipv4":
- cmd = 'iptables'
- elif family == "ipv6":
- cmd = 'ip6tables'
- else:
- return "Invalid ip family specified. Use either ipv4 or ipv6"
-
- tables = get_structure(family)
-
- f_name = '/tmp/' + cmd + '-policy-' + str(time()).split('.')[0] + '.sh'
-
- with open(f_name, 'w') as f:
- f.write('#!/bin/sh\n')
- for table in tables:
- for var in enumerate(table):
- t_name = var[1]
- for chain in table[t_name]:
- f.write(cmd + ' -t ' + t_name + " -P " + chain + ' ' + policy + '\n')
-
- return run_script(f_name)
-
- def remove_stale_tables(config_file, family="ipv4"):
-
- ''' Remove tables which are not in config file
- to prevet flushing all the tables
-
- :param family: iptables ip family version. type: str
- :param config_file: iptables rules persistent config file. type: str
-
- '''
-
- if family == "ipv4":
- cmd = 'iptables'
- rmmod = 'iptable_'
- elif family == "ipv6":
- cmd = 'ip6tables'
- rmmod = 'ip6table_'
- else:
- return "Invalid ip family specified. Use either ipv4 or ipv6"
-
- runtime_tables = get_tables(family)
-
- config_tables = []
- for line in open(config_file, 'r'):
- if line != '':
- if line[0] == "*":
- config_tables.append(line.rstrip()[1:])
-
- runtime_tables.sort()
- config_tables.sort()
- diff = list(set(runtime_tables) - set(config_tables))
-
- if diff != []:
- tables = get_structure(family)
- f_name = '/tmp/' + cmd + '-flush-' + str(time()).split('.')[0] + '.sh'
- with open(f_name, 'w') as f:
- f.write('#!/bin/sh\n')
- for table in tables:
- for var in enumerate(table):
- t_name = var[1]
- if t_name in diff:
- for chain in table[t_name]:
- f.write(cmd + ' -t ' + t_name + " -F " + chain + '\n')
- if chain not in ['INPUT','FORWARD','OUTPUT','PREROUTING','POSTROUTING']:
- f.write(cmd + ' -t ' + t_name + " -X " + chain + '\n')
- f.write('rmmod ' + rmmod + t_name + '\n')
-
- return run_script(f_name)
- else:
- return
|