|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- # -*- 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
|