|
#!/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 |
when I enable the 'serving with transparent pixel' option then it actually redirects to my openWrt router right? But when it does so, doesn't it interfere with the LUCI login page also listening on port 80 and 443?