eibgrad

ddwrt-blacklist-domains.sh

Jun 22nd, 2019 (edited)
4,180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.78 KB | None | 0 0
  1. #!/bin/sh
  2. #DEBUG=; set -x # comment/uncomment to disable/enable debug mode
  3.  
  4. #          name: ddwrt-blacklist-domains.sh
  5. #       version: 4.2.0, 27-apr-2024, by eibgrad
  6. #       purpose: blacklist specific domains in dnsmasq (dns)
  7. #   script type: startup (autostart)
  8. #  installation:
  9. #    1. enable jffs2 (administration->jffs2)
  10. #    2. enable syslogd (services->services->system log)
  11. #    3. use shell (telnet/ssh) to execute one of the following commands:
  12. #         curl -kLs bit.ly/ddwrt-installer|tr -d '\r'|sh -s aySi7RhY startup
  13. #       or
  14. #         wget -qO - bit.ly/ddwrt-installer|tr -d '\r'|sh -s aySi7RhY startup
  15. #    4. add the following to the "additional dnsmasq options" field on the
  16. #           services page:
  17. #         addn-hosts=/tmp/blacklisted_domains_ipv4
  18. #         addn-hosts=/tmp/blacklisted_domains_ipv6
  19. #    5. (optional) modify options using vi editor:
  20. #         vi /jffs/etc/config/ddwrt-blacklist-domains.startup
  21. #    6. (optional) enable cron (administration->management) and add the
  22. #           following job:
  23. #         0 4 * * * root /jffs/etc/config/ddwrt-blacklist-domains.startup
  24. #    7. reboot
  25. (
  26. # ------------------------------ BEGIN OPTIONS ------------------------------- #
  27.  
  28. # domains to be blacklisted
  29. BLACKLIST="/tmp/tmp.$$.blacklist"
  30.  
  31. # note: nested blacklists are supported; any blacklist may contain domain
  32. #       names and/or urls; those urls in turn may contain lists of other
  33. #       domain names and/or urls; url references may be either remote
  34. #       (http://|https://) or local (file://)
  35. # note: both ipv4 and ipv6 blacklisting are supported, however, ipv6 is
  36. #       disabled by default (see SW_BLACKLIST_IPV6)
  37. # note: firebog.net is an excellent source of curated blacklists,
  38. #       including "lists of lists" (https://v.firebog.net/hosts/lists.php)
  39. # note: exercise caution when using certain urls; these sometimes contain
  40. #       *very* large lists of blacklisted domains, which may exceed the memory
  41. #       capacity of the router and/or dnsmasq, and *may* have a detrimental
  42. #       affect on dns performance; in the worst cases, it may crash dnsmasq
  43. #       or even spontaneously reboot the router; consider using the --dry-run
  44. #       command-line option to determine the number of domains (via the
  45. #       syslog) that will be blacklisted before committing them to dnsmasq
  46. cat << 'EOF' > $BLACKLIST
  47. #facebook.com
  48. #www.facebook.com
  49. #whitehouse.gov
  50. #www.whitehouse.gov
  51. #file:///jffs/my_personal_blacklist
  52. https://v.firebog.net/hosts/lists.php?type=nocross # list of lists
  53. #https://raw.githubusercontent.com/chadmayfield/my-pihole-blocklists/master/lists/pi_blocklist_porn_top1m.list
  54. #https://v.firebog.net/hosts/Prigent-Adult.txt # CAUTION: EXTREMELY LARGE (in the many millions)
  55. #https://raw.githubusercontent.com/anudeepND/blacklist/master/facebook.txt
  56. EOF
  57.  
  58. # exceptions: domains (and their sub-domains) NOT to be blacklisted
  59.  
  60. # note: matching only occurs on whole parts of the domain name, moving right
  61. #       to left; for example, adding somedomain.com to the whitelist would
  62. #       also match xyz.somedomain.com, but NOT match xyzsomedomain.com nor
  63. #       xyz.somedomain.com.us; wildcards (*) are NOT supported and will be
  64. #       removed
  65. WHITELIST='
  66. localhost
  67. example-allow-this-domain.com
  68. '
  69.  
  70. # comment/uncomment to disable/enable ipv4 blacklist
  71. SW_BLACKLIST_IPV4=
  72. # comment/uncomment to disable/enable ipv6 blacklist
  73. #SW_BLACKLIST_IPV6=
  74.  
  75. # maximum time (in secs) allotted for curl to establish connection
  76. MAX_WAIT=60
  77. # maximum time (in secs) allotted for curl/wget to complete all operations
  78. MAX_TIME=120
  79.  
  80. # ------------------------------- END OPTIONS -------------------------------- #
  81.  
  82. # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
  83.  
  84. # required for serialization when reentry is possible
  85. LOCK="/tmp/$(basename $0).lock"
  86. acquire_lock() {
  87.     if ! mkdir $LOCK &>/dev/null; then
  88.         echo "error: already running, this run aborted"
  89.         rm -f $BLACKLIST
  90.         exit 1
  91.     fi
  92. }
  93. release_lock() { rmdir $LOCK &>/dev/null; }
  94.  
  95. # default to curl, failover to wget (not guaranteed to support tls)
  96. which curl &>/dev/null && \
  97.     GET_URL="curl -sLk --connect-timeout $MAX_WAIT --max-time $MAX_TIME" || \
  98.     GET_URL="wget -T $MAX_TIME -qO -"
  99.  
  100. # useful/common regular expressions
  101. REGEX_NOOP='^[[:space:]]*(#|$)'
  102. REGEX_URL='^[[:space:]]*(http|https|file)://'
  103. REGEX_IP='^[[:space:]]*([0-9]{1,3}\.){3}[0-9]{1,3}'
  104. REGEX_UBO='^[[:space:]]*\|\|([^^]*)(\^|)$' # ublock origin formatting
  105.  
  106. # work/interim files
  107. BLACKLIST_DOM="/tmp/tmp.$$.blacklist_dom"
  108. BLACKLIST_TMP="/tmp/tmp.$$.blacklist_tmp"
  109. BLACKLIST4_TMP="/tmp/tmp.$$.blacklist4_tmp"
  110. BLACKLIST6_TMP="/tmp/tmp.$$.blacklist6_tmp"
  111.  
  112. # blacklisted domains referenced in dnsmasq config
  113. BLACKLIST4='/tmp/blacklisted_domains_ipv4'
  114. BLACKLIST6='/tmp/blacklisted_domains_ipv6'
  115.  
  116. # validate command-line args/options
  117. if [ "$1" ]; then
  118.     if [ "$1" != '--dry-run' ]; then
  119.         echo "error: unknown argument/option: $1"
  120.         rm -f $BLACKLIST
  121.         exit 1
  122.     fi
  123.     SW_DRY_RUN=
  124. fi
  125.  
  126. # wait for wan availability
  127. until ping -qc1 -W3 8.8.8.8 &>/dev/null; do sleep 10; done
  128.  
  129. # one instance at a time
  130. acquire_lock
  131.  
  132. # catch premature exit and cleanup
  133. trap 'release_lock; exit 1' SIGHUP SIGINT SIGTERM
  134.  
  135. while read line; do
  136.     # skip comments and blank lines
  137.     echo $line | grep -Eq "$REGEX_NOOP" && continue
  138.  
  139.     # isolate url/domain by removing any trailing comments
  140.     line="$(echo $line | awk '{print $1}')"
  141.  
  142.     if echo $line | grep -Eq "$REGEX_URL"; then
  143.         # retrieve the file
  144.         $GET_URL $line > $BLACKLIST_TMP || { echo "error: $line"; continue; }
  145.  
  146.         # split file contents into urls and domains
  147.         grep -E  "$REGEX_URL" $BLACKLIST_TMP >> $BLACKLIST
  148.         grep -Ev "$REGEX_URL" $BLACKLIST_TMP >> $BLACKLIST_DOM
  149.     else
  150.         # save the domain
  151.         echo $line >> $BLACKLIST_DOM
  152.     fi
  153.  
  154. done < $BLACKLIST
  155.  
  156. > $BLACKLIST4_TMP
  157. > $BLACKLIST6_TMP
  158.  
  159. # function regex_wl()
  160. regex_wl() {
  161.     echo $WHITELIST | \
  162.         sed -r 's/\*//g;s/ |$/$|/g;s/\|$//;s/\./\\./g;s/([^|]*)/[ .]\1/g'
  163. }
  164.  
  165. if [ ${SW_BLACKLIST_IPV4+x} ]; then
  166.     # ipv4 - reformat as '0.0.0.0 domain-name' pairs
  167.     sed -r "/$REGEX_NOOP/d;s/$REGEX_IP//;s/$REGEX_UBO/\1/" $BLACKLIST_DOM | \
  168.         awk '{print "0.0.0.0 " $1}' | \
  169.             grep -E '^0\.0\.0\.0 [0-9A-z\.-]+$' | \
  170.                 sed -r "/$(regex_wl)/d" | \
  171.                     sort -u > $BLACKLIST4_TMP
  172. fi
  173.  
  174. if [ ${SW_BLACKLIST_IPV6+x} ]; then
  175.     # ipv6 - reformat as ':: domain-name' pairs
  176.     if [ -s $BLACKLIST4_TMP ]; then
  177.         # for maximum efficiency, base it off ipv4 results when possible
  178.         sed 's/^0\.0\.0\.0/::/' $BLACKLIST4_TMP > $BLACKLIST6_TMP
  179.     else
  180.         sed -r "/$REGEX_NOOP/d;s/$REGEX_IP//;s/$REGEX_UBO/\1/" $BLACKLIST_DOM | \
  181.             awk '{print ":: " $1}' | \
  182.                 grep -E '^:: [0-9A-z\.-]+$' | \
  183.                     sed -r "/$(regex_wl)/d" | \
  184.                         sort -u > $BLACKLIST6_TMP
  185.     fi
  186. fi
  187.  
  188. # cleanup
  189. rm -f $BLACKLIST $BLACKLIST_DOM $BLACKLIST_TMP
  190.  
  191. # report the results
  192. echo "info: total blacklisted ipv4 domains:" \
  193.     $(wc -l < $BLACKLIST4_TMP) "($(du -h $BLACKLIST4_TMP | cut -f1))"
  194. echo "info: total blacklisted ipv6 domains:" \
  195.     $(wc -l < $BLACKLIST6_TMP) "($(du -h $BLACKLIST6_TMP | cut -f1))"
  196.  
  197. if [ ${SW_DRY_RUN+x} ]; then
  198.     # cleanup
  199.     rm -f $BLACKLIST4_TMP $BLACKLIST6_TMP
  200. else
  201.     # update dnsmasq blacklists
  202.     mv $BLACKLIST4_TMP $BLACKLIST4
  203.     mv $BLACKLIST6_TMP $BLACKLIST6
  204.  
  205.     # wait for dnsmasq availability
  206.     until pidof dnsmasq &>/dev/null; do sleep 10; done
  207.  
  208.     # force dnsmasq to recognize updated blacklists
  209.     killall -HUP dnsmasq
  210. fi
  211.  
  212. # any concurrent instance(s) may now run
  213. release_lock
  214.  
  215. exit 0
  216.  
  217. ) 2>&1 | logger -t $(basename $0 | grep -Eo '^.{0,23}')[$$] &
Add Comment
Please, Sign In to add comment