523 lines
14 KiB
Bash
Executable File
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
|
|
#
|