#!/bin/sh
VER="vDemo"
#======================================================================================== © 2018 Martineau, vDemo
Get_FirmwareVersion() {
# Assume VVV.nn such as 380.68 but ensure 382.1 is returned as 38201
local FIRMWARE=$(echo $(nvram get buildno) | awk 'BEGIN { FS = "." } {printf("%03d%02d",$1,$2)}')
echo $FIRMWARE
}
ANSIColours () {
cRESET="\e[0m";cBLA="\e[30m";cRED="\e[31m";cGRE="\e[32m";cYEL="\e[33m";cBLU="\e[34m";cMAG="\e[35m";cCYA="\e[36m";cGRA="\e[37m"
cBGRA="\e[90m";cBRED="\e[91m";cBGRE="\e[92m";cBYEL="\e[93m";cBBLU="\e[94m";cBMAG="\e[95m";cBCYA="\e[96m";cBWHT="\e[97m"
aBOLD="\e[1m";aDIM="\e[2m";aUNDER="\e[4m";aBLINK="\e[5m";aREVERSE="\e[7m"
cRED_="\e[41m";cGRE_="\e[42m"
}
CHAIN_exists() {
# Args: {FCHAIN_name} [table_name]
local FCHAIN="$1"
shift
[ $# -eq 1 ] && local TABLE="-t $1"
iptables $TABLE -n -L $FCHAIN >/dev/null 2>&1
local RC=$?
if [ $RC -eq 1 ];then
echo "N"
return 1
else
echo "Y"
return 0
fi
}
Firewall(){
iptables $@ 2>/dev/null # Suppress error messages
local FIREWALL_ERROR=$?
if [ "$FIREWALL_ERROR" -gt 0 ];then # Report error for "-I" insert and '-A' append actions
if [ "$1" == "-I" ] || [ "$1" == "-A" ];then
# Hack using I/O to file!
iptables $@ 2>/tmp/iptables.error$$; echo -e $cBRED"\t" $(grep "" -m1 /tmp/iptables.error$$);rm /tmp/iptables.error$$ # Hack using I/O to file!
echo -e "\t\t==> $@"
return 1
fi
fi
return 0
}
#======================================Main============================================
ANSIColours
FIRMWARE=$(Get_FirmwareVersion)
modprobe xt_comment
RESTRICT_LIST="10.88.8.114" # <<=== LAN IPs to be restricted to certain URLs
DOMAIN_LIST="google msn ibm" # <<=== Restricted 'keyword'/domains (assumed www.xxx.com)
FCHAIN="myURL"
ICHAIN="myDNS"
VERBOSE=
if [ ! -z "$(echo $@ | grep -ow "status")" ];then
VERBOSE="n"
fi
for IP in $RESTRICT_LIST
do
case $1 in
off)
ACTION="-D";;
on)
ACTION="-I"
if [ "$(CHAIN_exists "$FCHAIN")" == "N" ];then
iptables -N $FCHAIN
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -j DROP -m comment --comment Block-WAN-ACCESS
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -j REJECT --reject-with tcp-reset -p tcp -m comment --comment Block-WAN-ACCESS-TCP
else
iptables -F $FCHAIN 2> /dev/null
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -j DROP -m comment --comment Block-WAN-ACCESS
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -j REJECT --reject-with tcp-reset -p tcp -m comment --comment Block-WAN-ACCESS-TCP
fi
if [ "$(CHAIN_exists "$ICHAIN")" == "N" ];then
iptables -N $ICHAIN
Firewall $ACTION $ICHAIN -i br0 -s $IP -p udp -m udp --dport 53 -j DROP -m comment --comment Block-DNS-ACCESS
else
iptables -F $ICHAIN 2> /dev/null
Firewall $ACTION $ICHAIN -i br0 -s $IP -p udp -m udp --dport 53 -j DROP -m comment --comment Block-DNS-ACCESS
fi
;;
*)
echo -e $cBMAG
iptables -"${VERBOSE}"vL INPUT --line -t filter | grep -E "Chain INPUT|^num|\/"
echo -e
iptables -"${VERBOSE}"vL FORWARD --line -t filter | grep -E "Chain FORWARD|^num|\/"
echo -e
iptables -"${VERBOSE}"vL $ICHAIN --line -t filter 2>/dev/null
echo -e
iptables -"${VERBOSE}"vL $FCHAIN --line -t filter 2>/dev/null
echo -e $cRESET
exit 0
;;
esac
Firewall $ACTION INPUT -i br0 -s $IP -p udp -m udp --dport 53 -j $ICHAIN -m comment --comment DNS-filtering
Firewall $ACTION FORWARD -i br0 -s $IP -o $(nvram get wan0_ifname) -j $FCHAIN -m comment --comment URL-filtering
# For the custom chains, simply wipe them if it's a 'off' (delete) request
if [ "$ACTION" == "-I" ];then
for STRING in $DOMAIN_LIST
do
Firewall $ACTION $ICHAIN -i br0 -s $IP -p udp -m udp --dport 53 -m string --string $STRING --algo bm --to 65535 -j ACCEPT -m comment --comment $STRING
Firewall $ACTION $ICHAIN -i br0 -s $IP -p udp -m udp --dport 53 -m webstr --url "www."${STRING}".com" -j LOG -m comment --comment www."${STRING}".com
Firewall $ACTION $ICHAIN -i br0 -s $IP -p udp -m udp --dport 53 -m webstr --content "www."${STRING}".com" -j LOG -m comment --comment www."${STRING}".com
Firewall $ACTION $ICHAIN -i br0 -s $IP -m string --string $STRING --algo bm --to 65535 -j LOG -m comment --comment $STRING
Firewall $ACTION $ICHAIN -i br0 -s $IP -m webstr --url "www."${STRING}".com" -j LOG -m comment --comment www."${STRING}".com
Firewall $ACTION $ICHAIN -i br0 -s $IP -m webstr --content "www."${STRING}".com" -j LOG -m comment --comment www."${STRING}".com
LEN=${#STRING}
Firewall $ACTION $ICHAIN -i br0 -s $IP -m string --hex-string "\|03\|www\|$LEN\|$STRING\|03\|com" --algo bm --to 65535 -j LOG
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -d www.${STRING}.com -j ACCEPT -m comment --comment www."${STRING}".com
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -m webstr --url "www."${STRING}".com" -j LOG -m comment --comment www."${STRING}".com
Firewall $ACTION $FCHAIN -i br0 -s $IP -p udp -m udp --dport 53 -m string --string $STRING --algo bm --to 65535 -j LOG -m comment --comment DNS-$STRING
Firewall $ACTION $FCHAIN -i br0 -p udp -m udp --dport 53 -m string --string $STRING --algo bm --to 65535 -j LOG -m comment --comment DNS-$STRING
Firewall $ACTION $FCHAIN -i br0 -s $IP -o $(nvram get wan0_ifname) -m webstr --url "www."${STRING}".com" -j LOG -m comment --comment www."${STRING}".com
Firewall $ACTION $FCHAIN -i br0 -s $IP -m string --string $STRING --algo bm --to 65535 -j LOG -m comment --comment DNS-$STRING
done
else
if [ "$(CHAIN_exists "$ICHAIN")" == "Y" ] || [ "$(CHAIN_exists "$FCHAIN")" == "Y" ];then
iptables -F $ICHAIN 2>/dev/null
iptables -X $ICHAIN 2>/dev/null
iptables -F $FCHAIN 2>/dev/null
iptables -X $FCHAIN 2>/dev/null
fi
fi
done
# Status....
if [ "$1" != "on" ];then
echo -e $cBMAG
else
echo -e $cBGRE
fi
iptables -${VERBOSE}vL INPUT --line -t filter | grep -E "Chain INPUT|\$FCHAIN|^num|\/"
echo -e
iptables -${VERBOSE}vL FORWARD --line -t filter | grep -E "Chain FORWARD|$FCHAIN\/|^num|\/"
if [ "$1" == "off" ];then
echo -en $cRED # Just in case the custom tables haven't been deleted correctly
else
echo -en $cBGRE
fi
iptables -${VERBOSE}vL $ICHAIN --line -t filter 2>/dev/null
echo -e
iptables -${VERBOSE}vL $FCHAIN --line -t filter 2>/dev/null
echo -e $cRESET
exit 0