Commit 0bd9aa5b authored by Vitaly Lipatov's avatar Vitaly Lipatov

add IPv6 support

parent f3da27cf
#!/bin/sh #!/bin/sh
setname="eterban_1" setname="eterban_1"
setname_ipv6="eterban_1_ipv6"
command="$1" command="$1"
[ -n "$command" ] && shift [ -n "$command" ] && shift
if [ "$command" = "count" ] ; then if [ "$command" = "count" ] ; then
echo "Count of banned:" echo "Count of banned:"
# TODO: some quiet to ignore headers
ipset list $setname | wc -l ipset list $setname | wc -l
ipset list $setname_ipv6 | wc -l
exit exit
fi fi
if [ "$command" = "list" ] ; then if [ "$command" = "list" ] ; then
ipset list $setname ipset list $setname
ipset list $setname_ipv6
exit exit
fi fi
...@@ -29,6 +33,7 @@ fi ...@@ -29,6 +33,7 @@ fi
if [ "$command" = "search" ] ; then if [ "$command" = "search" ] ; then
mask="$(echo "$1" | sed -e 's|\.|\\.|g')" mask="$(echo "$1" | sed -e 's|\.|\\.|g')"
ipset list $setname | grep --color "$mask" ipset list $setname | grep --color "$mask"
ipset list $setname_ipv6 | grep --color "$mask"
exit exit
fi fi
......
...@@ -7,10 +7,12 @@ import configparser ...@@ -7,10 +7,12 @@ import configparser
import os import os
import signal import signal
import socket import socket
import ipaddress
path_to_config = '/etc/eterban/settings.ini' path_to_config = '/etc/eterban/settings.ini'
path_to_eterban = '/usr/share/eterban/' path_to_eterban = '/usr/share/eterban/'
ipset_eterban_1 = 'eterban_1' ipset_eterban_1 = 'eterban_1'
ipset_eterban_1_ipv6 = 'eterban_1_ipv6'
ipset_firehol = 'firehol_level1' ipset_firehol = 'firehol_level1'
ipset_eterban_white = 'eterban_white' ipset_eterban_white = 'eterban_white'
...@@ -41,6 +43,7 @@ def parse_config (path_to_config, path_to_log): ...@@ -41,6 +43,7 @@ def parse_config (path_to_config, path_to_log):
redis_server = config.get("Settings", "redis_server", fallback = "redis_server") redis_server = config.get("Settings", "redis_server", fallback = "redis_server")
ban_server = config.get("Settings", "ban_server", fallback = "ban_server") ban_server = config.get("Settings", "ban_server", fallback = "ban_server")
ban_server_ipv6 = config.get("Settings", "ban_server_ipv6", fallback = "")
i_interface = config.get("Settings", "i_interface", fallback = "i_interface") i_interface = config.get("Settings", "i_interface", fallback = "i_interface")
i_interface2 = config.get("Settings", "i_interface2", fallback = "") i_interface2 = config.get("Settings", "i_interface2", fallback = "")
if redis_server == "redis_server" or ban_server == "ban_server" or i_interface == "i_interface": if redis_server == "redis_server" or ban_server == "ban_server" or i_interface == "i_interface":
...@@ -53,18 +56,18 @@ def parse_config (path_to_config, path_to_log): ...@@ -53,18 +56,18 @@ def parse_config (path_to_config, path_to_log):
log_file.write(info) log_file.write(info)
sys.exit() sys.exit()
else: else:
return (redis_server, ban_server, i_interface, i_interface2) return (redis_server, ban_server, ban_server_ipv6, i_interface, i_interface2)
def save_ipset_eterban_1(): def save_ipset_eterban_1():
global ipset_eterban_1, ipset_firehol, ipset_eterban_white, path_to_eterban global ipset_eterban_1, ipset_eterban_1_ipv6, ipset_firehol, ipset_eterban_white, path_to_eterban
name_list = [ipset_eterban_1, ipset_firehol, ipset_eterban_white] name_list = [ipset_eterban_1, ipset_eterban_1_ipv6, ipset_firehol, ipset_eterban_white]
for name in name_list: for name in name_list:
command = 'ipset save ' + name + ' --file ' + path_to_eterban + name command = 'ipset save ' + name + ' --file ' + path_to_eterban + name
subprocess.call (command, shell = True) subprocess.call (command, shell = True)
def restore_ipset_eterban_1(): def restore_ipset_eterban_1():
global ipset_eterban_1, ipset_firehol, ipset_eterban_white, path_to_eterban global ipset_eterban_1, ipset_eterban_1_ipv6, ipset_firehol, ipset_eterban_white, path_to_eterban
name_list = [ipset_eterban_1, ipset_firehol, ipset_eterban_white] name_list = [ipset_eterban_1, ipset_eterban_1_ipv6, ipset_firehol, ipset_eterban_white]
for name in name_list: for name in name_list:
command='ipset restore --file ' + path_to_eterban + name command='ipset restore --file ' + path_to_eterban + name
subprocess.call (command, shell = True) subprocess.call (command, shell = True)
...@@ -96,6 +99,37 @@ def create_iptables_rules(): ...@@ -96,6 +99,37 @@ def create_iptables_rules():
for command in commands: for command in commands:
subprocess.call (command, shell = True) subprocess.call (command, shell = True)
def create_ip6tables_rules():
global ban_server_ipv6, ipset_eterban_1_ipv6, i_interface, i_interface2
if not ban_server_ipv6:
return
commands=['ipset create ' + ipset_eterban_1_ipv6 + ' hash:ip family inet6 maxelem 650000',
#'ipset create ' + ipset_firehol + ' hash:net',
#'ipset create ' + ipset_eterban_white + ' hash:ip',
#'ip6tables -t nat -I PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_firehol + ' src -j DNAT --to-destination ' + ban_server,
'ip6tables -t nat -I PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j DNAT --to-destination ' + ban_server_ipv6,
#'ip6tables -t nat -I PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_white + ' src -j ACCEPT',
#'iptables -t nat -I PREROUTING -i ' + i_interface + ' -m set ! --match-set ' + ipset_eterban_1 + ' src -d ' + ban_server + ' -p tcp -m multiport --destination-port 80,443 -j DNAT --to-destination ' + ban_server + ':81',
#'iptables -t nat -I PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_1 + ' src -p tcp --dport 443 -j DNAT --to-destination ' + ban_server + ':80',
'ip6tables -I FORWARD -i ' + i_interface + ' -p tcp -m multiport ! --dport 80,443 -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j REJECT']
for command in commands:
subprocess.call (command, shell = True)
if not i_interface2:
return
commands=[
#'iptables -t nat -I PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_firehol + ' src -j DNAT --to-destination ' + ban_server,
'ip6tables -t nat -I PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j DNAT --to-destination ' + ban_server,
#'iptables -t nat -I PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_eterban_white + ' src -j ACCEPT',
#'iptables -t nat -I PREROUTING -i ' + i_interface2 + ' -m set ! --match-set ' + ipset_eterban_1 + ' src -d ' + ban_server + ' -p tcp -m multiport --destination-port 80,443 -j DNAT --to-destination ' + ban_server + ':81',
#'iptables -t nat -I PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_eterban_1 + ' src -p tcp --dport 443 -j DNAT --to-destination ' + ban_server + ':80',
'ip6tables -I FORWARD -i ' + i_interface2 + ' -p tcp -m multiport ! --dport 80,443 -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j REJECT']
for command in commands:
subprocess.call (command, shell = True)
def destroy_iptables_rules (): def destroy_iptables_rules ():
global ban_server, ipset_eterban_1, ipset_firehol, ipset_eterban_white, i_interface, i_interface2 global ban_server, ipset_eterban_1, ipset_firehol, ipset_eterban_white, i_interface, i_interface2
commands=[ commands=[
...@@ -127,9 +161,48 @@ def destroy_iptables_rules (): ...@@ -127,9 +161,48 @@ def destroy_iptables_rules ():
subprocess.call (command, shell = True) subprocess.call (command, shell = True)
#print (command) #print (command)
def destroy_ip6tables_rules ():
global ban_server_ipv6, ipset_eterban_1_ipv6, i_interface, i_interface2
if not ban_server_ipv6:
return
commands=[
#'iptables -t nat -D PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_firehol + ' src -j DNAT --to-destination ' + ban_server,
'ip6tables -t nat -D PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j DNAT --to-destination ' + ban_server_ipv6,
#'iptables -t nat -D PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_white + ' src -j ACCEPT',
#'iptables -t nat -D PREROUTING -i ' + i_interface + ' -m set ! --match-set ' + ipset_eterban_1 + ' src -d ' + ban_server + ' -p tcp -m multiport --destination-port 80,443 -j DNAT --to-destination ' + ban_server + ':81',
#'iptables -t nat -D PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_1 + ' src -p tcp --dport 443 -j DNAT --to-destination ' + ban_server + ':80',
'ip6tables -D FORWARD -i ' + i_interface + ' -p tcp -m multiport ! --dport 80,443 -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j REJECT',
'ipset destroy ' + ipset_eterban_1_ipv6,
#'ipset destroy ' + ipset_firehol,
#'ipset destroy ' + ipset_eterban_white
]
for command in commands:
subprocess.call (command, shell = True)
#print (command)
if not i_interface2:
return
commands=[
#'iptables -t nat -D PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_firehol + ' src -j DNAT --to-destination ' + ban_server,
'ip6tables -t nat -D PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j DNAT --to-destination ' + ban_server_ipv6,
#'iptables -t nat -D PREROUTING -i ' + i_interface2 + ' -m set --match-set ' + ipset_eterban_white + ' src -j ACCEPT',
#'iptables -t nat -D PREROUTING -i ' + i_interface + ' -m set ! --match-set ' + ipset_eterban_1 + ' src -d ' + ban_server + ' -p tcp -m multiport --destination-port 80,443 -j DNAT --to-destination ' + ban_server + ':81',
#'iptables -t nat -D PREROUTING -i ' + i_interface + ' -m set --match-set ' + ipset_eterban_1 + ' src -p tcp --dport 443 -j DNAT --to-destination ' + ban_server + ':80',
'ip6tables -D FORWARD -i ' + i_interface2 + ' -p tcp -m multiport ! --dport 80,443 -m set --match-set ' + ipset_eterban_1_ipv6 + ' src -j REJECT']
for command in commands:
subprocess.call (command, shell = True)
#print (command)
def exit_gracefully(signum, frame): def exit_gracefully(signum, frame):
save_ipset_eterban_1() save_ipset_eterban_1()
destroy_iptables_rules() destroy_iptables_rules()
destroy_ip6tables_rules()
print ("End of the program. I was killed with ", signum,'\n') print ("End of the program. I was killed with ", signum,'\n')
sys.exit() sys.exit()
...@@ -139,7 +212,7 @@ signal.signal(signal.SIGTERM, exit_gracefully) ...@@ -139,7 +212,7 @@ signal.signal(signal.SIGTERM, exit_gracefully)
#print ('1') #print ('1')
redis_server, ban_server, i_interface, i_interface2 = parse_config (path_to_config, path_to_log) redis_server, ban_server, ban_server_ipv6, i_interface, i_interface2 = parse_config (path_to_config, path_to_log)
#destroy_iptables_rules () #destroy_iptables_rules ()
#sys.exit() #sys.exit()
...@@ -158,28 +231,36 @@ except: ...@@ -158,28 +231,36 @@ except:
restore_ipset_eterban_1() restore_ipset_eterban_1()
create_iptables_rules() create_iptables_rules()
create_ip6tables_rules()
for message in p.listen(): for message in p.listen():
if message is not None and message['type']=='message' and message['channel'] == b'ban': if message is not None and message['type']=='message' and message['channel'] == b'ban':
ip = message['data'].decode('utf-8') ip = message['data'].decode('utf-8')
ip = message['data'].decode('utf-8') ipo = ipaddress.ip_address(ip)
if isinstance(ipo, ipaddress.IPv6Address):
ban = 'ipset -A ' + ipset_eterban_1_ipv6 + ' ' + ip
else:
ban = 'ipset -A ' + ipset_eterban_1 + ' ' + ip ban = 'ipset -A ' + ipset_eterban_1 + ' ' + ip
remove = 'ipset -D ' + ipset_eterban_white + ' ' + ip #remove = 'ipset -D ' + ipset_eterban_white + ' ' + ip
print (ban) print (ban)
print (message) print (message)
subprocess.call (ban, shell = True) subprocess.call (ban, shell = True)
subprocess.call (remove, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True) #subprocess.call (remove, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True)
tcp_drop = 'conntrack -D -s ' + ip tcp_drop = 'conntrack -D -s ' + ip
subprocess.Popen(tcp_drop, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True) subprocess.Popen(tcp_drop, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True)
elif message is not None and message['type'] =='message' and message['channel'] == b'unban' : elif message is not None and message['type'] =='message' and message['channel'] == b'unban' :
print (message) print (message)
ip = message['data'].decode('utf-8') ip = message['data'].decode('utf-8')
ipo = ipaddress.ip_address(ip)
if isinstance(ipo, ipaddress.IPv6Address):
unban = 'ipset -D ' + ipset_eterban_1_ipv6 + ' ' + ip
else:
unban = 'ipset -D ' + ipset_eterban_1 + ' ' + ip unban = 'ipset -D ' + ipset_eterban_1 + ' ' + ip
add = 'ipset -A ' + ipset_eterban_white + ' ' + ip #add = 'ipset -A ' + ipset_eterban_white + ' ' + ip
subprocess.call (unban, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True) subprocess.call (unban, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True)
subprocess.call (add, shell = True) #subprocess.call (add, shell = True)
tcp_drop = 'conntrack -D -s ' + ip tcp_drop = 'conntrack -D -s ' + ip
subprocess.Popen(tcp_drop, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True) subprocess.Popen(tcp_drop, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True)
elif message is not None and message['type'] =='message' and message['channel'] == b'by': elif message is not None and message['type'] =='message' and message['channel'] == b'by':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment