|
#!/bin/sh |
|
#Put in /etc/adblock.sh |
|
#Block ads, malware, etc. |
|
|
|
#### CONFIG SECTION #### |
|
|
|
# Only block wireless ads? Y/N |
|
ONLY_WIRELESS="N" |
|
|
|
# IPv6 support? Y/N |
|
IPV6="N" |
|
|
|
# Need SSL websites? |
|
SSL="N" |
|
|
|
# Try to transparently serve pixel response? |
|
# If enabled, understand the consequences and mechanics of this setup |
|
TRANS="N" |
|
|
|
# Exempt an ip range |
|
EXEMPT="N" |
|
START_RANGE="192.168.1.0" |
|
END_RANGE="192.168.1.255" |
|
|
|
# Redirect endpoint |
|
ENDPOINT_IP4="0.0.0.0" |
|
ENDPOINT_IP6="::" |
|
|
|
#Change the cron command to what is comfortable, or leave as is |
|
CRON="0 4 * * 0,3 sh /etc/adblock.sh" |
|
|
|
#### END CONFIG #### |
|
|
|
#### FUNCTIONS #### |
|
|
|
cleanup() |
|
{ |
|
#Delete files used to build list to free up the limited space |
|
echo 'Cleaning up...' |
|
rm -f /tmp/block.build.list |
|
rm -f /tmp/block.build.before |
|
} |
|
|
|
install_dependencies() |
|
{ |
|
#Need iptables-mod-nat-extra installed |
|
if opkg list-installed | grep -q iptables-mod-nat-extra |
|
then |
|
echo 'iptables-mod-nat-extra is installed!' |
|
else |
|
echo 'Updating package list...' |
|
opkg update > /dev/null |
|
echo 'Installing iptables-mod-nat-extra...' |
|
opkg install iptables-mod-nat-extra > /dev/null |
|
fi |
|
|
|
#Need iptable-mod-iprange for exemption |
|
if [ "$EXEMPT" = "Y" ] |
|
then |
|
if opkg list-installed | grep -q iptables-mod-iprange |
|
then |
|
echo 'iptables-mod-iprange installed' |
|
else |
|
echo 'Updating package list...' |
|
opkg update > /dev/null |
|
echo 'Installing iptables-mod-iprange...' |
|
opkg install iptables-mod-iprange > /dev/null |
|
fi |
|
fi |
|
|
|
#Need wget for https websites |
|
if [ "$SSL" = "Y" ] |
|
then |
|
if opkg list-installed wget | grep -q wget |
|
then |
|
if wget --version | grep -q +ssl |
|
then |
|
echo 'wget (with ssl) found' |
|
else |
|
# wget without ssl, need to reinstall full wget |
|
opkg update > /dev/null |
|
opkg install wget --force-reinstall > /dev/null |
|
fi |
|
else |
|
echo 'Updating package list...' |
|
opkg update > /dev/null |
|
echo 'Installing wget (with ssl)...' |
|
opkg install wget > /dev/null |
|
fi |
|
fi |
|
} |
|
|
|
add_config() |
|
{ |
|
if [ "$ONLY_WIRELESS" = "Y" ] |
|
then |
|
echo 'Wireless only blocking!' |
|
if [ "$EXEMPT" = "Y" ] |
|
then |
|
echo 'Exempting some ips...' |
|
FW1="iptables -t nat -I PREROUTING -m iprange ! --src-range $START_RANGE-$END_RANGE -i wlan+ -p tcp --dport 53 -j REDIRECT --to-ports 53" |
|
FW2="iptables -t nat -I PREROUTING -m iprange ! --src-range $START_RANGE-$END_RANGE -i wlan+ -p udp --dport 53 -j REDIRECT --to-ports 53" |
|
else |
|
FW1="iptables -t nat -I PREROUTING -i wlan+ -p tcp --dport 53 -j REDIRECT --to-ports 53" |
|
FW2="iptables -t nat -I PREROUTING -i wlan+ -p udp --dport 53 -j REDIRECT --to-ports 53" |
|
fi |
|
else |
|
if [ "$EXEMPT" = "Y" ] |
|
then |
|
echo "Exempting some ips..." |
|
FW1="iptables -t nat -I PREROUTING -m iprange ! --src-range $START_RANGE-$END_RANGE -p tcp --dport 53 -j REDIRECT --to-ports 53" |
|
FW2="iptables -t nat -I PREROUTING -m iprange ! --src-range $START_RANGE-$END_RANGE -p udp --dport 53 -j REDIRECT --to-ports 53" |
|
else |
|
FW1="iptables -t nat -I PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53" |
|
FW2="iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53" |
|
fi |
|
fi |
|
|
|
echo 'Updating config...' |
|
|
|
#Update DHCP config |
|
uci add_list dhcp.@dnsmasq[0].addnhosts=/etc/block.hosts > /dev/null 2>&1 && uci commit |
|
|
|
#Add to crontab |
|
echo "$CRON" >> /etc/crontabs/root |
|
|
|
#Update dnsmasq config for Tor |
|
TOR=`uci get tor.global.enabled 2> /dev/null` |
|
if [ "$TOR" == "1" ] |
|
then |
|
TORPORT=`uci get tor.client.dns_port` |
|
TORIP="127.0.0.1:$TORPORT" |
|
uci set dhcp.@dnsmasq[0].noresolv='1' > /dev/null &2>1 && uci commit |
|
uci add_list dhcp.@dnsmasq[0].server="$TORIP" > /dev/null &2>1 && uci commit |
|
fi |
|
|
|
# Add firewall rules |
|
echo "$FW1" >> /etc/firewall.user |
|
echo "$FW2" >> /etc/firewall.user |
|
|
|
# Provide hint if localservice is 1 |
|
LS=`uci get dhcp.@dnsmasq[0].localservice 2> /dev/null` |
|
if [ "$LS" == "1" ] |
|
then |
|
echo "HINT: localservice is set to 1" |
|
echo " Adblocking (and router DNS) over a VPN may not work" |
|
echo " To allow VPN router DNS, manually set localservice to 0" |
|
fi |
|
|
|
|
|
# Determining uhttpd/httpd_gargoyle for transparent pixel support |
|
if [ "$TRANS" = "Y" ] |
|
then |
|
if [ ! -e "/www/1.gif" ] |
|
then |
|
/usr/bin/wget -O /www/1.gif http://upload.wikimedia.org/wikipedia/commons/c/ce/Transparent.gif > /dev/null |
|
fi |
|
if [ -s "/usr/sbin/uhttpd" ] |
|
then |
|
#The default is none, so I don't want to check for it, so just write it |
|
echo "uhttpd found..." |
|
echo "updating server error page to return transparent pixel..." |
|
uci set uhttpd.main.error_page="/1.gif" && uci commit |
|
elif [ -s "/usr/sbin/httpd_gargoyle" ] |
|
then |
|
# Write without testing |
|
echo "httpd_gargoyle found..." |
|
echo "updating server error page to return transparent pixel..." |
|
uci set httpd_gargoyle.server.page_not_found_file="1.gif" && uci commit |
|
else |
|
echo "Cannot find supported web server..." |
|
fi |
|
fi |
|
} |
|
|
|
update_blocklist() |
|
{ |
|
#Delete the old block.hosts to make room for the updates |
|
rm -f /etc/block.hosts |
|
|
|
# Correct endpoint for transparent pixel response |
|
if [ "$TRANS" = "Y" ] && [ -e "/www/1.gif" ] && ([ -s "/usr/sbin/uhttpd" ] || [ -s "/usr/sbin/httpd_gargoyle" ]) |
|
then |
|
ENDPOINT_IP4=$(uci get network.lan.ipaddr) |
|
if [ "$IPV6" = "Y" ] |
|
then |
|
ENDPOINT_IP6=$(uci get network.lan6.ipaddr) |
|
fi |
|
fi |
|
|
|
echo 'Downloading hosts lists...' |
|
#Download and process the files needed to make the lists (enable/add more, if you want) |
|
wget -qO- http://www.mvps.org/winhelp2002/hosts.txt| awk -v r="$ENDPOINT_IP4" '{sub(/^0.0.0.0/, r)} $0 ~ "^"r' > /tmp/block.build.list |
|
wget -qO- "http://adaway.org/hosts.txt"|awk -v r="$ENDPOINT_IP4" '{sub(/^127.0.0.1/, r)} $0 ~ "^"r' >> /tmp/block.build.list |
|
#wget -qO- http://www.malwaredomainlist.com/hostslist/hosts.txt|awk -v r="$ENDPOINT_IP4" '{sub(/^127.0.0.1/, r)} $0 ~ "^"r' >> /tmp/block.build.list |
|
#wget -qO- "http://hosts-file.net/.\ad_servers.txt"|awk -v r="$ENDPOINT_IP4" '{sub(/^127.0.0.1/, r)} $0 ~ "^"r' >> /tmp/block.build.list |
|
|
|
#Add black list, if non-empty |
|
if [ -s "/etc/black.list" ] |
|
then |
|
echo 'Adding blacklist...' |
|
awk -v r="$ENDPOINT_IP4" '/^[^#]/ { print r,$1 }' /etc/black.list >> /tmp/block.build.list |
|
fi |
|
|
|
echo 'Sorting lists...' |
|
|
|
#Sort the download/black lists |
|
awk '{sub(/\r$/,"");print $1,$2}' /tmp/block.build.list|sort -u > /tmp/block.build.before |
|
|
|
#Filter (if applicable) |
|
if [ -s "/etc/white.list" ] |
|
then |
|
#Filter the blacklist, supressing whitelist matches |
|
# This is relatively slow =-( |
|
echo 'Filtering white list...' |
|
egrep -v "^[[:space:]]*$" /etc/white.list | awk '/^[^#]/ {sub(/\r$/,"");print $1}' | grep -vf - /tmp/block.build.before > /etc/block.hosts |
|
else |
|
cat /tmp/block.build.before > /etc/block.hosts |
|
fi |
|
|
|
if [ "$IPV6" = "Y" ] |
|
then |
|
safe_pattern=$(printf '%s\n' "$ENDPOINT_IP4" | sed 's/[[\.*^$(){}?+|/]/\\&/g') |
|
safe_addition=$(printf '%s\n' "$ENDPOINT_IP6" | sed 's/[\&/]/\\&/g') |
|
echo 'Adding ipv6 support...' |
|
sed -i -re "s/^(${safe_pattern}) (.*)$/\1 \2\n${safe_addition} \2/g" /etc/block.hosts |
|
fi |
|
} |
|
|
|
restart_firewall() |
|
{ |
|
echo 'Restarting firewall...' |
|
if [ -s "/usr/lib/gargoyle/restart_firewall.sh" ] |
|
then |
|
/usr/lib/gargoyle/restart_firewall.sh > /dev/null 2>&1 |
|
else |
|
/etc/init.d/firewall restart > /dev/null 2>&1 |
|
fi |
|
} |
|
|
|
restart_dnsmasq() |
|
{ |
|
if [ "$1" -eq "0" ] |
|
then |
|
echo 'Re-reading blocklist' |
|
killall -HUP dnsmasq |
|
else |
|
echo 'Restarting dnsmasq...' |
|
/etc/init.d/dnsmasq restart |
|
fi |
|
} |
|
|
|
restart_http() |
|
{ |
|
if [ -s "/usr/sbin/uhttpd" ] |
|
then |
|
echo 'Restarting uhttpd...' |
|
/etc/init.d/uhttpd restart |
|
elif [ -s "/usr/sbin/httpd_gargoyle" ] |
|
then |
|
echo 'Restarting httpd_gargoyle...' |
|
/etc/init.d/httpd_gargoyle restart |
|
fi |
|
} |
|
restart_cron() |
|
{ |
|
echo 'Restarting cron...' |
|
/etc/init.d/cron restart > /dev/null 2>&1 |
|
} |
|
|
|
remove_config() |
|
{ |
|
echo 'Reverting config...' |
|
|
|
# Remove addnhosts |
|
uci del_list dhcp.@dnsmasq[0].addnhosts=/etc/block.hosts > /dev/null 2>&1 && uci commit |
|
|
|
# Remove cron entry |
|
sed -i '/adblock/d' /etc/crontabs/root |
|
|
|
# Remove firewall rules |
|
sed -i '/--to-ports 53/d' /etc/firewall.user |
|
|
|
# Remove Tor workarounds |
|
uci del_list dhcp.@dnsmasq[0].server > /dev/null 2>&1 && uci commit |
|
uci set dhcp.@dnsmasq[0].noresolv='0' > /dev/null 2>&1 && uci commit |
|
|
|
# Remove proxying |
|
uci delete uhttpd.main.error_page > /dev/null 2>&1 && uci commit |
|
uci set httpd_gargoyle.server.page_not_found_file="login.sh" > /dev/null 2>&1 && uci commit |
|
} |
|
|
|
|
|
toggle() |
|
{ |
|
# Check for cron as test for on/off |
|
if grep -q "adblock" /etc/crontabs/root |
|
then |
|
# Turn off |
|
echo 'Turning off!' |
|
remove_config |
|
else |
|
# Turn on |
|
echo 'Turning on!' |
|
add_config |
|
fi |
|
|
|
# Restart services |
|
restart_firewall |
|
restart_dnsmasq 1 |
|
restart_http |
|
restart_cron |
|
} |
|
|
|
#### END FUNCTIONS #### |
|
|
|
### Options parsing #### |
|
|
|
case "$1" in |
|
# Toggle on/off |
|
"-t") |
|
toggle |
|
;; |
|
#First time run |
|
"-f") |
|
install_dependencies |
|
add_config |
|
update_blocklist |
|
restart_firewall |
|
restart_dnsmasq 1 |
|
restart_http |
|
restart_cron |
|
cleanup |
|
;; |
|
#Reinstall |
|
"-r") |
|
remove_config |
|
install_dependencies |
|
add_config |
|
update_blocklist |
|
restart_firewall |
|
restart_dnsmasq 1 |
|
restart_http |
|
restart_cron |
|
cleanup |
|
;; |
|
#Default updates blocklist only |
|
*) |
|
update_blocklist |
|
restart_dnsmasq 0 |
|
cleanup |
|
;; |
|
esac |
|
|
|
#### END OPTIONS #### |
|
|
|
exit 0 |