Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- #DEBUG=; set -x # comment/uncomment to disable/enable debug mode
- # name: ddwrt-blacklist-domains.sh
- # version: 4.2.0, 27-apr-2024, by eibgrad
- # purpose: blacklist specific domains in dnsmasq (dns)
- # script type: startup (autostart)
- # installation:
- # 1. enable jffs2 (administration->jffs2)
- # 2. enable syslogd (services->services->system log)
- # 3. use shell (telnet/ssh) to execute one of the following commands:
- # curl -kLs bit.ly/ddwrt-installer|tr -d '\r'|sh -s aySi7RhY startup
- # or
- # wget -qO - bit.ly/ddwrt-installer|tr -d '\r'|sh -s aySi7RhY startup
- # 4. add the following to the "additional dnsmasq options" field on the
- # services page:
- # addn-hosts=/tmp/blacklisted_domains_ipv4
- # addn-hosts=/tmp/blacklisted_domains_ipv6
- # 5. (optional) modify options using vi editor:
- # vi /jffs/etc/config/ddwrt-blacklist-domains.startup
- # 6. (optional) enable cron (administration->management) and add the
- # following job:
- # 0 4 * * * root /jffs/etc/config/ddwrt-blacklist-domains.startup
- # 7. reboot
- (
- # ------------------------------ BEGIN OPTIONS ------------------------------- #
- # domains to be blacklisted
- BLACKLIST="/tmp/tmp.$$.blacklist"
- # note: nested blacklists are supported; any blacklist may contain domain
- # names and/or urls; those urls in turn may contain lists of other
- # domain names and/or urls; url references may be either remote
- # (http://|https://) or local (file://)
- # note: both ipv4 and ipv6 blacklisting are supported, however, ipv6 is
- # disabled by default (see SW_BLACKLIST_IPV6)
- # note: firebog.net is an excellent source of curated blacklists,
- # including "lists of lists" (https://v.firebog.net/hosts/lists.php)
- # note: exercise caution when using certain urls; these sometimes contain
- # *very* large lists of blacklisted domains, which may exceed the memory
- # capacity of the router and/or dnsmasq, and *may* have a detrimental
- # affect on dns performance; in the worst cases, it may crash dnsmasq
- # or even spontaneously reboot the router; consider using the --dry-run
- # command-line option to determine the number of domains (via the
- # syslog) that will be blacklisted before committing them to dnsmasq
- cat << 'EOF' > $BLACKLIST
- #facebook.com
- #www.facebook.com
- #whitehouse.gov
- #www.whitehouse.gov
- #file:///jffs/my_personal_blacklist
- https://v.firebog.net/hosts/lists.php?type=nocross # list of lists
- #https://raw.githubusercontent.com/chadmayfield/my-pihole-blocklists/master/lists/pi_blocklist_porn_top1m.list
- #https://v.firebog.net/hosts/Prigent-Adult.txt # CAUTION: EXTREMELY LARGE (in the many millions)
- #https://raw.githubusercontent.com/anudeepND/blacklist/master/facebook.txt
- EOF
- # exceptions: domains (and their sub-domains) NOT to be blacklisted
- # note: matching only occurs on whole parts of the domain name, moving right
- # to left; for example, adding somedomain.com to the whitelist would
- # also match xyz.somedomain.com, but NOT match xyzsomedomain.com nor
- # xyz.somedomain.com.us; wildcards (*) are NOT supported and will be
- # removed
- WHITELIST='
- localhost
- example-allow-this-domain.com
- '
- # comment/uncomment to disable/enable ipv4 blacklist
- SW_BLACKLIST_IPV4=
- # comment/uncomment to disable/enable ipv6 blacklist
- #SW_BLACKLIST_IPV6=
- # maximum time (in secs) allotted for curl to establish connection
- MAX_WAIT=60
- # maximum time (in secs) allotted for curl/wget to complete all operations
- MAX_TIME=120
- # ------------------------------- END OPTIONS -------------------------------- #
- # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
- # required for serialization when reentry is possible
- LOCK="/tmp/$(basename $0).lock"
- acquire_lock() {
- if ! mkdir $LOCK &>/dev/null; then
- echo "error: already running, this run aborted"
- rm -f $BLACKLIST
- exit 1
- fi
- }
- release_lock() { rmdir $LOCK &>/dev/null; }
- # default to curl, failover to wget (not guaranteed to support tls)
- which curl &>/dev/null && \
- GET_URL="curl -sLk --connect-timeout $MAX_WAIT --max-time $MAX_TIME" || \
- GET_URL="wget -T $MAX_TIME -qO -"
- # useful/common regular expressions
- REGEX_NOOP='^[[:space:]]*(#|$)'
- REGEX_URL='^[[:space:]]*(http|https|file)://'
- REGEX_IP='^[[:space:]]*([0-9]{1,3}\.){3}[0-9]{1,3}'
- REGEX_UBO='^[[:space:]]*\|\|([^^]*)(\^|)$' # ublock origin formatting
- # work/interim files
- BLACKLIST_DOM="/tmp/tmp.$$.blacklist_dom"
- BLACKLIST_TMP="/tmp/tmp.$$.blacklist_tmp"
- BLACKLIST4_TMP="/tmp/tmp.$$.blacklist4_tmp"
- BLACKLIST6_TMP="/tmp/tmp.$$.blacklist6_tmp"
- # blacklisted domains referenced in dnsmasq config
- BLACKLIST4='/tmp/blacklisted_domains_ipv4'
- BLACKLIST6='/tmp/blacklisted_domains_ipv6'
- # validate command-line args/options
- if [ "$1" ]; then
- if [ "$1" != '--dry-run' ]; then
- echo "error: unknown argument/option: $1"
- rm -f $BLACKLIST
- exit 1
- fi
- SW_DRY_RUN=
- fi
- # wait for wan availability
- until ping -qc1 -W3 8.8.8.8 &>/dev/null; do sleep 10; done
- # one instance at a time
- acquire_lock
- # catch premature exit and cleanup
- trap 'release_lock; exit 1' SIGHUP SIGINT SIGTERM
- while read line; do
- # skip comments and blank lines
- echo $line | grep -Eq "$REGEX_NOOP" && continue
- # isolate url/domain by removing any trailing comments
- line="$(echo $line | awk '{print $1}')"
- if echo $line | grep -Eq "$REGEX_URL"; then
- # retrieve the file
- $GET_URL $line > $BLACKLIST_TMP || { echo "error: $line"; continue; }
- # split file contents into urls and domains
- grep -E "$REGEX_URL" $BLACKLIST_TMP >> $BLACKLIST
- grep -Ev "$REGEX_URL" $BLACKLIST_TMP >> $BLACKLIST_DOM
- else
- # save the domain
- echo $line >> $BLACKLIST_DOM
- fi
- done < $BLACKLIST
- > $BLACKLIST4_TMP
- > $BLACKLIST6_TMP
- # function regex_wl()
- regex_wl() {
- echo $WHITELIST | \
- sed -r 's/\*//g;s/ |$/$|/g;s/\|$//;s/\./\\./g;s/([^|]*)/[ .]\1/g'
- }
- if [ ${SW_BLACKLIST_IPV4+x} ]; then
- # ipv4 - reformat as '0.0.0.0 domain-name' pairs
- sed -r "/$REGEX_NOOP/d;s/$REGEX_IP//;s/$REGEX_UBO/\1/" $BLACKLIST_DOM | \
- awk '{print "0.0.0.0 " $1}' | \
- grep -E '^0\.0\.0\.0 [0-9A-z\.-]+$' | \
- sed -r "/$(regex_wl)/d" | \
- sort -u > $BLACKLIST4_TMP
- fi
- if [ ${SW_BLACKLIST_IPV6+x} ]; then
- # ipv6 - reformat as ':: domain-name' pairs
- if [ -s $BLACKLIST4_TMP ]; then
- # for maximum efficiency, base it off ipv4 results when possible
- sed 's/^0\.0\.0\.0/::/' $BLACKLIST4_TMP > $BLACKLIST6_TMP
- else
- sed -r "/$REGEX_NOOP/d;s/$REGEX_IP//;s/$REGEX_UBO/\1/" $BLACKLIST_DOM | \
- awk '{print ":: " $1}' | \
- grep -E '^:: [0-9A-z\.-]+$' | \
- sed -r "/$(regex_wl)/d" | \
- sort -u > $BLACKLIST6_TMP
- fi
- fi
- # cleanup
- rm -f $BLACKLIST $BLACKLIST_DOM $BLACKLIST_TMP
- # report the results
- echo "info: total blacklisted ipv4 domains:" \
- $(wc -l < $BLACKLIST4_TMP) "($(du -h $BLACKLIST4_TMP | cut -f1))"
- echo "info: total blacklisted ipv6 domains:" \
- $(wc -l < $BLACKLIST6_TMP) "($(du -h $BLACKLIST6_TMP | cut -f1))"
- if [ ${SW_DRY_RUN+x} ]; then
- # cleanup
- rm -f $BLACKLIST4_TMP $BLACKLIST6_TMP
- else
- # update dnsmasq blacklists
- mv $BLACKLIST4_TMP $BLACKLIST4
- mv $BLACKLIST6_TMP $BLACKLIST6
- # wait for dnsmasq availability
- until pidof dnsmasq &>/dev/null; do sleep 10; done
- # force dnsmasq to recognize updated blacklists
- killall -HUP dnsmasq
- fi
- # any concurrent instance(s) may now run
- release_lock
- exit 0
- ) 2>&1 | logger -t $(basename $0 | grep -Eo '^.{0,23}')[$$] &
Add Comment
Please, Sign In to add comment