#!/bin/sh
# This script was written to overcome a 'bug'!.........and overcome the 128 keywords filter limitation?
# Beware that entries added to the FORWARD table WILL be wiped if U turn ON/OFF either the Asus GUI URL or KEYWORD filtering!!
# So if you already had selective routing with forced VPN i.e. no WAN access, then this will be erased allowing supposedly blocked devices
# to use the WAN if their VPN goes down.!
# NOTE: Logically you would expect to add the -j DROP / -j REJECT to the OUTPUT chain, but clearly blocking the results
# from being returned to the user is what filtering implies!
# Use of IPTABLES for URL filtering is a hack, and the preferred solution would be to use a true Proxy Server such as SQUID
# i.e. for string filtering, there is no guarantee that the search string wouldn't be split across two packets!
# Beware that ALL times are based on UTC, so if on British Summer Time (BST) etc. then you will be an hour out!
# e.g. Suppose U only want to allow Dailymail access during lunchtime, on BST the following would be actually applied as 13:30 to 14:30!
# iptables -I FORWARD -m webstr --url Dailymail -p tcp -j REJECT --reject-with tcp-reset
# iptables -I FORWARD -m webstr --url Dailymail -m time --timestart 12:30 --timestop 13:30 -j ACCEPT
#
# URLString_match {keyword | -?} {reject | drop | accept} {-d | -url | -str}
#
# where keyword text string you wish to filter (case insensitive)
# -? lists the current URL/STRING filters
#
# reject|accept|drop
#
# -d deletes URL and STRING matching rules - keyword is case sensitive
# -url only creates a URL filter
# -str only creates a STRING filter
# e.g.
# URLString_match -?
# URLString_match PorN
# URLString_match PorN -d
#
# URLString_match PoRn reject
# URLString_match PoRn reject -d
## URLString_match sex reject -url
# URLString_match Middlesex accept -url
#
#
#logger -t "($(basename $0))" $$ Martineau URL and Keyword matching....
echo "($(basename $0))" $$ Martineau URL and Keyword matching.... "[$@]"
# Translate input args into UPPERCASE
TARGET=`echo $1 | tr '[a-z]' '[A-Z]'`
RULEARG=`echo $2 | tr '[a-z]' '[A-Z]'`
ACTION=`echo $3 | tr '[a-z]' '[A-Z]'`
if [ "$TARGET" = "-?" ];then
iptables -nvL FORWARD --line
exit
fi
echo "Checking filter request ARGs"
if [ "$TARGET" = "" ];then
echo "Required filter URL/Keyword is missing" $1
exit 1
fi
if [ "$TARGET" = "-D" ];then
echo "Missing filter URL/Keyword for -d argument"
exit 1
fi
if [ "$RULEARG" = "-D" ];then
ACTION="-D"
fi
if [ "$RULEARG" = "-?" ];then
echo "Keyword $1 ignored for misplaced -? argument, status list request assumed"
iptables -nvL FORWARD --line
exit 0
fi
if [ "$RULEARG" = "-URL" ];then
ACTION=$RULEARG
fi
if [ "$RULEARG" = "-STR" ];then
ACTION=$RULEARG
fi
RULEACT=""
TIMESPEC=" -m time --timestart 00:00:00 --timestop 23:59:00"
# REJECT is visually far quicker informing the user of the Block
# rather than DROP
#DROP option retained if required!
if [ "$RULEARG" = "DROP" ];then
RULEACT=" -j DROP"
fi
if [ "$RULEARG" = "ACCEPT" ];then
RULEACT=" -j ACCEPT"
fi
if [ "$RULEARG" = "REJECT" ];then
RULEACT=" -p tcp -j REJECT --reject-with tcp-reset"
fi
# Delete ALL request ?
if [ "$ACTION" = "-D" ];then
echo "Flushing ALL filter(s) for URL/Keyword" $1 $RULEACT
iptables -D FORWARD -m webstr --url $1 $RULEACT
iptables -D FORWARD -m string --string $1 --algo bm $RULEACT $TIMESPEC
iptables -nvL FORWARD --line
else
echo "Flushing existing filter(s) for URL/Keyword" $1 $RULEACT
if [ "$ACTION" = "-URL" ];then
iptables -D FORWARD -m webstr --url $1 $RULEACT
fi
if [ "$ACTION" = "-STR" ];then
iptables -D FORWARD -m string --string $1 --algo bm $RULEACT $TIMESPEC
fi
echo "Inserting filter(s) for URL/Keyword" $1 "for" $ACTION "using" $RULEACT
if [ "$ACTION" = "-URL" ];then
iptables -I FORWARD -m webstr --url $1 $RULEACT
fi
if [ "$ACTION" = "-STR" ];then
iptables -I FORWARD -m string --string $1 --algo bm $RULEACT $TIMESPEC
fi
# Show the status of the modified rules
iptables -nvL FORWARD --line
fi