11#!/usr/bin/env python
22# -*- coding: UTF-8 -*-
33# Author: Andrey Skopenko <andrey@scopenco.net>
4- '''A tool create rules for Iptables that block or allow networks by country code
5- (ex: RU CN etc.) For the correct execution of script need to download geip
4+ '''A tool create rules for Iptables that block
5+ or allow networks by country code(ex: RU CN etc.).
6+ For the correct execution of script need to download geip
67database and country codes.'''
78
89import csv
1112import os .path
1213
1314IPTABLES_BIN = '/sbin/iptables'
14- MAXMIND_DB = 'http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip'
15+ MAXMIND_DB = \
16+ 'http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip'
1517COUTRY_DB = 'http://www.iso.org/iso/list-en1-semic-3.txt'
1618
19+
1720def main ():
1821 p = optparse .OptionParser (description = __doc__ ,
19- prog = "netblock" ,
20- version = "0.1" ,
21- usage = "%prog [-cc] [-c] [-i] [-p] [-d] [-a] country1 coutry2 ..." )
22+ prog = "netblock" ,
23+ version = "0.1" ,
24+ usage = "%prog [-cc] [-c] [-i] [-p]"
25+ "[-d] [-a] country1 coutry2 ..." )
2226 p .add_option ("--geoipdb" ,
23- help = 'Path to GeoIPCountryWhois.csv with GeoIP data' ,
24- default = 'GeoIPCountryWhois.csv' )
27+ help = 'Path to GeoIPCountryWhois.csv with GeoIP data' ,
28+ default = 'GeoIPCountryWhois.csv' )
2529 p .add_option ("--countrydb" ,
26- help = 'Path to country_names_and_code_elements_txt with country codes' ,
27- default = 'country_names_and_code_elements_txt' )
30+ help = 'Path to country_names_and_code_elements_txt '
31+ 'with country codes' ,
32+ default = 'country_names_and_code_elements_txt' )
2833 p .add_option ("--cc" ,
29- action = 'store_true' ,
30- help = 'List of country codes' )
34+ action = 'store_true' ,
35+ help = 'List of country codes' )
3136 p .add_option ("--chain" , "-c" ,
32- help = 'Iptables chain, default INPUT' ,
33- default = 'INPUT' )
37+ help = 'Iptables chain, default INPUT' ,
38+ default = 'INPUT' )
3439 p .add_option ("--interface" , "-i" ,
35- help = 'Iptables interface, default eth0' ,
36- default = 'eth0' )
40+ help = 'Iptables interface, default eth0' ,
41+ default = 'eth0' )
3742 p .add_option ("--protocol" , "-p" ,
38- help = 'Iptables protocol, choose from (icmp, tcp, udp, all)' ,
39- action = "store" ,
40- type = "choice" ,
41- choices = ["icmp" , "tcp" , "udp" , 'all' ])
43+ help = 'Iptables protocol, choose from (icmp, tcp, udp, all)' ,
44+ action = "store" ,
45+ type = "choice" ,
46+ choices = ["icmp" , "tcp" , "udp" , 'all' ])
4247 p .add_option ('--dport' , '-d' ,
43- help = 'Iptables destination port' )
48+ help = 'Iptables destination port' )
4449 p .add_option ("--allow_only" , "-a" ,
45- help = 'Generate iptables rules that allow only selected coutry' ,
46- action = "store_true" )
50+ help = 'Generate iptables rules that allow '
51+ 'only selected coutry' ,
52+ action = "store_true" )
4753 options , arguments = p .parse_args ()
4854
4955 # show list of country codes
5056 if options .cc :
5157 if not os .path .isfile (options .countrydb ):
52- print '%s not found! try command "wget %s"' % (options .countrydb , COUTRY_DB )
53- sys .exit ()
58+ print '%s not found! try command "wget %s"' % (
59+ options .countrydb , COUTRY_DB )
60+ sys .exit ()
5461 with open (options .countrydb ) as f :
5562 for line in f :
56- if line == "" or line .startswith ("Country " ) or ";" not in line :
63+ if line == "" or line .startswith ("Country " ) \
64+ or ";" not in line :
5765 continue
5866 c_name , c_code = line .strip ().split (";" )
59- c_name = ' ' .join ([part .capitalize () for part in \
60- c_name .split (" " )])
67+ c_name = ' ' .join ([part .capitalize () for part in
68+ c_name .split (" " )])
6169 print '%s\t %s' % (c_code , c_name )
6270 return
6371
@@ -67,8 +75,10 @@ def main():
6775 sys .exit ()
6876
6977 if not os .path .isfile (options .geoipdb ):
70- print '%s not found! try command "wget %s && unzip GeoIPCountryCSV.zip"' % (options .geoipdb , MAXMIND_DB )
71- sys .exit ()
78+ print '%s not found! try ' \
79+ 'command "wget %s && unzip GeoIPCountryCSV.zip"' % (
80+ options .geoipdb , MAXMIND_DB )
81+ sys .exit ()
7282
7383 # construct iptables rule tempate
7484 base_rule = IPTABLES_BIN
@@ -94,7 +104,8 @@ def main():
94104 while (network <= mask ):
95105 x = 0
96106 while True :
97- if network & (1 << x ) == 0 and network + ((1 << (x + 1 )) - 1 ) <= mask :
107+ if network & (1 << x ) == 0 and \
108+ network + ((1 << (x + 1 )) - 1 ) <= mask :
98109 x += 1
99110 continue
100111 print block_rule % '%s/%s' % (get_net (network ), 32 - x )
@@ -104,6 +115,7 @@ def main():
104115 if options .allow_only :
105116 print base_rule + ' -j DROP'
106117
118+
107119def get_net (network ):
108120 '''convert bin network to decimal'''
109121 out = str (network & 255 )
0 commit comments