2018-11-10 10:01:45 +00:00
#!/bin/sh
# banIP - ban incoming and outgoing ip adresses/subnets via ipset
# written by Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2019-09-09 15:12:52 +00:00
# (s)hellcheck exceptions
# shellcheck disable=1091 disable=2039 disable=2143 disable=2181 disable=2188
2018-11-10 10:01:45 +00:00
# set initial defaults
#
LC_ALL = C
PATH = "/usr/sbin:/usr/bin:/sbin:/bin"
2019-09-09 15:12:52 +00:00
ban_ver = "0.2.0"
2018-11-10 10:01:45 +00:00
ban_enabled = 0
ban_automatic = "1"
2019-05-30 14:09:38 +00:00
ban_sources = ""
2018-11-10 10:01:45 +00:00
ban_iface = ""
ban_debug = 0
2019-01-05 15:28:44 +00:00
ban_backupdir = "/mnt"
2019-05-16 09:16:03 +00:00
ban_maxqueue = 4
2019-08-06 13:53:46 +00:00
ban_autoblacklist = 1
ban_autowhitelist = 1
2018-11-10 10:01:45 +00:00
ban_fetchutil = "uclient-fetch"
2018-11-16 20:06:48 +00:00
ban_ip = " $( command -v ip) "
2018-11-10 10:01:45 +00:00
ban_ipt = " $( command -v iptables) "
ban_ipt_save = " $( command -v iptables-save) "
ban_ipt_restore = " $( command -v iptables-restore) "
ban_ipt6 = " $( command -v ip6tables) "
ban_ipt6_save = " $( command -v ip6tables-save) "
ban_ipt6_restore = " $( command -v ip6tables-restore) "
ban_ipset = " $( command -v ipset) "
ban_chain = "banIP"
ban_action = " ${ 1 :- "start" } "
ban_pidfile = "/var/run/banip.pid"
ban_rtfile = "/tmp/ban_runtime.json"
2019-09-09 15:12:52 +00:00
ban_sshdaemon = "dropbear"
2018-11-10 10:01:45 +00:00
ban_setcnt = 0
ban_cnt = 0
# load environment
#
f_envload( )
{
# get system information
#
2019-09-09 15:12:52 +00:00
ban_sysver = " $( ubus -S call system board 2>/dev/null | jsonfilter -e '@.model' -e '@.release.description' | \
awk 'BEGIN{ORS=", "}{print $0}' | awk '{print substr($0,1,length($0)-2)}' ) "
2018-11-10 10:01:45 +00:00
# parse 'global' and 'extra' section by callback
#
config_cb( )
{
local type = " ${ 1 } "
if [ " ${ type } " = "banip" ]
then
option_cb( )
{
local option = " ${ 1 } "
local value = " ${ 2 } "
eval " ${ option } =\" ${ value } \" "
}
else
reset_cb
fi
}
# parse 'source' typed sections
#
parse_config( )
{
local value opt section = " ${ 1 } " options = "ban_src ban_src_6 ban_src_rset ban_src_rset_6 ban_src_settype ban_src_ruletype ban_src_on ban_src_on_6 ban_src_cat"
for opt in ${ options }
do
config_get value " ${ section } " " ${ opt } "
if [ -n " ${ value } " ]
then
eval " ${ opt } _ ${ section } =\" ${ value } \" "
if [ " ${ opt } " = "ban_src" ]
then
eval " ban_sources=\" ${ ban_sources } ${ section } \" "
elif [ " ${ opt } " = "ban_src_6" ]
then
eval " ban_sources=\" ${ ban_sources } ${ section } _6\" "
fi
fi
done
}
# load config
#
config_load banip
config_foreach parse_config source
# create temp directory & files
#
f_temp
# check status
#
2019-05-30 14:09:38 +00:00
if [ " ${ ban_enabled } " -eq 0 ]
2018-11-10 10:01:45 +00:00
then
f_jsnup disabled
f_ipset destroy
2019-01-05 15:28:44 +00:00
f_rmbackup
2018-11-10 10:01:45 +00:00
f_rmtemp
f_log "info" "banIP is currently disabled, please set ban_enabled to '1' to use this service"
exit 0
fi
}
# check environment
#
f_envcheck( )
{
2018-11-16 20:06:48 +00:00
local ssl_lib tmp
2018-11-10 10:01:45 +00:00
2019-09-09 15:12:52 +00:00
# check backup directory
#
if [ ! -d " ${ ban_backupdir } " ]
then
f_log "err" " the backup directory ' ${ ban_backupdir } ' does not exist/is not mounted yet, please create the directory or raise the 'ban_triggerdelay' to defer the banIP start "
fi
2018-11-10 10:01:45 +00:00
# check fetch utility
#
case " ${ ban_fetchutil } " in
2019-09-09 15:12:52 +00:00
"uclient-fetch" )
2018-11-10 10:01:45 +00:00
if [ -f "/lib/libustream-ssl.so" ]
then
ban_fetchparm = " ${ ban_fetchparm :- "--timeout=20 --no-check-certificate -O" } "
ssl_lib = "libustream-ssl"
fi
; ;
2019-09-09 15:12:52 +00:00
"wget" )
2018-11-10 10:01:45 +00:00
ban_fetchparm = " ${ ban_fetchparm :- "--no-cache --no-cookies --max-redirect=0 --timeout=20 --no-check-certificate -O" } "
ssl_lib = "built-in"
; ;
2019-09-09 15:12:52 +00:00
"curl" )
2018-11-10 10:01:45 +00:00
ban_fetchparm = " ${ ban_fetchparm :- "--connect-timeout 20 --insecure -o" } "
ssl_lib = "built-in"
; ;
2019-09-09 15:12:52 +00:00
"aria2c" )
2018-11-10 10:01:45 +00:00
ban_fetchparm = " ${ ban_fetchparm :- "--timeout=20 --allow-overwrite=true --auto-file-renaming=false --check-certificate=false -o" } "
ssl_lib = "built-in"
; ;
esac
ban_fetchutil = " $( command -v " ${ ban_fetchutil } " ) "
ban_fetchinfo = " ${ ban_fetchutil :- "-" } ( ${ ssl_lib :- "-" } ) "
if [ ! -x " ${ ban_fetchutil } " ] || [ -z " ${ ban_fetchutil } " ] || [ -z " ${ ban_fetchparm } " ]
then
2019-09-09 15:12:52 +00:00
f_log "err" "download utility not found, please install 'uclient-fetch' with the 'libustream-mbedtls' ssl library or the full 'wget' package"
2018-11-10 10:01:45 +00:00
fi
# get wan device and wan subnets
#
if [ " ${ ban_automatic } " = "1" ]
then
network_find_wan ban_iface
if [ -z " ${ ban_iface } " ]
then
network_find_wan6 ban_iface
fi
fi
2018-11-16 20:06:48 +00:00
for iface in ${ ban_iface }
do
2018-12-26 20:52:26 +00:00
network_get_device tmp " ${ iface } "
2018-11-16 20:06:48 +00:00
if [ -n " ${ tmp } " ]
then
ban_dev = " ${ ban_dev } ${ tmp } "
2018-12-26 20:52:26 +00:00
else
network_get_physdev tmp " ${ iface } "
if [ -n " ${ tmp } " ]
then
ban_dev = " ${ ban_dev } ${ tmp } "
fi
2018-11-16 20:06:48 +00:00
fi
network_get_subnets tmp " ${ iface } "
if [ -n " ${ tmp } " ]
then
ban_subnets = " ${ ban_subnets } ${ tmp } "
fi
network_get_subnets6 tmp " ${ iface } "
if [ -n " ${ tmp } " ]
then
ban_subnets6 = " ${ ban_subnets6 } ${ tmp } "
fi
done
2018-11-10 10:01:45 +00:00
if [ -z " ${ ban_iface } " ] || [ -z " ${ ban_dev } " ]
then
2018-11-16 20:06:48 +00:00
f_log "err" " wan interface(s)/device(s) ( ${ ban_iface :- "-" } / ${ ban_dev :- "-" } ) not found, please please check your configuration "
2018-11-10 10:01:45 +00:00
fi
2018-11-16 20:06:48 +00:00
ban_dev_all = " $( ${ ban_ip } link show | awk 'BEGIN{FS="[@: ]"}/^[0-9:]/{if(($3!="lo")&&($3!="br-lan")){print $3}}' ) "
2018-11-10 10:01:45 +00:00
uci_set banip global ban_iface " ${ ban_iface } "
uci_commit banip
f_jsnup "running"
f_log "info" " start banIP processing ( ${ ban_action } ) "
}
# create temporary files and directories
#
f_temp( )
{
2019-09-09 15:12:52 +00:00
if [ -d "/tmp" ] && [ -z " ${ ban_tmpdir } " ]
2018-11-10 10:01:45 +00:00
then
ban_tmpdir = " $( mktemp -p /tmp -d) "
2019-05-30 14:09:38 +00:00
ban_tmpload = " $( mktemp -p " ${ ban_tmpdir } " -tu) "
ban_tmpfile = " $( mktemp -p " ${ ban_tmpdir } " -tu) "
2019-09-09 15:12:52 +00:00
elif [ ! -d "/tmp" ]
then
f_log "err" "the temp directory '/tmp' does not exist/is not mounted yet, please create the directory or raise the 'ban_triggerdelay' to defer the banIP start"
2018-11-10 10:01:45 +00:00
fi
if [ ! -s " ${ ban_pidfile } " ]
then
2019-09-09 15:12:52 +00:00
printf "%s" " ${ $} " > " ${ ban_pidfile } "
2018-11-10 10:01:45 +00:00
fi
}
# remove temporary files and directories
#
f_rmtemp( )
{
if [ -d " ${ ban_tmpdir } " ]
then
rm -rf " ${ ban_tmpdir } "
fi
> " ${ ban_pidfile } "
}
2019-01-05 15:28:44 +00:00
# remove backup files
#
f_rmbackup( )
{
if [ -d " ${ ban_backupdir } " ]
then
2019-05-30 14:09:38 +00:00
rm -f " ${ ban_backupdir } " /banIP.*.gz
2019-01-05 15:28:44 +00:00
fi
}
2018-11-10 10:01:45 +00:00
# iptables rules engine
#
f_iptrule( )
{
local rc timeout = "-w 5" action = " ${ 1 } " rule = " ${ 2 } "
if [ " ${ src_name ##*_ } " = "6" ]
then
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt6 } " ]
2018-11-10 10:01:45 +00:00
then
2019-09-09 15:12:52 +00:00
rc = " $( " ${ ban_ipt6 } " " ${ timeout } " -C ${ rule } 2>/dev/null; printf "%u" ${ ? } ) "
2019-05-27 04:19:01 +00:00
2019-05-30 14:09:38 +00:00
if { [ " ${ rc } " -ne 0 ] && { [ " ${ action } " = "-A" ] || [ " ${ action } " = "-I" ] ; } } || \
{ [ " ${ rc } " -eq 0 ] && [ " ${ action } " = "-D" ] ; }
2019-05-27 04:19:01 +00:00
then
" ${ ban_ipt6 } " " ${ timeout } " " ${ action } " ${ rule }
fi
2018-11-10 10:01:45 +00:00
fi
else
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt } " ]
2018-11-10 10:01:45 +00:00
then
2019-09-09 15:12:52 +00:00
rc = " $( " ${ ban_ipt } " " ${ timeout } " -C ${ rule } 2>/dev/null; printf "%u" ${ ? } ) "
2019-05-27 04:19:01 +00:00
2019-05-30 14:09:38 +00:00
if { [ " ${ rc } " -ne 0 ] && { [ " ${ action } " = "-A" ] || [ " ${ action } " = "-I" ] ; } } || \
{ [ " ${ rc } " -eq 0 ] && [ " ${ action } " = "-D" ] ; }
2019-05-27 04:19:01 +00:00
then
" ${ ban_ipt } " " ${ timeout } " " ${ action } " ${ rule }
fi
2018-11-10 10:01:45 +00:00
fi
fi
}
# remove/add iptables rules
#
f_iptadd( )
{
2018-11-16 20:06:48 +00:00
local rm = " ${ 1 } " dev
2018-11-10 10:01:45 +00:00
2018-11-16 20:06:48 +00:00
for dev in ${ ban_dev_all }
do
f_iptrule "-D" " ${ ban_chain } -i ${ dev } -m conntrack --ctstate NEW -m set --match-set ${ src_name } src -j ${ target_src } "
f_iptrule "-D" " ${ ban_chain } -o ${ dev } -m conntrack --ctstate NEW -m set --match-set ${ src_name } dst -j ${ target_dst } "
done
2018-11-10 10:01:45 +00:00
2019-05-30 14:09:38 +00:00
if [ -z " ${ rm } " ] && [ " ${ cnt } " -gt 0 ]
2018-11-10 10:01:45 +00:00
then
if [ " ${ src_ruletype } " != "dst" ]
then
if [ " ${ src_name ##*_ } " = "6" ]
then
# dummy, special IPv6 rules
/bin/true
else
f_iptrule "-I" " ${ wan_input } -p udp --dport 67:68 --sport 67:68 -j RETURN "
fi
f_iptrule "-A" " ${ wan_input } -j ${ ban_chain } "
f_iptrule "-A" " ${ wan_forward } -j ${ ban_chain } "
2018-11-16 20:06:48 +00:00
for dev in ${ ban_dev }
do
f_iptrule " ${ action :- "-A" } " " ${ ban_chain } -i ${ dev } -m conntrack --ctstate NEW -m set --match-set ${ src_name } src -j ${ target_src } "
done
2018-11-10 10:01:45 +00:00
fi
if [ " ${ src_ruletype } " != "src" ]
then
if [ " ${ src_name ##*_ } " = "6" ]
then
# dummy, special IPv6 rules
/bin/true
else
f_iptrule "-I" " ${ lan_input } -p udp --dport 67:68 --sport 67:68 -j RETURN "
fi
f_iptrule "-A" " ${ lan_input } -j ${ ban_chain } "
f_iptrule "-A" " ${ lan_forward } -j ${ ban_chain } "
2018-11-16 20:06:48 +00:00
for dev in ${ ban_dev }
do
f_iptrule " ${ action :- "-A" } " " ${ ban_chain } -o ${ dev } -m conntrack --ctstate NEW -m set --match-set ${ src_name } dst -j ${ target_dst } "
done
2018-11-10 10:01:45 +00:00
fi
else
2019-06-18 20:23:17 +00:00
if [ -x " ${ ban_ipset } " ] && [ -n " $( " ${ ban_ipset } " -q -n list " ${ src_name } " ) " ]
2018-11-10 10:01:45 +00:00
then
2019-06-18 20:23:17 +00:00
" ${ ban_ipset } " -q destroy " ${ src_name } "
2018-11-10 10:01:45 +00:00
fi
fi
}
# ipset/iptables actions
#
f_ipset( )
{
2019-09-09 15:12:52 +00:00
local out_rc cnt cnt_ip cnt_cidr size source action ruleset ruleset_6 rule timeout = "-w 5" mode = " ${ 1 } " in_rc = " ${ src_rc :- 0 } "
2018-11-10 10:01:45 +00:00
if [ " ${ src_name %_6* } " = "whitelist" ]
then
2019-05-30 14:09:38 +00:00
target_src = "RETURN"
target_dst = "RETURN"
2018-11-10 10:01:45 +00:00
action = "-I"
fi
case " ${ mode } " in
2019-09-09 15:12:52 +00:00
"backup" )
gzip -cf " ${ tmp_load } " 2>/dev/null > " ${ ban_backupdir } /banIP. ${ src_name } .gz "
out_rc = " ${ ? :- " ${ in_rc } " } "
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } , out_rc: ${ out_rc } "
return " ${ out_rc } "
2019-01-05 15:28:44 +00:00
; ;
2019-09-09 15:12:52 +00:00
"restore" )
if [ -f " ${ ban_backupdir } /banIP. ${ src_name } .gz " ]
2019-01-05 15:28:44 +00:00
then
2019-09-09 15:12:52 +00:00
zcat " ${ ban_backupdir } /banIP. ${ src_name } .gz " 2>/dev/null > " ${ tmp_load } "
out_rc = " ${ ? } "
2019-01-05 15:28:44 +00:00
fi
2019-09-09 15:12:52 +00:00
out_rc = " ${ out_rc :- " ${ in_rc } " } "
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } , out_rc: ${ out_rc } "
return " ${ out_rc } "
2019-01-05 15:28:44 +00:00
; ;
2019-09-09 15:12:52 +00:00
"remove" )
if [ -f " ${ ban_backupdir } /banIP. ${ src_name } .gz " ]
2019-01-05 15:28:44 +00:00
then
rm -f " ${ ban_backupdir } /banIP. ${ src_name } .gz "
2019-09-09 15:12:52 +00:00
out_rc = " ${ ? } "
2019-01-05 15:28:44 +00:00
fi
2019-09-09 15:12:52 +00:00
out_rc = " ${ out_rc :- " ${ in_rc } " } "
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } , out_rc: ${ out_rc } "
return " ${ out_rc } "
2019-01-05 15:28:44 +00:00
; ;
2019-09-09 15:12:52 +00:00
"initial" )
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt } " ] && [ -z " $( " ${ ban_ipt } " " ${ timeout } " -nL " ${ ban_chain } " 2>/dev/null) " ]
2018-11-10 10:01:45 +00:00
then
" ${ ban_ipt } " " ${ timeout } " -N " ${ ban_chain } "
2019-05-27 04:19:01 +00:00
elif [ -x " ${ ban_ipt } " ]
then
src_name = "ruleset"
ruleset = " ${ ban_wan_input_chain :- "input_wan_rule" } ${ ban_wan_forward_chain :- "forwarding_wan_rule" } ${ ban_lan_input_chain :- "input_lan_rule" } ${ ban_lan_forward_chain :- "forwarding_lan_rule" } "
for rule in ${ ruleset }
do
f_iptrule "-D" " ${ rule } -j ${ ban_chain } "
done
2018-11-10 10:01:45 +00:00
fi
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt6 } " ] && [ -z " $( " ${ ban_ipt6 } " " ${ timeout } " -nL " ${ ban_chain } " 2>/dev/null) " ]
2018-11-10 10:01:45 +00:00
then
" ${ ban_ipt6 } " " ${ timeout } " -N " ${ ban_chain } "
2019-05-27 04:19:01 +00:00
elif [ -x " ${ ban_ipt6 } " ]
then
src_name = "ruleset_6"
ruleset_6 = " ${ ban_wan_input_chain_6 :- "input_wan_rule" } ${ ban_wan_forward_chain_6 :- "forwarding_wan_rule" } ${ ban_lan_input_chain_6 :- "input_lan_rule" } ${ ban_lan_forward_chain_6 :- "forwarding_lan_rule" } "
for rule in ${ ruleset_6 }
do
f_iptrule "-D" " ${ rule } -j ${ ban_chain } "
done
2018-11-10 10:01:45 +00:00
fi
2019-05-30 14:09:38 +00:00
f_log "debug" " f_ipset ::: name: -, mode: ${ mode :- "-" } , chain: ${ ban_chain :- "-" } , ruleset: ${ ruleset :- "-" } , ruleset_6: ${ ruleset_6 :- "-" } "
2018-11-10 10:01:45 +00:00
; ;
2019-09-09 15:12:52 +00:00
"create" )
if [ -x " ${ ban_ipset } " ] && [ -z " $( " ${ ban_ipset } " -q -n list " ${ src_name } " ) " ]
then
" ${ ban_ipset } " -q create " ${ src_name } " hash:" ${ src_settype } " hashsize " ${ size } " maxelem 262144 family " ${ src_setipv } " counters
else
" ${ ban_ipset } " -q flush " ${ src_name } "
fi
if [ -s " ${ tmp_file } " ]
2018-11-10 10:01:45 +00:00
then
" ${ ban_ipset } " -! restore < " ${ tmp_file } "
2019-09-09 15:12:52 +00:00
out_rc = " ${ ? } "
" ${ ban_ipset } " -q save " ${ src_name } " > " ${ tmp_file } "
cnt = " $(( $( wc -l 2>/dev/null < " ${ tmp_file } " ) - 1 )) "
cnt_cidr = " $( grep -cF "/" " ${ tmp_file } " ) "
cnt_ip = " $(( cnt-cnt_cidr)) "
size = " $(( cnt/4)) "
printf "%s\\n" "1" > " ${ tmp_set } "
printf "%s\\n" " ${ cnt } " > " ${ tmp_cnt } "
f_iptadd
2018-11-10 10:01:45 +00:00
fi
end_ts = " $( date +%s) "
2019-09-09 15:12:52 +00:00
out_rc = " ${ out_rc :- " ${ in_rc } " } "
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } , settype: ${ src_settype :- "-" } , setipv: ${ src_setipv :- "-" } , ruletype: ${ src_ruletype :- "-" } , count(sum/ip/cidr): ${ cnt :- 0 } / ${ cnt_ip :- 0 } / ${ cnt_cidr :- 0 } , time: $(( end_ts-start_ts)) , out_rc: ${ out_rc } "
2018-11-10 10:01:45 +00:00
; ;
2019-09-09 15:12:52 +00:00
"refresh" )
2019-06-18 20:23:17 +00:00
if [ -x " ${ ban_ipset } " ] && [ -n " $( " ${ ban_ipset } " -q -n list " ${ src_name } " ) " ]
2018-11-10 10:01:45 +00:00
then
2019-06-18 20:23:17 +00:00
" ${ ban_ipset } " -q save " ${ src_name } " > " ${ tmp_file } "
2019-09-09 15:12:52 +00:00
out_rc = " ${ ? } "
2018-11-10 10:01:45 +00:00
if [ -s " ${ tmp_file } " ]
then
2019-05-30 14:09:38 +00:00
cnt = " $(( $( wc -l 2>/dev/null < " ${ tmp_file } " ) - 1 )) "
cnt_cidr = " $( grep -cF "/" " ${ tmp_file } " ) "
cnt_ip = " $(( cnt-cnt_cidr)) "
2019-09-09 15:12:52 +00:00
printf "%s\\n" "1" > " ${ tmp_set } "
printf "%s\\n" " ${ cnt } " > " ${ tmp_cnt } "
2018-11-10 10:01:45 +00:00
fi
f_iptadd
fi
end_ts = " $( date +%s) "
2019-09-09 15:12:52 +00:00
out_rc = " ${ out_rc :- " ${ in_rc } " } "
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } , count: ${ cnt :- 0 } / ${ cnt_ip :- 0 } / ${ cnt_cidr :- 0 } , time: $(( end_ts-start_ts)) , out_rc: ${ out_rc } "
return " ${ out_rc } "
2018-11-10 10:01:45 +00:00
; ;
2019-09-09 15:12:52 +00:00
"flush" )
2018-11-10 10:01:45 +00:00
f_iptadd "remove"
2019-06-18 20:23:17 +00:00
if [ -x " ${ ban_ipset } " ] && [ -n " $( " ${ ban_ipset } " -q -n list " ${ src_name } " ) " ]
2018-11-10 10:01:45 +00:00
then
2019-06-18 20:23:17 +00:00
" ${ ban_ipset } " -q flush " ${ src_name } "
" ${ ban_ipset } " -q destroy " ${ src_name } "
2018-11-10 10:01:45 +00:00
fi
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } "
; ;
2019-09-09 15:12:52 +00:00
"destroy" )
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt } " ] && [ -x " ${ ban_ipt_save } " ] && [ -x " ${ ban_ipt_restore } " ] && \
[ -n " $( " ${ ban_ipt } " " ${ timeout } " -nL " ${ ban_chain } " 2>/dev/null) " ]
2018-11-10 10:01:45 +00:00
then
" ${ ban_ipt_save } " | grep -v -- " -j ${ ban_chain } " | " ${ ban_ipt_restore } "
" ${ ban_ipt } " " ${ timeout } " -F " ${ ban_chain } "
" ${ ban_ipt } " " ${ timeout } " -X " ${ ban_chain } "
fi
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt6 } " ] && [ -x " ${ ban_ipt6_save } " ] && [ -x " ${ ban_ipt6_restore } " ] && \
[ -n " $( " ${ ban_ipt6 } " " ${ timeout } " -nL " ${ ban_chain } " 2>/dev/null) " ]
2018-11-10 10:01:45 +00:00
then
" ${ ban_ipt6_save } " | grep -v -- " -j ${ ban_chain } " | " ${ ban_ipt6_restore } "
" ${ ban_ipt6 } " " ${ timeout } " -F " ${ ban_chain } "
" ${ ban_ipt6 } " " ${ timeout } " -X " ${ ban_chain } "
fi
for source in ${ ban_sources }
do
2019-06-18 20:23:17 +00:00
if [ -x " ${ ban_ipset } " ] && [ -n " $( " ${ ban_ipset } " -q -n list " ${ source } " ) " ]
2018-11-10 10:01:45 +00:00
then
2019-06-18 20:23:17 +00:00
" ${ ban_ipset } " -q destroy " ${ source } "
2018-11-10 10:01:45 +00:00
fi
done
f_log "debug" " f_ipset ::: name: ${ src_name :- "-" } , mode: ${ mode :- "-" } "
; ;
esac
}
# write to syslog
#
f_log( )
{
local class = " ${ 1 } " log_msg = " ${ 2 } "
2019-05-30 14:09:38 +00:00
if [ -n " ${ log_msg } " ] && { [ " ${ class } " != "debug" ] || [ " ${ ban_debug } " -eq 1 ] ; }
2018-11-10 10:01:45 +00:00
then
logger -p " ${ class } " -t " banIP-[ ${ ban_ver } ] " " ${ log_msg } "
if [ " ${ class } " = "err" ]
then
f_jsnup error
f_ipset destroy
2019-01-05 15:28:44 +00:00
f_rmbackup
2018-11-10 10:01:45 +00:00
f_rmtemp
logger -p " ${ class } " -t " banIP-[ ${ ban_ver } ] " "Please also check 'https://github.com/openwrt/packages/blob/master/net/banip/files/README.md'"
exit 1
fi
fi
}
# main function for banIP processing
#
f_main( )
{
2019-05-27 04:19:01 +00:00
local pid pid_list start_ts end_ts ip tmp_raw tmp_cnt tmp_load tmp_file mem_total mem_free cnt = 1
2019-09-09 15:12:52 +00:00
local src_name src_on src_url src_rset src_setipv src_settype src_ruletype src_cat src_log src_addon src_rc
2019-05-27 04:19:01 +00:00
local wan_input wan_forward lan_input lan_forward target_src target_dst log_content
2018-11-10 10:01:45 +00:00
2019-09-09 15:12:52 +00:00
log_content = " $( logread -e " ${ ban_sshdaemon } " ) "
2018-11-10 10:01:45 +00:00
mem_total = " $( awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null) "
mem_free = " $( awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null) "
2019-09-09 15:12:52 +00:00
f_log "debug" " f_main ::: fetch_util: ${ ban_fetchinfo :- "-" } , fetch_parm: ${ ban_fetchparm :- "-" } , ssh_daemon: ${ ban_sshdaemon } , interface(s): ${ ban_iface :- "-" } , device(s): ${ ban_dev :- "-" } , all_devices: ${ ban_dev_all :- "-" } , backup_dir: ${ ban_backupdir :- "-" } , mem_total: ${ mem_total :- 0 } , mem_free: ${ mem_free :- 0 } , max_queue: ${ ban_maxqueue } "
2018-11-10 10:01:45 +00:00
f_ipset initial
# main loop
#
for src_name in ${ ban_sources }
do
2019-05-27 04:19:01 +00:00
unset src_on
2018-11-10 10:01:45 +00:00
if [ " ${ src_name ##*_ } " = "6" ]
then
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt6 } " ]
then
2019-09-09 15:12:52 +00:00
src_on = " $( eval printf "%s" \" \$ \{ ban_src_on_6_${ src_name %_6* } \} \" ) "
src_url = " $( eval printf "%s" \" \$ \{ ban_src_6_${ src_name %_6* } \} \" ) "
src_rset = " $( eval printf "%s" \" \$ \{ ban_src_rset_6_${ src_name %_6* } \} \" ) "
2019-05-27 04:19:01 +00:00
src_setipv = "inet6"
wan_input = " ${ ban_wan_input_chain_6 :- "input_wan_rule" } "
wan_forward = " ${ ban_wan_forward_chain_6 :- "forwarding_wan_rule" } "
lan_input = " ${ ban_lan_input_chain_6 :- "input_lan_rule" } "
lan_forward = " ${ ban_lan_forward_chain_6 :- "forwarding_lan_rule" } "
target_src = " ${ ban_target_src_6 :- "DROP" } "
target_dst = " ${ ban_target_dst_6 :- "REJECT" } "
fi
2018-11-10 10:01:45 +00:00
else
2019-05-27 04:19:01 +00:00
if [ -x " ${ ban_ipt } " ]
then
2019-09-09 15:12:52 +00:00
src_on = " $( eval printf "%s" \" \$ \{ ban_src_on_${ src_name } \} \" ) "
src_url = " $( eval printf "%s" \" \$ \{ ban_src_${ src_name } \} \" ) "
src_rset = " $( eval printf "%s" \" \$ \{ ban_src_rset_${ src_name } \} \" ) "
2019-05-27 04:19:01 +00:00
src_setipv = "inet"
wan_input = " ${ ban_wan_input_chain :- "input_wan_rule" } "
wan_forward = " ${ ban_wan_forward_chain :- "forwarding_wan_rule" } "
lan_input = " ${ ban_lan_input_chain :- "input_lan_rule" } "
lan_forward = " ${ ban_lan_forward_chain :- "forwarding_lan_rule" } "
target_src = " ${ ban_target_src :- "DROP" } "
target_dst = " ${ ban_target_dst :- "REJECT" } "
fi
2018-11-10 10:01:45 +00:00
fi
2019-09-09 15:12:52 +00:00
src_settype = " $( eval printf "%s" \" \$ \{ ban_src_settype_${ src_name %_6* } \} \" ) "
src_ruletype = " $( eval printf "%s" \" \$ \{ ban_src_ruletype_${ src_name %_6* } \} \" ) "
src_cat = " $( eval printf "%s" \" \$ \{ ban_src_cat_${ src_name %_6* } \} \" ) "
2018-11-10 10:01:45 +00:00
src_addon = ""
2019-09-09 15:12:52 +00:00
src_rc = 4
2018-11-10 10:01:45 +00:00
tmp_load = " ${ ban_tmpload } . ${ src_name } "
tmp_file = " ${ ban_tmpfile } . ${ src_name } "
tmp_raw = " ${ tmp_load } .raw "
tmp_cnt = " ${ tmp_file } .cnt "
tmp_set = " ${ tmp_file } .setcnt "
# basic pre-checks
#
f_log "debug" " f_main ::: name: ${ src_name } , src_on: ${ src_on :- "-" } "
2019-05-27 04:19:01 +00:00
if [ -z " ${ src_on } " ] || [ " ${ src_on } " != "1" ] || [ -z " ${ src_url } " ] || \
[ -z " ${ src_rset } " ] || [ -z " ${ src_settype } " ] || [ -z " ${ src_ruletype } " ]
2018-11-10 10:01:45 +00:00
then
f_ipset flush
2019-01-05 15:28:44 +00:00
f_ipset remove
2018-11-10 10:01:45 +00:00
continue
2019-09-09 15:12:52 +00:00
elif [ " ${ ban_action } " = "refresh" ] && [ ! -f " ${ src_url } " ]
2018-11-16 20:06:48 +00:00
then
2019-06-18 20:23:17 +00:00
start_ts = " $( date +%s) "
2018-11-16 20:06:48 +00:00
f_ipset refresh
2019-09-09 15:12:52 +00:00
if [ " ${ ? } " -eq 0 ]
2019-06-18 20:23:17 +00:00
then
continue
fi
2018-11-10 10:01:45 +00:00
fi
# download queue processing
#
(
start_ts = " $( date +%s) "
2019-09-09 15:12:52 +00:00
if [ ! -f " ${ src_url } " ] && [ " ${ ban_action } " = "start" ]
2018-11-10 10:01:45 +00:00
then
2019-01-05 15:28:44 +00:00
f_ipset restore
fi
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
if [ " ${ src_rc } " -ne 0 ] || [ ! -s " ${ tmp_load } " ]
2018-11-10 10:01:45 +00:00
then
2019-01-05 15:28:44 +00:00
if [ -f " ${ src_url } " ]
2018-11-10 10:01:45 +00:00
then
2019-01-05 15:28:44 +00:00
src_log = " $( cat " ${ src_url } " 2>/dev/null > " ${ tmp_load } " ) "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
2019-01-05 15:28:44 +00:00
case " ${ src_name } " in
2019-09-09 15:12:52 +00:00
"whitelist" )
2019-01-05 15:28:44 +00:00
src_addon = " ${ ban_subnets } "
; ;
2019-09-09 15:12:52 +00:00
"whitelist_6" )
2019-01-05 15:28:44 +00:00
src_addon = " ${ ban_subnets6 } "
; ;
2019-09-09 15:12:52 +00:00
"blacklist" )
if [ " ${ ban_sshdaemon } " = "dropbear" ]
then
pid_list = " $( printf "%s\\n" " ${ log_content } " | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}' ) "
for pid in ${ pid_list }
do
src_addon = " ${ src_addon } $( printf "%s\\n" " ${ log_content } " | grep -F " ${ pid } " | awk 'match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}/){ORS=" ";print substr($0,RSTART,RLENGTH)}' ) "
done
elif [ " ${ ban_sshdaemon } " = "sshd" ]
then
src_addon = " $( printf "%s\\n" " ${ log_content } " | grep -E " [0-9]+ \[preauth\] $" | awk 'match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}/){ORS=" ";print substr($0,RSTART,RLENGTH)}' ) "
fi
2019-01-05 15:28:44 +00:00
; ;
2019-09-09 15:12:52 +00:00
"blacklist_6" )
if [ " ${ ban_sshdaemon } " = "dropbear" ]
then
pid_list = " $( printf "%s\\n" " ${ log_content } " | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}' ) "
for pid in ${ pid_list }
do
src_addon = " ${ src_addon } $( printf "%s\\n" " ${ log_content } " | grep -F " ${ pid } " | awk 'match($0,/([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}/){ORS=" ";print substr($0,RSTART,RLENGTH)}' ) "
done
elif [ " ${ ban_sshdaemon } " = "sshd" ]
then
src_addon = " $( printf "%s\\n" " ${ log_content } " | grep -E " [0-9]+ \[preauth\] $" | awk 'match($0,/([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}/){ORS=" ";print substr($0,RSTART,RLENGTH)}' ) "
fi
2019-01-05 15:28:44 +00:00
; ;
esac
for ip in ${ src_addon }
2018-11-10 10:01:45 +00:00
do
2019-01-05 15:28:44 +00:00
if [ -z " $( grep -F " ${ ip } " " ${ src_url } " ) " ]
2018-11-10 10:01:45 +00:00
then
2019-09-09 15:12:52 +00:00
printf "%s\\n" " ${ ip } " >> " ${ tmp_load } "
2019-08-06 13:53:46 +00:00
if { [ " ${ src_name //_*/ } " = "blacklist" ] && [ " ${ ban_autoblacklist } " -eq 1 ] ; } || \
{ [ " ${ src_name //_*/ } " = "whitelist" ] && [ " ${ ban_autowhitelist } " -eq 1 ] ; }
then
2019-09-09 15:12:52 +00:00
printf "%s\\n" " ${ ip } " >> " ${ src_url } "
2019-08-06 13:53:46 +00:00
fi
2018-11-10 10:01:45 +00:00
fi
done
2019-01-05 15:28:44 +00:00
elif [ -n " ${ src_cat } " ]
then
if [ " ${ src_cat //[0-9]/ } " != " ${ src_cat } " ]
then
for as in ${ src_cat }
do
src_log = " $( " ${ ban_fetchutil } " ${ ban_fetchparm } " ${ tmp_raw } " " ${ src_url } AS ${ as } " 2>& 1) "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
if [ " ${ src_rc } " -eq 0 ]
2019-01-05 15:28:44 +00:00
then
jsonfilter -i " ${ tmp_raw } " -e '@.data.prefixes.*.prefix' 2>/dev/null >> " ${ tmp_load } "
else
break
fi
done
2019-09-09 15:12:52 +00:00
if [ " ${ src_rc } " -eq 0 ]
2019-01-05 15:28:44 +00:00
then
f_ipset backup
2019-09-09 15:12:52 +00:00
elif [ " ${ ban_action } " != "start" ]
2018-11-10 10:01:45 +00:00
then
2019-01-05 15:28:44 +00:00
f_ipset restore
fi
else
for co in ${ src_cat }
do
src_log = " $( " ${ ban_fetchutil } " ${ ban_fetchparm } " ${ tmp_raw } " " ${ src_url } ${ co } &v4_format=prefix " 2>& 1) "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
if [ " ${ src_rc } " -eq 0 ]
2018-11-10 10:01:45 +00:00
then
2019-01-05 15:28:44 +00:00
if [ " ${ src_name ##*_ } " = "6" ]
then
jsonfilter -i " ${ tmp_raw } " -e '@.data.resources.ipv6.*' 2>/dev/null >> " ${ tmp_load } "
else
jsonfilter -i " ${ tmp_raw } " -e '@.data.resources.ipv4.*' 2>/dev/null >> " ${ tmp_load } "
fi
2018-11-10 10:01:45 +00:00
else
2019-01-05 15:28:44 +00:00
break
2018-11-10 10:01:45 +00:00
fi
2019-01-05 15:28:44 +00:00
done
2019-09-09 15:12:52 +00:00
if [ " ${ src_rc } " -eq 0 ]
2019-01-05 15:28:44 +00:00
then
f_ipset backup
2019-09-09 15:12:52 +00:00
elif [ " ${ ban_action } " != "start" ]
2019-01-05 15:28:44 +00:00
then
f_ipset restore
2018-11-10 10:01:45 +00:00
fi
2019-01-05 15:28:44 +00:00
fi
else
src_log = " $( " ${ ban_fetchutil } " ${ ban_fetchparm } " ${ tmp_raw } " " ${ src_url } " 2>& 1) "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
if [ " ${ src_rc } " -eq 0 ]
2018-11-10 10:01:45 +00:00
then
2019-01-05 15:28:44 +00:00
zcat " ${ tmp_raw } " 2>/dev/null > " ${ tmp_load } "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
if [ " ${ src_rc } " -ne 0 ]
2019-01-05 15:28:44 +00:00
then
mv -f " ${ tmp_raw } " " ${ tmp_load } "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
2019-01-05 15:28:44 +00:00
fi
2019-09-09 15:12:52 +00:00
if [ " ${ src_rc } " -eq 0 ]
2019-01-05 15:28:44 +00:00
then
f_ipset backup
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
2019-01-05 15:28:44 +00:00
fi
2019-09-09 15:12:52 +00:00
elif [ " ${ ban_action } " != "start" ]
2019-01-05 15:28:44 +00:00
then
f_ipset restore
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
2018-11-10 10:01:45 +00:00
fi
fi
fi
2019-01-05 15:28:44 +00:00
2019-09-09 15:12:52 +00:00
if [ " ${ src_rc } " -eq 0 ]
2018-11-10 10:01:45 +00:00
then
2019-05-16 09:16:03 +00:00
awk " ${ src_rset } " " ${ tmp_load } " 2>/dev/null > " ${ tmp_file } "
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
if [ " ${ src_rc } " -eq 0 ]
2018-11-10 10:01:45 +00:00
then
f_ipset create
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
elif [ " ${ ban_action } " != "refresh" ]
then
2018-11-10 10:01:45 +00:00
f_ipset refresh
2019-09-09 15:12:52 +00:00
src_rc = " ${ ? } "
2018-11-10 10:01:45 +00:00
fi
else
2019-09-09 15:12:52 +00:00
src_log = " $( printf "%s" " ${ src_log } " | awk '{ORS=" ";print $0}' ) "
if [ " ${ ban_action } " != "refresh" ]
then
f_ipset refresh
src_rc = " ${ ? } "
fi
f_log "debug" " f_main ::: name: ${ src_name } , url: ${ src_url } , rc: ${ src_rc } , log: ${ src_log :- "-" } "
2018-11-10 10:01:45 +00:00
fi
2019-09-09 15:12:52 +00:00
) &
2019-05-30 14:09:38 +00:00
hold = " $(( cnt%ban_maxqueue)) "
if [ " ${ hold } " -eq 0 ]
2018-11-10 10:01:45 +00:00
then
wait
fi
2019-05-30 14:09:38 +00:00
cnt = " $(( cnt+1)) "
2018-11-10 10:01:45 +00:00
done
wait
2019-09-09 15:12:52 +00:00
for cnt in $( cat " ${ ban_tmpfile } " .*.setcnt 2>/dev/null)
do
ban_setcnt = " $(( ban_setcnt+cnt)) "
done
for cnt in $( cat " ${ ban_tmpfile } " .*.cnt 2>/dev/null)
do
ban_cnt = " $(( ban_cnt+cnt)) "
done
f_log "info" " ${ ban_setcnt } IPSets with overall ${ ban_cnt } IPs/Prefixes loaded successfully ( ${ ban_sysver } ) "
2018-11-10 10:01:45 +00:00
f_jsnup
f_rmtemp
}
# update runtime information
#
f_jsnup( )
{
2019-09-09 15:12:52 +00:00
local rundate status = " ${ 1 :- "enabled" } "
2018-11-10 10:01:45 +00:00
2019-05-27 04:19:01 +00:00
rundate = " $( /bin/date "+%d.%m.%Y %H:%M:%S" ) "
2018-11-10 10:01:45 +00:00
ban_cntinfo = " ${ ban_setcnt } IPSets with overall ${ ban_cnt } IPs/Prefixes "
2019-01-05 15:28:44 +00:00
> " ${ ban_rtfile } "
json_load_file " ${ ban_rtfile } " >/dev/null 2>& 1
json_init
json_add_object "data"
2018-11-10 10:01:45 +00:00
json_add_string "status" " ${ status } "
json_add_string "version" " ${ ban_ver } "
json_add_string "fetch_info" " ${ ban_fetchinfo :- "-" } "
2019-09-09 15:12:52 +00:00
json_add_string "ipset_info" " ${ ban_cntinfo :- "-" } "
json_add_string "backup_dir" " ${ ban_backupdir } "
2018-11-10 10:01:45 +00:00
json_add_string "last_run" " ${ rundate :- "-" } "
json_add_string "system" " ${ ban_sysver } "
2019-01-05 15:28:44 +00:00
json_close_object
2018-11-10 10:01:45 +00:00
json_dump > " ${ ban_rtfile } "
f_log "debug" " f_jsnup ::: status: ${ status } , setcnt: ${ ban_setcnt } , cnt: ${ ban_cnt } "
}
# source required system libraries
#
if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
then
. "/lib/functions.sh"
. "/lib/functions/network.sh"
. "/usr/share/libubox/jshn.sh"
else
f_log "err" "system libraries not found"
fi
# handle different banIP actions
#
f_envload
case " ${ ban_action } " in
2019-09-09 15:12:52 +00:00
"stop" )
2018-11-10 10:01:45 +00:00
f_jsnup stopped
f_ipset destroy
2019-01-05 15:28:44 +00:00
f_rmbackup
2018-11-10 10:01:45 +00:00
f_rmtemp
; ;
2019-09-09 15:12:52 +00:00
"start" | "restart" | "reload" | "refresh" )
2018-11-10 10:01:45 +00:00
f_envcheck
f_main
; ;
esac