mir3c/squashfs-root/usr/sbin/sysapi.firewall

523 lines
14 KiB
Bash
Executable File

#!/bin/sh
#
#execute by /lib/firewall.sysapi.loader when system firewall start/reload
#
#TODO: hack fw3 to support create custom chain and target to chain
#
#TODO: hack fw3 to using -m u32
#
#TODO: change all rules in uci and fw3 reload
#
#TODO: make macfilter rules stable
#
. /lib/lib.scripthelper.sh
#
. /lib/functions.sh
export ctlop="$1"
export addop="$2"
export exitcode=0
if [ -z "$ctlop" ]
then
elog "WARNING: Usage: $0 <index> [add args]"
exit 1
fi
errcount(){
local errcode="$1"
test -z "$errcode" && return 0
test "$errcode" -ne 0 && let exitcode=$exitcode+1
return 0
}
proclock(){
local needlan
needlan="$1"
LANIPMASK="$(getlanipmask)"
if [ "$needlan" = 'needlan' -a -z "$LANIPMASK" ]
then
dlog "INFO: bypass for lan ip/netmask no exist."
exit 0
fi
#
dlog "INFO: LANIPMASK: $LANIPMASK"
#
checkproclock 30 replaceproc
#check lock, return 0 for no locked, 1 for locked
if [ $? -ne 0 ]
then
elog "ERROR: executing $ALLARGS exited, waiting for proc lock failed after 30 seconds, current locked pid: $(getlockedprocpid)"
exit 1
fi
setproclock
}
#prepare_doit(){
# #delegate_postrouting of mangle for landownloadtraffic
# iptnewchain "-N delegate_postrouting -t mangle"
# errcount $?
# iptables -L POSTROUTING -t mangle --line-numbers 2>/dev/null | grep '1 ' | grep -q 'delegate_postrouting'
# if [ $? -eq 0 ]
# then
# return 0
# fi
# iptremoverule "-D POSTROUTING -t mangle -j delegate_postrouting"
# iptexec "iptables -I POSTROUTING -t mangle -j delegate_postrouting"
# errcount $?
#}
webinitrdr_disable(){
local force="$1"
local initMark="$(uci get xiaoqiang.common.INITTED 2>/dev/null)"
if [ "$initMark" != 'YES' -o "$force" = 'force' ]
then
touch /etc/config/xiaoqiang 2>/dev/null
errcount $?
uci set xiaoqiang.common='core' && uci set xiaoqiang.common.INITTED='YES' && uci commit xiaoqiang
errcount $?
if [ "$initMark" = 'YES' -a "$force" = 'force' ]
then
dlog "INFO: force remove redirect rules and restart services."
else
dlog "INFO: remove redirect rules and restart services."
fi
iptremoverule "-D $HTTPRDR_RULE"
iptremoverule "-D $DNSRDR_RULE"
test -x /etc/init.d/dnsmasq && dlog "INFO: restart dnsmasq for webinitrdr." && /etc/init.d/dnsmasq restart &
else
dlog "INFO: disable skipped for already initialed."
fi
sync 2>/dev/null
return 0
}
webinitrdr_doit(){
#
#if [ "$(nvram get model 2>/dev/null)" = "R1CM" ];then
# dlog "INFO: R1CM platform ,disable webinitrdr."
# return 0
#fi
NGINXWEBINITPORT=8098
DNSWEBINITPORT=53
#
HTTPRDR_RULE="prerouting_lan_rule -t nat -p tcp --dport 80 -m comment --comment HTTPWEBINITRDR -j REDIRECT --to-ports $NGINXWEBINITPORT"
DNSRDR_RULE="prerouting_lan_rule -t nat -p udp --dport 53 -m comment --comment DNSWEBINITRDR -j REDIRECT --to-ports $DNSWEBINITPORT"
#
test -z "$addop" && addop='on'
if [ "$addop" = 'off' -o "$addop" = 'stop' ]
then
#
proclock
#
webinitrdr_disable force
dlog "INFO: webinitrdr manual disabled."
return 0
fi
#
proclock needlan
DEVINITMARK="$(uci get xiaoqiang.common.INITTED 2>/dev/null)"
if [ "$DEVINITMARK" = 'YES' ]
then
dlog "INFO: webinitrdr bypass for device already initialed."
webinitrdr_disable
return 0
fi
local is_webinit=$(uci -q get misc.firewall.webinit)
is_webinit="${is_webinit:-1}"
# boot_status no ready
if [ $is_webinit == '0' ]; then
#NGINXWEBINITPORT=80
webinitrdr_disable
if [ "$DEVINITMARK" != 'YES' ]
then
dlog "INFO: webinitrdr disabled for squash system."
return $?
else
dlog "INFO: device already initialed for squash system."
return 0
fi
fi
#
#rdr on
#
if [ "$INTERFACE" != "lan" -a -n "$INTERFACE" -a -n "$DEVICE" -a -n "$ACTION" ] ;then
dlog "INFO: skip webinitrdr for interface ${INTERFACE}."
return 0
fi
dlog "INFO: try to insert redirect rules and restart services."
iptables -L prerouting_lan_rule -t nat 2>/dev/null | grep -qi 'HTTPWEBINITRDR'
webrdrok=$?
iptables -L prerouting_lan_rule -t nat 2>/dev/null| grep -qi 'DNSWEBINITRDR'
dnsrdrok=$?
if [ $webrdrok -ne 0 -o $dnsrdrok -ne 0 ]
then
test $webrdrok -ne 0 && iptexec "iptables -A $HTTPRDR_RULE"
test $dnsrdrok -ne 0 && iptexec "iptables -A $DNSRDR_RULE"
iptables -L prerouting_lan_rule -t nat 2>/dev/null| grep -qi 'HTTPWEBINITRDR'
webrdrok=$?
if [ $webrdrok -ne 0 ]
then
dlog "WARNING: preload catch all web init redirect on failed, miss HTTPWEBINITRDR rules."
fi
iptables -L prerouting_lan_rule -t nat 2>/dev/null| grep -qi 'DNSWEBINITRDR'
dnsrdrok=$?
if [ $dnsrdrok -ne 0 ]
then
dlog "WARNING: preload catch all dns init redirect on failed, miss DNSWEBINITRDR rules."
fi
if [ $webrdrok -eq 0 -a $dnsrdrok -eq 0 ]
then
dlog "INFO: web init redirect switch to on."
test -x /usr/sbin/preload.monitor && dlog "INFO: restart preload.monitor for webinitrdr." && /usr/sbin/preload.monitor restart &
test -x /etc/init.d/dnsmasq && dlog "INFO: restart dnsmasq for webinitrdr." && /etc/init.d/dnsmasq restart &
else
dlog "ERROR: web init redirect switch to on failed."
errcount $?
fi
else
dlog "INFO: redirect rules already exist, nothing to do."
fi
return $errcount
}
dnsmiwifi_doit(){
#
proclock needlan
#
#U32 match dns query www.miwifi.com/miwifi.com
#
#www.miwifi.com
if [ "$INTERFACE" != "lan" -a -n "$INTERFACE" -a -n "$DEVICE" -a -n "$ACTION" ] ;then
dlog "INFO: skip dnsmiwifi for interface ${INTERFACE}."
return 0
fi
iptremoverule -D prerouting_lan_rule -t nat -p udp --dport 53 -m u32 --u32 "0>>22&0x3C@20&0xFFDFDFDF=0x03575757&&0>>22&0x3C@24&0xFFDFDFDF=0x064d4957&&0>>22&0x3C@28&0xDFDFDFFF=0x49464903&&0>>22&0x3C@32&0xDFDFDF00=0x434f4d00" -j REDIRECT --to-port 53
iptables -A prerouting_lan_rule -t nat -p udp --dport 53 -m u32 --u32 "0>>22&0x3C@20&0xFFDFDFDF=0x03575757&&0>>22&0x3C@24&0xFFDFDFDF=0x064d4957&&0>>22&0x3C@28&0xDFDFDFFF=0x49464903&&0>>22&0x3C@32&0xDFDFDF00=0x434f4d00" -j REDIRECT --to-port 53
errcount $?
#miwifi.com
iptremoverule -D prerouting_lan_rule -t nat -p udp --dport 53 -m u32 --u32 "0>>22&0x3C@20&0xFFDFDFDF=0x064d4957&&0>>22&0x3C@24&0xDFDFDFFF=0x49464903&&0>>22&0x3C@28&0xDFDFDF00=0x434f4d00" -j REDIRECT --to-port 53
iptables -A prerouting_lan_rule -t nat -p udp --dport 53 -m u32 --u32 "0>>22&0x3C@20&0xFFDFDFDF=0x064d4957&&0>>22&0x3C@24&0xDFDFDFFF=0x49464903&&0>>22&0x3C@28&0xDFDFDF00=0x434f4d00" -j REDIRECT --to-port 53
errcount $?
#
return 0
}
iptaccount_doit(){
#
proclock needlan
#
if [ "$INTERFACE" != "lan" -a -n "$INTERFACE" -a -n "$DEVICE" -a -n "$ACTION" ] ;then
dlog "INFO: skip iptacount for interface ${INTERFACE}."
return 0
fi
iptables -L POSTROUTING -t mangle --line-numbers 2>/dev/null | grep -q 'landownloadtraffic'
test $? -eq 0 && iptremoverule "-D POSTROUTING -t mangle -o br-lan -j landownloadtraffic"
iptables -L fwmark -t mangle --line-numbers 2>/dev/null | grep -q 'lanuploadtraffic'
test $? -eq 0 && iptremoverule "-D fwmark -t mangle -i br-lan -j lanuploadtraffic"
iptremoverule "-F landownloadtraffic -t mangle"
iptremoverule "-F lanuploadtraffic -t mangle"
iptremoverule "-X landownloadtraffic -t mangle"
iptremoverule "-X lanuploadtraffic -t mangle"
if [ "$addop" = 'stop' -o "$addop" = 'stop' ]
then
dlog "INFO: IP LAN TRAFFIC ACCOUNT rules removed."
return 0
fi
dlog "INFO: setup IP LAN TRAFFIC ACCOUNT rules for $LANIPMASK ..."
#-A POSTROUTING -o br-lan -m comment --comment "LANIPTRAFFICACCOUNT" -j landownloadtraffic
iptnewchain "-N landownloadtraffic -t mangle"
errcount $?
iptables -L POSTROUTING -t mangle --line-numbers 2>/dev/null | grep '1 ' | grep -q 'landownloadtraffic'
if [ $? -ne 0 ]
then
iptremoverule "-D POSTROUTING -t mangle -o br-lan -j landownloadtraffic"
iptexec "iptables -I POSTROUTING -t mangle -o br-lan -j landownloadtraffic"
errcount $?
fi
#-A fwmark -i br-lan -m comment --comment "LANIPTRAFFICACCOUNT" -j lanuploadtraffic
iptnewchain "-N lanuploadtraffic -t mangle"
errcount $?
iptables -L fwmark -t mangle --line-numbers 2>/dev/null | grep '1 ' | grep -q 'lanuploadtraffic'
if [ $? -ne 0 ]
then
iptremoverule "-D fwmark -t mangle -i br-lan -j lanuploadtraffic"
iptexec "iptables -I fwmark -t mangle -i br-lan -j lanuploadtraffic"
errcount $?
fi
#clean up rules in lanuploadtraffic, landownloadtraffic and re-create all
iptremoverule "-F landownloadtraffic -t mangle"
iptremoverule "-F lanuploadtraffic -t mangle"
iptexec "iptables -A landownloadtraffic -t mangle -m comment --comment LANIPTRAFFICACCOUNT -j ACCOUNT --addr $LANIPMASK --tname landownloadtraffic"
iptexec "iptables -A lanuploadtraffic -t mangle -m comment --comment LANIPTRAFFICACCOUNT -j ACCOUNT --addr $LANIPMASK --tname lanuploadtraffic"
#
chk=$(iptables -L landownloadtraffic -t mangle -n -v | grep -c 'LANIPTRAFFICACCOUNT')
if [ $chk -lt 1 ]
then
dlog "ERROR: landownloadtraffic rules setup failed."
errcount 1
fi
chk=$(iptables -L lanuploadtraffic -t mangle -n -v | grep -c 'LANIPTRAFFICACCOUNT')
if [ $chk -lt 1 ]
then
dlog "ERROR: lanuploadtraffic rules setup failed."
errcount 1
fi
return 0
}
macfilter_doit(){
#
proclock needlan
#
if [ "$INTERFACE" != "lan" -a -n "$INTERFACE" -a -n "$DEVICE" -a -n "$ACTION" ] ;then
dlog "INFO: skip macfilter for interface ${INTERFACE}."
return 0
fi
dlog "INFO: setup MACFILTER rules ..."
lua /usr/sbin/macfilterctl init
errcount $?
errcount $?
}
ttl_doit(){
if [ "$(nvram get model 2>/dev/null)" != "R1CM" -a "$(nvram get model 2>/dev/null)" != "R1CQ" ]
then
dlog "INFO: platform $(nvram get model 2>/dev/null) skip setting TTL to 64"
return 0
fi
local delnum=`iptables -t mangle --line-numbers -L POSTROUTING 2>/dev/null|awk '/TTL set to /{print$1}'`
if [ -n "$delnum" ]
then
iptables -t mangle -D POSTROUTING $delnum 2>/dev/null
if [ $? -eq 0 ]
then
dlog "INFO: unset TTL to 64 ok."
else
dlog "ERROR: unset TTL to 64 failed."
fi
fi
local ttldevice=`getdefaultroutedev`
if [ -n "$ttldevice" ]
then
iptables -t mangle -I POSTROUTING -o $ttldevice -j TTL --ttl-set 64 2>/dev/null
if [ $? -eq 0 ]
then
dlog "INFO: set $ttldevice TTL to 64 ok."
return 0
else
dlog "ERROR: set $ttldevice TTL to 64 failed."
return 1
fi
fi
return 1
}
miqos_doit(){
#initial miqos ipt mark
/etc/init.d/miqos init_ipt
#only active qos when boot-check is ready
local stat=`cat /proc/xiaoqiang/boot_status 2>/dev/null`
if [ "$stat" -eq "3" ]; then
/etc/init.d/miqos restart
fi
return 0
}
xqfp_doit(){
if [ -f /proc/xqfp/dbg_switch ]; then
/etc/init.d/soft_fast_path fw_load
fi
return 0
}
smartproxy_doit(){
[ -f "/usr/sbin/proxy_thirdparty.sh" ] && /usr/sbin/proxy_thirdparty.sh flush
return 0
}
smartvpn_doit(){
[ -f "/etc/init.d/smartvpn" ] && /etc/init.d/smartvpn start
return 0
}
parentalctl_doit(){
[ -f "/usr/sbin/parentalctl.sh" ] && /usr/sbin/parentalctl.sh reload
return 0
}
kr_doit() {
ipset flush kr_query
ipset destroy kr_query
ipset create kr_query hash:net
iptables -t mangle -A fwmark -p tcp -m set --match-set kr_query dst -m comment --comment kr_query -j MARK --set-xmark 0x4/0x4
}
APK_PROXY_INITD="/etc/init.d/http_apk_proxy"
apk_proxy_doit() {
[ -f $APK_PROXY_INITD ] && $APK_PROXY_INITD reload_iptable_rule
return 0
}
turbo_doit() {
#ccgame
ccgame=`uci -q get turbo.ccgame.name`
ccgame_mark="0x0100/0x0300"
tables="/etc/iproute2/rt_tables"
[ -n "$ccgame" ] && {
# create rt table name of $service
grep -q $ccgame $tables || echo "150 $ccgame" >> $tables
#create ipset if not exist
ipset -q create $ccgame hash:ip
iptables -t mangle -D fwmark -m set --match-set $ccgame dst -m comment --comment $ccgame -j MARK --set-xmark $ccgame_mark
iptables -t mangle -A fwmark -m set --match-set $ccgame dst -m comment --comment $ccgame -j MARK --set-xmark $ccgame_mark
lsmod | grep ctf && {
iptables -t mangle -D fwmark -m set --match-set $ccgame dst -j SKIPCTF
iptables -t mangle -A fwmark -m set --match-set $ccgame dst -j SKIPCTF
}
#collecting ip list for cc game
[ -d /proc/net/xt_recent ] && {
ipset -q create ${ccgame}_chk hash:net
iptables -t nat -D PREROUTING -m set --match-set ${ccgame}_chk dst -m comment --comment ${ccgame}_chk -m recent --name $ccgame --set --rdest
iptables -t nat -I PREROUTING -m set --match-set ${ccgame}_chk dst -m comment --comment ${ccgame}_chk -m recent --name $ccgame --set --rdest
}
}
}
modules_doit(){
#prepare_doit
### NAT rules ####
if [ "$ctlop" = 'dnsmiwifi' ]
then
#suing chain prerouting_lan_rule
dnsmiwifi_doit
#test "$addop" = 'stop' -o "$addop" = 'off' && exit 0
fi
#
if [ "$ctlop" = 'webinitrdr' ]
then
#using chain prerouting_lan_rule
webinitrdr_doit
##test "$addop" = 'stop' -o "$addop" = 'off' && exit 0
fi
#
### INPUT rules ####
### FORWARD rules ####
### MANGLE rules ####
# using chain fwmark, lanuploadtraffic(PREROUTING), landownloadtraffic(POSTROUTING), preroute-wan-mac, preroute-admin-mac, preroute-lan-mac
#
if [ "$ctlop" = 'iptaccount' ]
then
#
iptaccount_doit
#test "$addop" = 'stop' -o "$addop" = 'off' && exit 0
fi
#
#
if [ "$ctlop" = 'macfilter' ]
then
#
macfilter_doit
#test "$addop" = 'stop' -o "$addop" = 'off' && exit 0
fi
if [ "$ctlop" = 'ttlset' ]
then
# disable ttl_doit because it break ICMP
exitcode=0
fi
#
if [ "$ctlop" = 'miqos' ]
then
miqos_doit
fi
if [ "$ctlop" = 'xqfp' ]
then
xqfp_doit
fi
#
if [ "$ctlop" = 'smartproxy' ]
then
smartproxy_doit
fi
#
if [ "$ctlop" = 'smartvpn' ]
then
smartvpn_doit
fi
#
if [ "$ctlop" = 'parentalctl' ]
then
parentalctl_doit
fi
#
if [ "$ctlop" = 'kr_query' ]
then
kr_doit
fi
#
if [ "$ctlop" = 'apk_proxy' ]
then
apk_proxy_doit
fi
#
if [ "$ctlop" = 'dmz_bypass_ctf' ]
then
lua /usr/sbin/dmz_bypass_ctf
fi
#
if [ "$ctlop" = 'turbo' ]
then
turbo_doit
fi
#
return $exitcode
}
test -z "$addop" && addop='unset'
#
LANIPMASK="$(getlanipmask)"
export LANIPMASK
#
SCRIPTTAG="${SCRIPTTAG}_${ctlop}_${addop}"
SCRIPTLOCK="${SCRIPTMARK}_${ctlop}"
PROC_LOCK_DEBUG='TRUE'
#
dlog "INFO: executing $@"
#
modules_doit 2>&1 | pipelog dlog
if [ ${exitcode} -eq 0 ]
then
dlog "INFO: executing $@ exit with code ${exitcode}."
else
dlog "ERROR: executing $@ exit with code ${exitcode}."
fi
exit $exitcode
#