#!/bin/sh /etc/rc.common # make sure this script is started AFTER the start of dnsmasq START=66 # make sure this script is stopped AFTER the shutdown of the network STOP=91 # source the configuration source "/etc/inithost.cfg" ### ### Functions ### ### unpack_hostfile # unpacks an persistent, compressed host file thus # preparing it for usage as an dnsmasq host file # 1. filters out the whitelisted items # 2. sorts it and removes duplicates # 3. adds the redirection IP unpack_hostfile() { zcat $1 | filter_whitelist } ### is_hostfile_consistent # this function checks whether the persistent host file under # $PERSISTENTDIR and its corresponding compressed gz file # contain consistent context or not is_hostfile_consistent() { local CHKSUM1=$( unpack_hostfile "$PERSISTENTDIR/$1.gz" | md5sum | awk '{print $1}' ) local CHKSUM2=$( md5sum "$PERSISTENTDIR/$1" | awk '{print $1}' ) test $CHKSUM1 = $CHKSUM2 } ### restore_persistent_hostfiles # this function is used prior to any internet accessability # and will install any persistently saved host files # this will circumvent users to reboot the router with internet disconnected # in order to disable DNS blockage # it will check for .gz in $PERSISTENTDIR and unpack those to $ACTIVEHOSTDIR/ # since can be a symlink the file may be stored elsewhere restore_persistent_hostfiles() { for f in $(ls -1 $PERSISTENTDIR/*.gz) ; do # link all host files (symlinks and real host files) to $ACTIVEHOSTDIR # host files in gz format get decompressed and written to the corresponding # files/symlinks in $PERSISTENTDIR hfn=$(basename $f .gz) if [ "$(readlink $PERSISTENTDIR/$hfn)" == "$ACTIVEHOSTDIR/$hfn" ] ; then logger "$PERSISTENTDIR/$hfn is already a symlink to $ACTIVEHOSTDIR/$hfn" else logger "Linking $ACTIVEHOSTDIR/$hfn to persistent host file $PERSISTENTDIR/$hfn" ln -sf $PERSISTENTDIR/$hfn $ACTIVEHOSTDIR/$hfn fi if is_hostfile_consistent "$hfn" ; then logger "$PERSISTENTDIR/$hfn already consistent, no unpacking needed" else logger "Unpacking persistent host file $f to $PERSISTENTDIR/$hfn" unpack_hostfile "$f" > $PERSISTENTDIR/$hfn fi done } ### save_persistent_hostfiles # this function is used after an update from a remote host file # and will update the permanently stored compressed host files # it will check for *.gz files in $PERSISTENTDIR and update just those save_persistent_hostfiles() { for f in $(ls -1 $PERSISTENTDIR/*.gz) ; do # update all existing compressed host files from their corresponding files/symlinks if test -e $PERSISTENTDIR/$(basename $f .gz); then if is_hostfile_consistent "$(basename $f .gz)"; then logger "Skip $f, contents already consistent" else # TODO keep existing '#' comments and white listed items in orig gz # FIXME for now these get deleted logger "Compressing updated host file to $f" cat $PERSISTENTDIR/$(basename $f .gz) | awk '{print $NF}' | gzip -c > $f fi fi done } ### last_mtime # helper function to check the last modification time of the remote host file and # returns a time stamp, if not accessible it returns -1 # $1 -- URL to the remote host file last_mtime() { curl -m 20 -sI $1 | awk '/^HTTP\//{if ($2!=200) exit(1)}/^Last-Modified:/{$1="";mtime=$0}END{print mtime}' |\ awk 'BEGIN{split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",m); for (i in m) {mn[m[i]]=i}} {hhmmss=gensub(/:/," ","g",$5);print mktime(""$4" "mn[$3]" "$2" "hhmmss)}' } ### update_dnsmasq_cfg # copy the tld mask rules from $RULESDIR and filter the whitelisted ones update_dnsmasq_cfg() { logger "Rewriting using address rules from $RULESDIR..." for f in $(ls -1 $RULESDIR/*) ; do cat $f | awk '{print "address=/"$1"/"'$ENDPOINT_IP4'}' > /tmp/dnsmasq.d/$(basename $f) done # TODO whitelist support } ### signal_dnsmasq # Signals a running dnsmasq instance to re-read host files contained in $ACTIVEHOSTDIR # If dnsmasq is not running it will be restarted # Run this once after finishing all 'update_active_hostfile' (/etc/inithost.cfg) calls signal_dnsmasq() { if ps -w | grep dns[m]asq; then killall -HUP dnsmasq else /etc/init.d/dnsmasq restart fi } boot() { logger "install iptable rules to force dnsmasq routing for port 53 queries" # route every DNS query through dnsmasq LAN_IP=$(uci get network.lan.ipaddr) # FIXME make fail safe iptables -t nat -A PREROUTING -i br-lan -p tcp --dport 53 -j DNAT --to $LAN_IP iptables -t nat -A PREROUTING -i br-lan -p udp --dport 53 -j DNAT --to $LAN_IP logger "make sure host directories exist" mkdir -p $PERSISTENTDIR mkdir -p $ACTIVEHOSTDIR start } restart() { stop start } start() { logger "Start and activate dnsmasq blocking of ads and porn sites" restore_persistent_hostfiles logger "Activate persistent host files..." signal_dnsmasq reload } reload() { logger "Retrieve updated host files from web..." update_hostfiles_from_web signal_dnsmasq logger "...done" logger "Make updated host settings persistent..." save_persistent_hostfiles logger "...done" } stop() { logger "Stopping host blocking..." # TODO delete tmp host files # shutdown dnsmasq if still running # delete iptables rules logger "...done" } # TODO that's how to get yoyo dnsmasq tld ruleset... check if those can be more useful... # wget -O /etc/dnsmasq.d/adblock.conf "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=dnsmasq&showintro=0&mimetype=plaintext" && service dnsmasq restart