You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1081 lines
28 KiB

  1. #!/bin/sh
  2. # dns based ad/abuse domain blocking
  3. # written by Dirk Brenken (dev@brenken.org)
  4. # This is free software, licensed under the GNU General Public License v3.
  5. # You should have received a copy of the GNU General Public License
  6. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  7. # set initial defaults
  8. #
  9. LC_ALL=C
  10. PATH="/usr/sbin:/usr/bin:/sbin:/bin"
  11. adb_ver="3.5.5-4"
  12. adb_sysver="unknown"
  13. adb_enabled=0
  14. adb_debug=0
  15. adb_backup_mode=0
  16. adb_forcesrt=0
  17. adb_forcedns=0
  18. adb_jail=0
  19. adb_maxqueue=4
  20. adb_notify=0
  21. adb_notifycnt=0
  22. adb_triggerdelay=0
  23. adb_backup=0
  24. adb_backupdir="/mnt"
  25. adb_fetchutil="uclient-fetch"
  26. adb_dns="dnsmasq"
  27. adb_dnsprefix="adb_list"
  28. adb_dnsfile="${adb_dnsprefix}.overall"
  29. adb_dnsjail="${adb_dnsprefix}.jail"
  30. adb_dnsflush=0
  31. adb_whitelist="/etc/adblock/adblock.whitelist"
  32. adb_rtfile="/tmp/adb_runtime.json"
  33. adb_hashutil="$(command -v sha256sum)"
  34. adb_hashold=""
  35. adb_hashnew=""
  36. adb_cnt=""
  37. adb_rc=0
  38. adb_action="${1:-"start"}"
  39. adb_pidfile="/var/run/adblock.pid"
  40. # load adblock environment
  41. #
  42. f_envload()
  43. {
  44. local dns_up sys_call sys_desc sys_model sys_ver cnt=0
  45. # get system information
  46. #
  47. sys_call="$(ubus -S call system board 2>/dev/null)"
  48. if [ -n "${sys_call}" ]
  49. then
  50. sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')"
  51. sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')"
  52. sys_ver="$(cat /etc/turris-version 2>/dev/null)"
  53. if [ -n "${sys_ver}" ]
  54. then
  55. sys_desc="${sys_desc}/${sys_ver}"
  56. fi
  57. adb_sysver="${sys_model}, ${sys_desc}"
  58. fi
  59. # check hash utility
  60. #
  61. if [ ! -x "${adb_hashutil}" ]
  62. then
  63. adb_hashutil="$(command -v md5sum)"
  64. fi
  65. # parse 'global' and 'extra' section by callback
  66. #
  67. config_cb()
  68. {
  69. local type="${1}"
  70. if [ "${type}" = "adblock" ]
  71. then
  72. option_cb()
  73. {
  74. local option="${1}"
  75. local value="${2}"
  76. eval "${option}=\"${value}\""
  77. }
  78. else
  79. reset_cb
  80. fi
  81. }
  82. # parse 'source' typed sections
  83. #
  84. parse_config()
  85. {
  86. local value opt section="${1}" options="enabled adb_src adb_src_rset adb_src_cat"
  87. eval "adb_sources=\"${adb_sources} ${section}\""
  88. for opt in ${options}
  89. do
  90. config_get value "${section}" "${opt}"
  91. if [ -n "${value}" ]
  92. then
  93. eval "${opt}_${section}=\"${value}\""
  94. fi
  95. done
  96. }
  97. # load adblock config
  98. #
  99. config_load adblock
  100. config_foreach parse_config source
  101. # check dns backend
  102. #
  103. case "${adb_dns}" in
  104. dnsmasq)
  105. adb_dnsinstance="${adb_dnsinstance:-"0"}"
  106. adb_dnsuser="${adb_dnsuser:-"dnsmasq"}"
  107. adb_dnsdir="${adb_dnsdir:-"/tmp"}"
  108. adb_dnsheader=""
  109. adb_dnsdeny="awk '{print \"server=/\"\$0\"/\"}'"
  110. adb_dnsallow="awk '{print \"server=/\"\$0\"/#\"}'"
  111. adb_dnshalt="server=/#/"
  112. ;;
  113. unbound)
  114. adb_dnsinstance="${adb_dnsinstance:-"0"}"
  115. adb_dnsuser="${adb_dnsuser:-"unbound"}"
  116. adb_dnsdir="${adb_dnsdir:-"/var/lib/unbound"}"
  117. adb_dnsheader=""
  118. adb_dnsdeny="awk '{print \"local-zone: \042\"\$0\"\042 static\"}'"
  119. adb_dnsallow="awk '{print \"local-zone: \042\"\$0\"\042 transparent\"}'"
  120. adb_dnshalt="local-zone: \".\" static"
  121. ;;
  122. named)
  123. adb_dnsinstance="${adb_dnsinstance:-"0"}"
  124. adb_dnsuser="${adb_dnsuser:-"bind"}"
  125. adb_dnsdir="${adb_dnsdir:-"/var/lib/bind"}"
  126. adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'" IN NS localhost."
  127. adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'"
  128. adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'"
  129. adb_dnshalt="* CNAME ."
  130. ;;
  131. kresd)
  132. adb_dnsinstance="${adb_dnsinstance:-"0"}"
  133. adb_dnsuser="${adb_dnsuser:-"root"}"
  134. adb_dnsdir="${adb_dnsdir:-"/etc/kresd"}"
  135. adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'" IN NS localhost."
  136. adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'"
  137. adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'"
  138. adb_dnshalt="* CNAME ."
  139. ;;
  140. dnscrypt-proxy)
  141. adb_dnsinstance="${adb_dnsinstance:-"0"}"
  142. adb_dnsuser="${adb_dnsuser:-"nobody"}"
  143. adb_dnsdir="${adb_dnsdir:-"/tmp"}"
  144. adb_dnsheader=""
  145. adb_dnsdeny="awk '{print \$0}'"
  146. adb_dnsallow=""
  147. adb_dnshalt=""
  148. ;;
  149. esac
  150. # check adblock status
  151. #
  152. if [ ${adb_enabled} -eq 0 ]
  153. then
  154. f_extconf
  155. f_temp
  156. f_rmdns
  157. f_jsnup "disabled"
  158. f_log "info" "adblock is currently disabled, please set adb_enabled to '1' to use this service"
  159. exit 0
  160. fi
  161. if [ -d "${adb_dnsdir}" ] && [ ! -f "${adb_dnsdir}/${adb_dnsfile}" ]
  162. then
  163. printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
  164. fi
  165. if [ "${adb_action}" = "start" ] && [ "${adb_trigger}" = "timed" ]
  166. then
  167. sleep ${adb_triggerdelay}
  168. fi
  169. while [ ${cnt} -le 30 ]
  170. do
  171. dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" 2>/dev/null | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running" 2>/dev/null)"
  172. if [ "${dns_up}" = "true" ]
  173. then
  174. break
  175. fi
  176. sleep 1
  177. cnt=$((cnt+1))
  178. done
  179. if [ "${dns_up}" != "true" ] || [ -z "${adb_dns}" ] || [ ! -x "$(command -v ${adb_dns})" ]
  180. then
  181. f_log "err" "'${adb_dns}' not running or not executable"
  182. elif [ ! -d "${adb_dnsdir}" ]
  183. then
  184. f_log "err" "'${adb_dnsdir}' backend directory not found"
  185. fi
  186. }
  187. # check environment
  188. #
  189. f_envcheck()
  190. {
  191. local ssl_lib
  192. # startup message
  193. #
  194. f_log "info" "adblock instance started ::: action: ${adb_action}, priority: ${adb_nice:-"0"}, pid: ${$}"
  195. f_jsnup "running"
  196. # check external uci config files
  197. #
  198. f_extconf
  199. # check fetch utility
  200. #
  201. case "${adb_fetchutil}" in
  202. uclient-fetch)
  203. if [ -f "/lib/libustream-ssl.so" ]
  204. then
  205. adb_fetchparm="${adb_fetchparm:-"--timeout=10 --no-check-certificate -O"}"
  206. ssl_lib="libustream-ssl"
  207. else
  208. adb_fetchparm="${adb_fetchparm:-"--timeout=10 -O"}"
  209. fi
  210. ;;
  211. wget)
  212. adb_fetchparm="${adb_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=10 --no-check-certificate -O"}"
  213. ssl_lib="built-in"
  214. ;;
  215. wget-nossl)
  216. adb_fetchparm="${adb_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=10 -O"}"
  217. ;;
  218. busybox)
  219. adb_fetchparm="${adb_fetchparm:-"-O"}"
  220. ;;
  221. curl)
  222. adb_fetchparm="${adb_fetchparm:-"--connect-timeout 10 --insecure -o"}"
  223. ssl_lib="built-in"
  224. ;;
  225. aria2c)
  226. adb_fetchparm="${adb_fetchparm:-"--timeout=10 --allow-overwrite=true --auto-file-renaming=false --check-certificate=false -o"}"
  227. ssl_lib="built-in"
  228. ;;
  229. esac
  230. adb_fetchutil="$(command -v "${adb_fetchutil}")"
  231. if [ ! -x "${adb_fetchutil}" ] || [ -z "${adb_fetchutil}" ] || [ -z "${adb_fetchparm}" ]
  232. then
  233. f_log "err" "download utility not found, please install 'uclient-fetch' with 'libustream-mbedtls' or the full 'wget' package"
  234. fi
  235. adb_fetchinfo="${adb_fetchutil} (${ssl_lib:-"-"})"
  236. f_temp
  237. }
  238. # create temporary files and directories
  239. #
  240. f_temp()
  241. {
  242. if [ -z "${adb_tmpdir}" ]
  243. then
  244. adb_tmpdir="$(mktemp -p /tmp -d)"
  245. adb_tmpload="$(mktemp -p ${adb_tmpdir} -tu)"
  246. adb_tmpfile="$(mktemp -p ${adb_tmpdir} -tu)"
  247. fi
  248. if [ ! -s "${adb_pidfile}" ]
  249. then
  250. printf '%s' "${$}" > "${adb_pidfile}"
  251. fi
  252. }
  253. # remove temporary files and directories
  254. #
  255. f_rmtemp()
  256. {
  257. if [ -d "${adb_tmpdir}" ]
  258. then
  259. rm -rf "${adb_tmpdir}"
  260. fi
  261. > "${adb_pidfile}"
  262. }
  263. # remove dns related files and directories
  264. #
  265. f_rmdns()
  266. {
  267. if [ -n "${adb_dns}" ]
  268. then
  269. f_hash
  270. printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
  271. > "${adb_dnsdir}/.${adb_dnsfile}"
  272. > "${adb_rtfile}"
  273. rm -f "${adb_backupdir}/${adb_dnsprefix}"*.gz
  274. f_hash
  275. if [ ${?} -eq 1 ]
  276. then
  277. f_dnsup
  278. fi
  279. f_rmtemp
  280. fi
  281. f_log "debug" "f_rmdns::: dns: ${adb_dns}, dns_dir: ${adb_dnsdir}, dns_prefix: ${adb_dnsprefix}, dns_file: ${adb_dnsfile}, rt_file: ${adb_rtfile}, backup_dir: ${adb_backupdir}"
  282. }
  283. # commit uci changes
  284. #
  285. f_uci()
  286. {
  287. local change config="${1}"
  288. if [ -n "${config}" ]
  289. then
  290. change="$(uci -q changes "${config}" | awk '{ORS=" "; print $0}')"
  291. if [ -n "${change}" ]
  292. then
  293. uci_commit "${config}"
  294. case "${config}" in
  295. firewall)
  296. /etc/init.d/firewall reload >/dev/null 2>&1
  297. ;;
  298. *)
  299. /etc/init.d/"${adb_dns}" reload >/dev/null 2>&1
  300. ;;
  301. esac
  302. fi
  303. fi
  304. f_log "debug" "f_uci ::: config: ${config}, change: ${change}"
  305. }
  306. # list/overall count
  307. #
  308. f_count()
  309. {
  310. local mode="${1}"
  311. adb_cnt=0
  312. if [ -s "${adb_dnsdir}/${adb_dnsfile}" ] && ([ -z "${mode}" ] || [ "${mode}" = "final" ])
  313. then
  314. adb_cnt="$(( $(wc -l 2>/dev/null < "${adb_dnsdir}/${adb_dnsfile}") ))"
  315. if [ -s "${adb_tmpdir}/tmp.add_whitelist" ]
  316. then
  317. adb_cnt="$(( ${adb_cnt} - $(wc -l 2>/dev/null < "${adb_tmpdir}/tmp.add_whitelist") ))"
  318. fi
  319. if [ "${adb_dns}" = "named" ] || [ "${adb_dns}" = "kresd" ]
  320. then
  321. adb_cnt="$(( (${adb_cnt} - $(printf '%s' "${adb_dnsheader}" | grep -c "^")) / 2 ))"
  322. fi
  323. elif [ -s "${adb_tmpfile}" ]
  324. then
  325. adb_cnt="$(wc -l 2>/dev/null < "${adb_tmpfile}")"
  326. fi
  327. }
  328. # set external config options
  329. #
  330. f_extconf()
  331. {
  332. local uci_config port port_list="53 853 5353"
  333. case "${adb_dns}" in
  334. dnsmasq)
  335. uci_config="dhcp"
  336. if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
  337. then
  338. uci_set dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile "${adb_dnsdir}/${adb_dnsfile}"
  339. elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
  340. then
  341. uci_remove dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile
  342. fi
  343. ;;
  344. kresd)
  345. uci_config="resolver"
  346. if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci_get resolver kresd rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
  347. then
  348. uci -q add_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}"
  349. elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci_get resolver kresd rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ]
  350. then
  351. uci -q del_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}"
  352. fi
  353. if [ ${adb_enabled} -eq 1 ] && [ ${adb_dnsflush} -eq 0 ] && [ "$(uci_get resolver kresd keep_cache)" != "1" ]
  354. then
  355. uci_set resolver kresd keep_cache "1"
  356. elif [ ${adb_enabled} -eq 0 ] || ([ ${adb_dnsflush} -eq 1 ] && [ "$(uci_get resolver kresd keep_cache)" = "1" ])
  357. then
  358. uci_set resolver kresd keep_cache "0"
  359. fi
  360. ;;
  361. esac
  362. f_uci "${uci_config}"
  363. uci_config="firewall"
  364. if [ ${adb_enabled} -eq 1 ] && [ ${adb_forcedns} -eq 1 ] && \
  365. [ -z "$(uci_get firewall adblock_dns_53)" ] && [ $(/etc/init.d/firewall enabled; printf '%u' ${?}) -eq 0 ]
  366. then
  367. for port in ${port_list}
  368. do
  369. uci_add firewall "redirect" "adblock_dns_${port}"
  370. uci_set firewall "adblock_dns_${port}" "name" "Adblock DNS, port ${port}"
  371. uci_set firewall "adblock_dns_${port}" "src" "lan"
  372. uci_set firewall "adblock_dns_${port}" "proto" "tcp udp"
  373. uci_set firewall "adblock_dns_${port}" "src_dport" "${port}"
  374. uci_set firewall "adblock_dns_${port}" "dest_port" "${port}"
  375. uci_set firewall "adblock_dns_${port}" "target" "DNAT"
  376. done
  377. elif [ -n "$(uci_get firewall adblock_dns_53)" ] && ([ ${adb_enabled} -eq 0 ] || [ ${adb_forcedns} -eq 0 ])
  378. then
  379. for port in ${port_list}
  380. do
  381. uci_remove firewall "adblock_dns_${port}"
  382. done
  383. fi
  384. f_uci "${uci_config}"
  385. }
  386. # restart of the dns backend
  387. #
  388. f_dnsup()
  389. {
  390. local dns_up cache_util cache_rc cnt=0
  391. if [ ${adb_dnsflush} -eq 0 ] && [ ${adb_enabled} -eq 1 ] && [ "${adb_rc}" -eq 0 ]
  392. then
  393. case "${adb_dns}" in
  394. dnsmasq)
  395. killall -q -HUP "${adb_dns}"
  396. cache_rc=${?}
  397. ;;
  398. unbound)
  399. cache_util="$(command -v unbound-control)"
  400. if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -f "${adb_dnsdir}"/unbound.conf ]
  401. then
  402. "${cache_util}" -c "${adb_dnsdir}"/unbound.conf dump_cache > "${adb_tmpdir}"/adb_cache.dump 2>/dev/null
  403. fi
  404. "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
  405. ;;
  406. kresd)
  407. cache_util="keep_cache"
  408. "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
  409. cache_rc=${?}
  410. ;;
  411. named)
  412. cache_util="$(command -v rndc)"
  413. if [ -x "${cache_util}" ] && [ -f /etc/bind/rndc.conf ]
  414. then
  415. "${cache_util}" -c /etc/bind/rndc.conf reload >/dev/null 2>&1
  416. cache_rc=${?}
  417. else
  418. "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
  419. fi
  420. ;;
  421. *)
  422. "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
  423. ;;
  424. esac
  425. else
  426. "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1
  427. fi
  428. adb_rc=1
  429. while [ ${cnt} -le 10 ]
  430. do
  431. dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running")"
  432. if [ "${dns_up}" = "true" ]
  433. then
  434. case "${adb_dns}" in
  435. unbound)
  436. cache_util="$(command -v unbound-control)"
  437. if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -s "${adb_tmpdir}"/adb_cache.dump ]
  438. then
  439. while [ ${cnt} -le 10 ]
  440. do
  441. "${cache_util}" -c "${adb_dnsdir}"/unbound.conf load_cache < "${adb_tmpdir}"/adb_cache.dump >/dev/null 2>&1
  442. cache_rc=${?}
  443. if [ ${cache_rc} -eq 0 ]
  444. then
  445. break
  446. fi
  447. cnt=$((cnt+1))
  448. sleep 1
  449. done
  450. fi
  451. ;;
  452. esac
  453. adb_rc=0
  454. break
  455. fi
  456. cnt=$((cnt+1))
  457. sleep 1
  458. done
  459. f_log "debug" "f_dnsup::: cache_util: ${cache_util:-"-"}, cache_rc: ${cache_rc:-"-"}, cache_flush: ${adb_dnsflush}, cache_cnt: ${cnt}, rc: ${adb_rc}"
  460. return ${adb_rc}
  461. }
  462. # backup/restore/remove blocklists
  463. #
  464. f_list()
  465. {
  466. local file mode="${1}" in_rc="${adb_rc}"
  467. case "${mode}" in
  468. backup)
  469. if [ -d "${adb_backupdir}" ]
  470. then
  471. gzip -cf "${adb_tmpfile}" 2>/dev/null > "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz"
  472. adb_rc=${?}
  473. fi
  474. ;;
  475. restore)
  476. if [ -d "${adb_backupdir}" ] && [ -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" ]
  477. then
  478. gunzip -cf "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" 2>/dev/null > "${adb_tmpfile}"
  479. adb_rc=${?}
  480. fi
  481. ;;
  482. remove)
  483. if [ -d "${adb_backupdir}" ]
  484. then
  485. rm -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz"
  486. fi
  487. adb_rc=${?}
  488. ;;
  489. merge)
  490. for file in "${adb_tmpfile}".*
  491. do
  492. cat "${file}" 2>/dev/null >> "${adb_tmpdir}/${adb_dnsfile}"
  493. if [ ${?} -ne 0 ]
  494. then
  495. adb_rc=${?}
  496. break
  497. fi
  498. rm -f "${file}"
  499. done
  500. adb_tmpfile="${adb_tmpdir}/${adb_dnsfile}"
  501. ;;
  502. final)
  503. > "${adb_dnsdir}/${adb_dnsfile}"
  504. if [ -s "${adb_tmpdir}/tmp.add_whitelist" ]
  505. then
  506. cat "${adb_tmpdir}/tmp.add_whitelist" >> "${adb_dnsdir}/${adb_dnsfile}"
  507. fi
  508. if [ -s "${adb_tmpdir}/tmp.rem_whitelist" ]
  509. then
  510. grep -vf "${adb_tmpdir}/tmp.rem_whitelist" "${adb_tmpdir}/${adb_dnsfile}" | eval "${adb_dnsdeny}" >> "${adb_dnsdir}/${adb_dnsfile}"
  511. else
  512. eval "${adb_dnsdeny}" "${adb_tmpdir}/${adb_dnsfile}" >> "${adb_dnsdir}/${adb_dnsfile}"
  513. fi
  514. if [ ${?} -eq 0 ] && [ -n "${adb_dnsheader}" ]
  515. then
  516. printf '%s\n' "${adb_dnsheader}" | cat - "${adb_dnsdir}/${adb_dnsfile}" > "${adb_tmpdir}/${adb_dnsfile}"
  517. mv -f "${adb_tmpdir}/${adb_dnsfile}" "${adb_dnsdir}/${adb_dnsfile}"
  518. fi
  519. adb_rc=${?}
  520. ;;
  521. esac
  522. f_count "${mode}"
  523. f_log "debug" "f_list ::: name: ${src_name:-"-"}, mode: ${mode}, cnt: ${adb_cnt}, in_rc: ${in_rc}, out_rc: ${adb_rc}"
  524. }
  525. # top level domain compression
  526. #
  527. f_tld()
  528. {
  529. local cnt cnt_srt cnt_tld source="${1}" temp="${1}.tld"
  530. cnt="$(wc -l 2>/dev/null < "${source}")"
  531. awk 'BEGIN{FS="."}{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${source}" > "${temp}"
  532. if [ ${?} -eq 0 ]
  533. then
  534. sort -u "${temp}" > "${source}"
  535. if [ ${?} -eq 0 ]
  536. then
  537. cnt_srt="$(wc -l 2>/dev/null < "${source}")"
  538. awk '{if(NR==1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "${source}" > "${temp}"
  539. if [ ${?} -eq 0 ]
  540. then
  541. awk 'BEGIN{FS="."}{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${temp}" > "${source}"
  542. if [ ${?} -eq 0 ]
  543. then
  544. cnt_tld="$(wc -l 2>/dev/null < "${source}")"
  545. else
  546. mv -f "${temp}" > "${source}"
  547. fi
  548. fi
  549. else
  550. mv -f "${temp}" "${source}"
  551. fi
  552. fi
  553. f_log "debug" "f_tld ::: source: ${source}, cnt: ${cnt:-"-"}, cnt_srt: ${cnt_srt:-"-"}, cnt_tld: ${cnt_tld:-"-"}"
  554. }
  555. # blocklist hash compare
  556. #
  557. f_hash()
  558. {
  559. local hash hash_rc=1
  560. if [ -x "${adb_hashutil}" ] && [ -f "${adb_dnsdir}/${adb_dnsfile}" ]
  561. then
  562. hash="$(${adb_hashutil} "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null | awk '{print $1}')"
  563. if [ -z "${adb_hashold}" ] && [ -n "${hash}" ]
  564. then
  565. adb_hashold="${hash}"
  566. elif [ -z "${adb_hashnew}" ] && [ -n "${hash}" ]
  567. then
  568. adb_hashnew="${hash}"
  569. fi
  570. if [ -n "${adb_hashold}" ] && [ -n "${adb_hashnew}" ]
  571. then
  572. if [ "${adb_hashold}" = "${adb_hashnew}" ]
  573. then
  574. hash_rc=0
  575. fi
  576. adb_hashold=""
  577. adb_hashnew=""
  578. fi
  579. fi
  580. f_log "debug" "f_hash ::: hash_util: ${adb_hashutil}, hash: ${hash}, out_rc: ${hash_rc}"
  581. return ${hash_rc}
  582. }
  583. # suspend/resume adblock processing
  584. #
  585. f_switch()
  586. {
  587. local status cnt mode="${1}"
  588. json_get_var status "adblock_status"
  589. json_get_var cnt "overall_domains"
  590. if [ "${mode}" = "suspend" ] && [ "${status}" = "enabled" ]
  591. then
  592. if [ ${cnt%% *} -gt 0 ] && [ -s "${adb_dnsdir}/${adb_dnsfile}" ]
  593. then
  594. f_hash
  595. cat "${adb_dnsdir}/${adb_dnsfile}" > "${adb_dnsdir}/.${adb_dnsfile}"
  596. printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}"
  597. f_hash
  598. fi
  599. elif [ "${mode}" = "resume" ] && [ "${status}" = "paused" ]
  600. then
  601. if [ ${cnt%% *} -gt 0 ] && [ -s "${adb_dnsdir}/.${adb_dnsfile}" ]
  602. then
  603. f_hash
  604. cat "${adb_dnsdir}/.${adb_dnsfile}" > "${adb_dnsdir}/${adb_dnsfile}"
  605. > "${adb_dnsdir}/.${adb_dnsfile}"
  606. f_hash
  607. fi
  608. fi
  609. if [ ${?} -eq 1 ]
  610. then
  611. f_temp
  612. f_dnsup
  613. f_jsnup "${mode}"
  614. f_log "info" "${mode} adblock processing"
  615. f_rmtemp
  616. exit 0
  617. fi
  618. }
  619. # query blocklist for certain (sub-)domains
  620. #
  621. f_query()
  622. {
  623. local search result prefix suffix field domain="${1}" tld="${1#*.}"
  624. if [ -z "${domain}" ] || [ "${domain}" = "${tld}" ]
  625. then
  626. printf '%s\n' "::: invalid domain input, please submit a single domain, e.g. 'doubleclick.net'"
  627. else
  628. case "${adb_dns}" in
  629. dnsmasq)
  630. prefix=".*[\/\.]"
  631. suffix="(\/)"
  632. field=2
  633. ;;
  634. unbound)
  635. prefix=".*[\"\.]"
  636. suffix="(static)"
  637. field=3
  638. ;;
  639. named)
  640. prefix="[^\*].*[\.]"
  641. suffix="( \.)"
  642. field=1
  643. ;;
  644. kresd)
  645. prefix="[^\*].*[\.]"
  646. suffix="( \.)"
  647. field=1
  648. ;;
  649. dnscrypt-proxy)
  650. prefix=".*[\.]"
  651. suffix=""
  652. field=1
  653. ;;
  654. esac
  655. while [ "${domain}" != "${tld}" ]
  656. do
  657. search="${domain//./\.}"
  658. result="$(awk -F '/|\"| ' "/^($search|${prefix}+${search}.*${suffix}$)/{i++;{printf(\" + %s\n\",\$${field})};if(i>9){printf(\" + %s\n\",\"[...]\");exit}}" "${adb_dnsdir}/${adb_dnsfile}")"
  659. printf '%s\n' "::: results for domain '${domain}'"
  660. printf '%s\n' "${result:-" - no match"}"
  661. domain="${tld}"
  662. tld="${domain#*.}"
  663. done
  664. fi
  665. }
  666. # update runtime information
  667. #
  668. f_jsnup()
  669. {
  670. local run_time bg_pid status="${1:-"enabled"}" mode="normal mode" no_mail=0
  671. if [ ${adb_rc} -gt 0 ]
  672. then
  673. status="error"
  674. run_time="$(/bin/date "+%d.%m.%Y %H:%M:%S")"
  675. fi
  676. if [ "${status}" = "enabled" ]
  677. then
  678. run_time="$(/bin/date "+%d.%m.%Y %H:%M:%S")"
  679. fi
  680. if [ "${status}" = "suspend" ]
  681. then
  682. status="paused"
  683. fi
  684. if [ "${status}" = "resume" ]
  685. then
  686. no_mail=1
  687. status="enabled"
  688. fi
  689. if [ ${adb_backup_mode} -eq 1 ]
  690. then
  691. mode="backup mode"
  692. fi
  693. if [ -z "${adb_fetchinfo}" ]
  694. then
  695. json_get_var adb_fetchinfo "fetch_utility"
  696. fi
  697. if [ -z "${adb_cnt}" ]
  698. then
  699. json_get_var adb_cnt "overall_domains"
  700. adb_cnt="${adb_cnt%% *}"
  701. fi
  702. if [ -z "${run_time}" ]
  703. then
  704. json_get_var run_time "last_rundate"
  705. fi
  706. json_add_string "adblock_status" "${status}"
  707. json_add_string "adblock_version" "${adb_ver}"
  708. json_add_string "overall_domains" "${adb_cnt:-0} (${mode})"
  709. json_add_string "fetch_utility" "${adb_fetchinfo:-"-"}"
  710. json_add_string "dns_backend" "${adb_dns} (${adb_dnsdir})"
  711. json_add_string "last_rundate" "${run_time:-"-"}"
  712. json_add_string "system_release" "${adb_sysver}"
  713. json_dump > "${adb_rtfile}"
  714. if [ ${adb_notify} -eq 1 ] && [ ${no_mail} -eq 0 ] && [ -x /etc/adblock/adblock.notify ] && \
  715. ([ "${status}" = "error" ] || ([ "${status}" = "enabled" ] && [ ${adb_cnt} -le ${adb_notifycnt} ]))
  716. then
  717. (/etc/adblock/adblock.notify >/dev/null 2>&1) &
  718. bg_pid=${!}
  719. fi
  720. f_log "debug" "f_jsnup::: status: ${status}, mode: ${mode}, cnt: ${adb_cnt}, notify: ${adb_notify}, notify_cnt: ${adb_notifycnt}, notify_pid: ${bg_pid:-"-"}"
  721. }
  722. # write to syslog
  723. #
  724. f_log()
  725. {
  726. local class="${1}" log_msg="${2}"
  727. if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${adb_debug} -eq 1 ])
  728. then
  729. logger -p "${class}" -t "adblock-${adb_ver}[${$}]" "${log_msg}"
  730. if [ "${class}" = "err" ]
  731. then
  732. f_rmdns
  733. f_jsnup
  734. logger -p "${class}" -t "adblock-${adb_ver}[${$}]" "Please also check 'https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md'"
  735. exit 1
  736. fi
  737. fi
  738. }
  739. # main function for blocklist processing
  740. #
  741. f_main()
  742. {
  743. local tmp_load tmp_file src_name src_rset src_url src_log src_arc src_cat cat list entry suffix mem_total mem_free enabled cnt=1
  744. mem_total="$(awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
  745. mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
  746. tmp_load="${adb_tmpload}"
  747. tmp_file="${adb_tmpfile}"
  748. > "${adb_dnsdir}/.${adb_dnsfile}"
  749. > "${adb_tmpdir}/tmp.raw_whitelist"
  750. > "${adb_tmpdir}/tmp.add_whitelist"
  751. > "${adb_tmpdir}/tmp.rem_whitelist"
  752. f_log "debug" "f_main ::: dns: ${adb_dns}, fetch_util: ${adb_fetchinfo}, backup: ${adb_backup}, backup_mode: ${adb_backup_mode}, dns_jail: ${adb_jail}, force_srt: ${adb_forcesrt}, force_dns: ${adb_forcedns}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${adb_maxqueue}"
  753. # prepare whitelist entries
  754. #
  755. if [ -s "${adb_whitelist}" ]
  756. then
  757. adb_whitelist_rset="/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}"
  758. awk "${adb_whitelist_rset}" "${adb_whitelist}" > "${adb_tmpdir}/tmp.raw_whitelist"
  759. f_tld "${adb_tmpdir}/tmp.raw_whitelist"
  760. adb_whitelist_rset="/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{gsub(\"\\\.\",\"\\\.\",\$1);print tolower(\"^\"\$1\"\\\|\\\.\"\$1)}"
  761. awk "${adb_whitelist_rset}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.rem_whitelist"
  762. if [ -n "${adb_dnsallow}" ]
  763. then
  764. eval "${adb_dnsallow}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.add_whitelist"
  765. fi
  766. fi
  767. # build 'dnsjail' list
  768. #
  769. if [ ${adb_jail} -eq 1 ]
  770. then
  771. cat "${adb_tmpdir}/tmp.add_whitelist" > "/tmp/${adb_dnsjail}"
  772. printf '%s\n' "${adb_dnshalt}" >> "/tmp/${adb_dnsjail}"
  773. if [ -n "${adb_dnsheader}" ]
  774. then
  775. printf '%s\n' "${adb_dnsheader}" | cat - "/tmp/${adb_dnsjail}" > "${adb_tmpdir}/tmp.dnsjail"
  776. cat "${adb_tmpdir}/tmp.dnsjail" > "/tmp/${adb_dnsjail}"
  777. fi
  778. fi
  779. # main loop
  780. #
  781. for src_name in ${adb_sources}
  782. do
  783. enabled="$(eval printf '%s' \"\${enabled_${src_name}\}\")"
  784. src_url="$(eval printf '%s' \"\${adb_src_${src_name}\}\")"
  785. src_rset="$(eval printf '%s' \"\${adb_src_rset_${src_name}\}\")"
  786. src_cat="$(eval printf '%s' \"\${adb_src_cat_${src_name}\}\")"
  787. adb_tmpload="${tmp_load}.${src_name}"
  788. adb_tmpfile="${tmp_file}.${src_name}"
  789. # basic pre-checks
  790. #
  791. f_log "debug" "f_main ::: name: ${src_name}, enabled: ${enabled}"
  792. if [ "${enabled}" != "1" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ]
  793. then
  794. f_list remove
  795. continue
  796. fi
  797. # backup mode
  798. #
  799. if [ ${adb_backup_mode} -eq 1 ] && [ "${adb_action}" = "start" ] && [ "${src_name}" != "blacklist" ]
  800. then
  801. f_list restore
  802. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
  803. then
  804. if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
  805. then
  806. f_tld "${adb_tmpfile}"
  807. fi
  808. continue
  809. fi
  810. fi
  811. # download queue processing
  812. #
  813. if [ "${src_name}" = "blacklist" ]
  814. then
  815. if [ -s "${src_url}" ]
  816. then
  817. (
  818. src_log="$(cat "${src_url}" > "${adb_tmpload}" 2>&1)"
  819. adb_rc=${?}
  820. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
  821. then
  822. awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
  823. adb_rc=${?}
  824. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
  825. then
  826. rm -f "${adb_tmpload}"
  827. f_list download
  828. if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
  829. then
  830. f_tld "${adb_tmpfile}"
  831. fi
  832. fi
  833. else
  834. src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
  835. f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
  836. fi
  837. ) &
  838. else
  839. continue
  840. fi
  841. elif [ -n "${src_cat}" ]
  842. then
  843. (
  844. src_arc="${adb_tmpdir}/${src_url##*/}"
  845. src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${src_arc}" "${src_url}" 2>&1)"
  846. adb_rc=${?}
  847. if [ ${adb_rc} -eq 0 ] && [ -s "${src_arc}" ]
  848. then
  849. list="$(tar -tzf "${src_arc}")"
  850. suffix="$(eval printf '%s' \"\${adb_src_suffix_${src_name}:-\"domains\"\}\")"
  851. for cat in ${src_cat}
  852. do
  853. entry="$(printf '%s' "${list}" | grep -E "[\^/]+${cat}/${suffix}")"
  854. if [ -n "${entry}" ]
  855. then
  856. tar -xOzf "${src_arc}" "${entry}" >> "${adb_tmpload}"
  857. adb_rc=${?}
  858. if [ ${adb_rc} -ne 0 ]
  859. then
  860. break
  861. fi
  862. fi
  863. done
  864. else
  865. src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
  866. f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
  867. fi
  868. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
  869. then
  870. rm -f "${src_arc}"
  871. awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
  872. adb_rc=${?}
  873. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
  874. then
  875. rm -f "${adb_tmpload}"
  876. f_list download
  877. if [ ${adb_backup} -eq 1 ]
  878. then
  879. f_list backup
  880. fi
  881. if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
  882. then
  883. f_tld "${adb_tmpfile}"
  884. fi
  885. elif [ ${adb_backup} -eq 1 ]
  886. then
  887. f_list restore
  888. fi
  889. elif [ ${adb_backup} -eq 1 ]
  890. then
  891. f_list restore
  892. fi
  893. ) &
  894. else
  895. (
  896. src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${adb_tmpload}" "${src_url}" 2>&1)"
  897. adb_rc=${?}
  898. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ]
  899. then
  900. awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}"
  901. adb_rc=${?}
  902. if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ]
  903. then
  904. rm -f "${adb_tmpload}"
  905. f_list download
  906. if [ ${adb_backup} -eq 1 ]
  907. then
  908. f_list backup
  909. fi
  910. if ([ ${mem_total} -lt 64 ] || [ ${mem_free} -lt 40 ]) && [ ${adb_forcesrt} -eq 0 ]
  911. then
  912. f_tld "${adb_tmpfile}"
  913. fi
  914. elif [ ${adb_backup} -eq 1 ]
  915. then
  916. f_list restore
  917. fi
  918. else
  919. src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
  920. f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}"
  921. if [ ${adb_backup} -eq 1 ]
  922. then
  923. f_list restore
  924. fi
  925. fi
  926. ) &
  927. fi
  928. hold=$(( cnt % adb_maxqueue ))
  929. if [ ${hold} -eq 0 ]
  930. then
  931. wait
  932. fi
  933. cnt=$(( cnt + 1 ))
  934. done
  935. # list merge
  936. #
  937. wait
  938. src_name="overall"
  939. adb_tmpfile="${tmp_file}"
  940. f_list merge
  941. # overall sort and conditional dns restart
  942. #
  943. f_hash
  944. if [ -s "${adb_tmpdir}/${adb_dnsfile}" ]
  945. then
  946. if ([ ${mem_total} -ge 64 ] && [ ${mem_free} -ge 40 ]) || [ ${adb_forcesrt} -eq 1 ]
  947. then
  948. f_tld "${adb_tmpdir}/${adb_dnsfile}"
  949. fi
  950. f_list final
  951. else
  952. > "${adb_dnsdir}/${adb_dnsfile}"
  953. fi
  954. chown "${adb_dnsuser}" "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null
  955. f_hash
  956. if [ ${?} -eq 1 ]
  957. then
  958. f_dnsup
  959. fi
  960. f_jsnup
  961. if [ ${?} -eq 0 ]
  962. then
  963. f_log "info" "blocklist with overall ${adb_cnt} domains loaded successfully (${adb_sysver})"
  964. else
  965. f_log "err" "dns backend restart with active blocklist failed"
  966. fi
  967. f_rmtemp
  968. exit ${adb_rc}
  969. }
  970. # source required system libraries
  971. #
  972. if [ -r "/lib/functions.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
  973. then
  974. . "/lib/functions.sh"
  975. . "/usr/share/libubox/jshn.sh"
  976. else
  977. f_log "err" "system libraries not found"
  978. fi
  979. # initialize json runtime file
  980. #
  981. json_load_file "${adb_rtfile}" >/dev/null 2>&1
  982. json_select data >/dev/null 2>&1
  983. if [ ${?} -ne 0 ]
  984. then
  985. > "${adb_rtfile}"
  986. json_init
  987. json_add_object "data"
  988. fi
  989. # handle different adblock actions
  990. #
  991. f_envload
  992. case "${adb_action}" in
  993. stop)
  994. f_rmdns
  995. ;;
  996. restart)
  997. f_rmdns
  998. f_envcheck
  999. f_main
  1000. ;;
  1001. suspend)
  1002. f_switch suspend
  1003. ;;
  1004. resume)
  1005. f_switch resume
  1006. ;;
  1007. query)
  1008. f_query "${2}"
  1009. ;;
  1010. start|reload)
  1011. f_envcheck
  1012. f_main
  1013. ;;
  1014. esac