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.

761 lines
23 KiB

  1. #!/bin/sh
  2. # function library used by adblock-update.sh
  3. # written by Dirk Brenken (dev@brenken.org)
  4. # set initial defaults
  5. #
  6. LC_ALL=C
  7. PATH="/usr/sbin:/usr/bin:/sbin:/bin"
  8. adb_hotplugif=""
  9. adb_lanif="lan"
  10. adb_nullport="65534"
  11. adb_nullportssl="65535"
  12. adb_nullipv4="198.18.0.1"
  13. adb_nullipv6="::ffff:c612:0001"
  14. adb_whitelist="/etc/adblock/adblock.whitelist"
  15. adb_whitelist_rset="\$1 ~/^([A-Za-z0-9_-]+\.){1,}[A-Za-z]+/{print tolower(\"^\"\$1\"\\\|[.]\"\$1)}"
  16. adb_dnsdir="/tmp/dnsmasq.d"
  17. adb_dnshidedir="${adb_dnsdir}/.adb_hidden"
  18. adb_dnsprefix="adb_list"
  19. adb_count=0
  20. adb_minspace=12000
  21. adb_forcedns=1
  22. adb_fetchttl=5
  23. adb_restricted=0
  24. adb_uci="$(which uci)"
  25. # f_envload: load adblock environment
  26. #
  27. f_envload()
  28. {
  29. # source in system function library
  30. #
  31. if [ -r "/lib/functions.sh" ]
  32. then
  33. . "/lib/functions.sh"
  34. else
  35. rc=-10
  36. f_log "system function library not found, please check your installation"
  37. f_exit
  38. fi
  39. # source in system network library
  40. #
  41. if [ -r "/lib/functions/network.sh" ]
  42. then
  43. . "/lib/functions/network.sh"
  44. else
  45. rc=-10
  46. f_log "system network library not found, please check your installation"
  47. f_exit
  48. fi
  49. # check opkg availability
  50. #
  51. if [ -f "/var/lock/opkg.lock" ]
  52. then
  53. rc=-10
  54. f_log "adblock installation finished successfully, 'opkg' currently locked by package installer"
  55. f_exit
  56. fi
  57. # uci function to parse global section by callback
  58. #
  59. config_cb()
  60. {
  61. local type="${1}"
  62. if [ "${type}" = "adblock" ]
  63. then
  64. option_cb()
  65. {
  66. local option="${1}"
  67. local value="${2}"
  68. eval "${option}=\"${value}\""
  69. }
  70. else
  71. reset_cb
  72. fi
  73. }
  74. # uci function to parse 'service' and 'source' sections
  75. #
  76. parse_config()
  77. {
  78. local value opt section="${1}" options="enabled adb_dir adb_src adb_src_rset adb_src_cat"
  79. if [ "${section}" != "backup" ]
  80. then
  81. eval "adb_sources=\"${adb_sources} ${section}\""
  82. fi
  83. for opt in ${options}
  84. do
  85. config_get value "${section}" "${opt}"
  86. if [ -n "${value}" ]
  87. then
  88. eval "${opt}_${section}=\"${value}\""
  89. fi
  90. done
  91. }
  92. # load adblock config and start parsing functions
  93. #
  94. config_load adblock
  95. config_foreach parse_config service
  96. config_foreach parse_config source
  97. # get network basics
  98. #
  99. network_get_ipaddr adb_ipv4 "${adb_lanif}"
  100. network_get_ipaddr6 adb_ipv6 "${adb_lanif}"
  101. network_get_device adb_landev "${adb_lanif}"
  102. network_find_wan adb_wanif4
  103. network_find_wan6 adb_wanif6
  104. }
  105. # f_envcheck: check/set environment prerequisites
  106. #
  107. f_envcheck()
  108. {
  109. local check
  110. # check 'enabled' & 'version' config options
  111. #
  112. if [ -z "${adb_enabled}" ] || [ -z "${adb_cfgver}" ] || [ "${adb_cfgver%%.*}" != "${adb_mincfgver%%.*}" ]
  113. then
  114. rc=-1
  115. f_log "outdated adblock config (${adb_mincfgver} vs. ${adb_cfgver}), please run '/etc/init.d/adblock cfgup' to update your configuration"
  116. f_exit
  117. elif [ "${adb_cfgver#*.}" != "${adb_mincfgver#*.}" ]
  118. then
  119. outdated_ok="true"
  120. fi
  121. if [ "${adb_enabled}" != "1" ]
  122. then
  123. rc=-10
  124. f_log "adblock is currently disabled, please set adblock.global.adb_enabled=1' to use this service"
  125. f_exit
  126. fi
  127. # get list with all installed packages
  128. #
  129. pkg_list="$(opkg list-installed)"
  130. if [ -z "${pkg_list}" ]
  131. then
  132. rc=-1
  133. f_log "empty 'opkg' package list, please check your installation"
  134. f_exit
  135. fi
  136. adb_sysver="$(printf "${pkg_list}" | grep "^base-files -")"
  137. adb_sysver="${adb_sysver##*-}"
  138. # get lan ip addresses
  139. #
  140. if [ -z "${adb_ipv4}" ] && [ -z "${adb_ipv6}" ]
  141. then
  142. rc=-1
  143. f_log "no valid IPv4/IPv6 configuration found (${adb_lanif}), please set 'adb_lanif' manually"
  144. f_exit
  145. fi
  146. # check logical update interfaces (with default route)
  147. #
  148. if [ -z "${adb_wanif4}" ] && [ -z "${adb_wanif6}" ]
  149. then
  150. adb_wanif4="${adb_lanif}"
  151. fi
  152. # check AP mode
  153. #
  154. if [ "${adb_wanif4}" = "${adb_lanif}" ] || [ "${adb_wanif6}" = "${adb_lanif}" ]
  155. then
  156. adb_nullipv4="${adb_ipv4}"
  157. adb_nullipv6="${adb_ipv6}"
  158. if [ -n "$(${adb_uci} -q get uhttpd.main.listen_http | grep -Fo "80")" ] ||
  159. [ -n "$(${adb_uci} -q get uhttpd.main.listen_https | grep -Fo "443")" ]
  160. then
  161. rc=-1
  162. f_log "AP mode detected, please set local LuCI instance to ports <> 80/443"
  163. f_exit
  164. elif [ ! -f "/etc/init.d/dnsmasq" ]
  165. then
  166. rc=-1
  167. f_log "please enable the local dnsmasq instance to use adblock"
  168. f_exit
  169. elif [ ! -f "/var/run/fw3.state" ]
  170. then
  171. rc=-1
  172. f_log "please enable the local firewall to use adblock"
  173. f_exit
  174. else
  175. apmode_ok="true"
  176. fi
  177. else
  178. apmode_ok="false"
  179. check="$(${adb_uci} -q get bcp38.@bcp38[0].enabled)"
  180. if [ "${check}" = "1" ]
  181. then
  182. if [ -n "$(${adb_uci} -q get bcp38.@bcp38[0].match | grep -Fo "${adb_nullipv4%.*}")" ]
  183. then
  184. rc=-1
  185. f_log "please whitelist '${adb_nullipv4}' in your bcp38 configuration to use adblock"
  186. f_exit
  187. fi
  188. fi
  189. fi
  190. # check general package dependencies
  191. #
  192. f_depend "busybox"
  193. f_depend "uci"
  194. f_depend "uhttpd"
  195. f_depend "iptables"
  196. f_depend "kmod-ipt-nat"
  197. # check ipv6 related package dependencies
  198. #
  199. if [ -n "${adb_wanif6}" ]
  200. then
  201. f_depend "ip6tables" "true"
  202. if [ "${package_ok}" = "false" ]
  203. then
  204. f_log "package 'ip6tables' not found, IPv6 support will be disabled"
  205. unset adb_wanif6
  206. else
  207. f_depend "kmod-ipt-nat6" "true"
  208. if [ "${package_ok}" = "false" ]
  209. then
  210. f_log "package 'kmod-ipt-nat6' not found, IPv6 support will be disabled"
  211. unset adb_wanif6
  212. fi
  213. fi
  214. fi
  215. # check uclient-fetch/wget dependencies
  216. #
  217. f_depend "uclient-fetch" "true"
  218. if [ "${package_ok}" = "true" ]
  219. then
  220. f_depend "libustream-polarssl" "true"
  221. if [ "${package_ok}" = "false" ]
  222. then
  223. f_depend "libustream-\(mbedtls\|openssl\|cyassl\)" "true"
  224. if [ "${package_ok}" = "true" ]
  225. then
  226. adb_fetch="$(which uclient-fetch)"
  227. fetch_parm="-q --timeout=${adb_fetchttl}"
  228. response_parm="--spider"
  229. fi
  230. fi
  231. fi
  232. if [ -z "${adb_fetch}" ]
  233. then
  234. f_depend "wget" "true"
  235. if [ "${package_ok}" = "true" ]
  236. then
  237. adb_fetch="$(which wget)"
  238. fetch_parm="--no-config --quiet --tries=1 --no-cache --no-cookies --max-redirect=0 --dns-timeout=${adb_fetchttl} --connect-timeout=${adb_fetchttl} --read-timeout=${adb_fetchttl}"
  239. response_parm="--spider --server-response"
  240. else
  241. rc=-1
  242. f_log "please install 'uclient-fetch' or 'wget' with ssl support to use adblock"
  243. f_exit
  244. fi
  245. fi
  246. # check ca-certificate package and set fetch parm accordingly
  247. #
  248. f_depend "ca-certificates" "true"
  249. if [ "${package_ok}" = "false" ]
  250. then
  251. fetch_parm="${fetch_parm} --no-check-certificate"
  252. fi
  253. # start normal processing/logging
  254. #
  255. f_log "domain adblock processing started (${adb_scriptver}, ${adb_sysver}, $(/bin/date "+%d.%m.%Y %H:%M:%S"))"
  256. # log partially outdated config
  257. #
  258. if [ "${outdated_ok}" = "true" ]
  259. then
  260. f_log "partially outdated adblock config (${adb_mincfgver} vs. ${adb_cfgver}), please run '/etc/init.d/adblock cfgup' to update your configuration"
  261. fi
  262. # log ap mode
  263. #
  264. if [ "${apmode_ok}" = "true" ]
  265. then
  266. f_log "AP mode enabled"
  267. fi
  268. # set/log restricted mode
  269. #
  270. if [ "${adb_restricted}" = "1" ]
  271. then
  272. adb_uci="$(which true)"
  273. f_log "Restricted mode enabled"
  274. fi
  275. # check dns hideout directory
  276. #
  277. if [ -d "${adb_dnshidedir}" ]
  278. then
  279. mv_done="$(find "${adb_dnshidedir}" -maxdepth 1 -type f -name "${adb_dnsprefix}*" -print -exec mv -f "{}" "${adb_dnsdir}" \;)"
  280. else
  281. mkdir -p -m 660 "${adb_dnshidedir}"
  282. fi
  283. # check adblock temp directory
  284. #
  285. adb_tmpfile="$(mktemp -tu)"
  286. adb_tmpdir="$(mktemp -p /tmp -d)"
  287. if [ -n "${adb_tmpdir}" ] && [ -d "${adb_tmpdir}" ]
  288. then
  289. f_space "${adb_tmpdir}"
  290. if [ "${space_ok}" = "false" ]
  291. then
  292. if [ $((av_space)) -le 2000 ]
  293. then
  294. rc=105
  295. f_log "not enough free space in '${adb_tmpdir}' (avail. ${av_space} kb)"
  296. f_exit
  297. else
  298. f_log "not enough free space to handle all block list sources at once in '${adb_tmpdir}' (avail. ${av_space} kb)"
  299. fi
  300. fi
  301. else
  302. rc=110
  303. f_log "temp directory not found"
  304. f_exit
  305. fi
  306. # check memory
  307. #
  308. mem_total="$(awk '$1 ~ /^MemTotal/ {printf $2}' "/proc/meminfo")"
  309. mem_free="$(awk '$1 ~ /^MemFree/ {printf $2}' "/proc/meminfo")"
  310. mem_swap="$(awk '$1 ~ /^SwapTotal/ {printf $2}' "/proc/meminfo")"
  311. if [ $((mem_total)) -le 64000 ] && [ $((mem_swap)) -eq 0 ]
  312. then
  313. mem_ok="false"
  314. f_log "not enough free memory, overall sort processing will be disabled (total: ${mem_total}, free: ${mem_free}, swap: ${mem_swap})"
  315. else
  316. mem_ok="true"
  317. fi
  318. # check backup configuration
  319. #
  320. if [ "${enabled_backup}" = "1" ] && [ -d "${adb_dir_backup}" ]
  321. then
  322. f_space "${adb_dir_backup}"
  323. if [ "${space_ok}" = "false" ]
  324. then
  325. f_log "not enough free space in '${adb_dir_backup}'(avail. ${av_space} kb), backup/restore will be disabled"
  326. backup_ok="false"
  327. else
  328. f_log "backup/restore will be enabled"
  329. backup_ok="true"
  330. fi
  331. else
  332. backup_ok="false"
  333. f_log "backup/restore will be disabled"
  334. fi
  335. # set dnsmasq defaults
  336. #
  337. if [ -n "${adb_wanif4}" ] && [ -n "${adb_wanif6}" ]
  338. then
  339. adb_dnsformat="awk -v ipv4="${adb_nullipv4}" -v ipv6="${adb_nullipv6}" '{print \"address=/\"\$0\"/\"ipv4\"\n\"\"address=/\"\$0\"/\"ipv6}'"
  340. elif [ -n "${adb_wanif4}" ]
  341. then
  342. adb_dnsformat="awk -v ipv4="${adb_nullipv4}" '{print \"address=/\"\$0\"/\"ipv4}'"
  343. else
  344. adb_dnsformat="awk -v ipv6="${adb_nullipv6}" '{print \"address=/\"\$0\"/\"ipv6}'"
  345. fi
  346. # check volatile iptables configuration
  347. #
  348. if [ -n "${adb_wanif4}" ]
  349. then
  350. if [ "${apmode_ok}" = "false" ]
  351. then
  352. if [ "${adb_forcedns}" = "1" ] && [ -n "${adb_landev}" ]
  353. then
  354. f_firewall "IPv4" "nat" "prerouting_rule" "adb-dns" "1" "dns" "-p udp --dport 53 -j DNAT --to-destination ${adb_ipv4}:53"
  355. f_firewall "IPv4" "nat" "prerouting_rule" "adb-dns" "2" "dns" "-p tcp --dport 53 -j DNAT --to-destination ${adb_ipv4}:53"
  356. fi
  357. f_firewall "IPv4" "filter" "forwarding_rule" "adb-fwd" "1" "fwd" "-p tcp -j REJECT --reject-with tcp-reset"
  358. f_firewall "IPv4" "filter" "forwarding_rule" "adb-fwd" "2" "fwd" "-j REJECT --reject-with icmp-host-unreachable"
  359. f_firewall "IPv4" "filter" "output_rule" "adb-out" "1" "out" "-p tcp -j REJECT --reject-with tcp-reset"
  360. f_firewall "IPv4" "filter" "output_rule" "adb-out" "2" "out" "-j REJECT --reject-with icmp-host-unreachable"
  361. fi
  362. f_firewall "IPv4" "nat" "prerouting_rule" "adb-nat" "1" "nat" "-p tcp --dport 80 -j DNAT --to-destination ${adb_ipv4}:${adb_nullport}"
  363. f_firewall "IPv4" "nat" "prerouting_rule" "adb-nat" "2" "nat" "-p tcp --dport 443 -j DNAT --to-destination ${adb_ipv4}:${adb_nullportssl}"
  364. fi
  365. if [ -n "${adb_wanif6}" ]
  366. then
  367. if [ "${apmode_ok}" = "false" ]
  368. then
  369. if [ "${adb_forcedns}" = "1" ] && [ -n "${adb_landev}" ]
  370. then
  371. f_firewall "IPv6" "nat" "PREROUTING" "adb-dns" "1" "dns" "-p udp --dport 53 -j DNAT --to-destination [${adb_ipv6}]:53"
  372. f_firewall "IPv6" "nat" "PREROUTING" "adb-dns" "2" "dns" "-p tcp --dport 53 -j DNAT --to-destination [${adb_ipv6}]:53"
  373. fi
  374. f_firewall "IPv6" "filter" "forwarding_rule" "adb-fwd" "1" "fwd" "-p tcp -j REJECT --reject-with tcp-reset"
  375. f_firewall "IPv6" "filter" "forwarding_rule" "adb-fwd" "2" "fwd" "-j REJECT --reject-with icmp6-addr-unreachable"
  376. f_firewall "IPv6" "filter" "output_rule" "adb-out" "1" "out" "-p tcp -j REJECT --reject-with tcp-reset"
  377. f_firewall "IPv6" "filter" "output_rule" "adb-out" "2" "out" "-j REJECT --reject-with icmp6-addr-unreachable"
  378. fi
  379. f_firewall "IPv6" "nat" "PREROUTING" "adb-nat" "1" "nat" "-p tcp --dport 80 -j DNAT --to-destination [${adb_ipv6}]:${adb_nullport}"
  380. f_firewall "IPv6" "nat" "PREROUTING" "adb-nat" "2" "nat" "-p tcp --dport 443 -j DNAT --to-destination [${adb_ipv6}]:${adb_nullportssl}"
  381. fi
  382. if [ "${firewall_ok}" = "true" ]
  383. then
  384. f_log "created volatile firewall rulesets"
  385. fi
  386. # check volatile uhttpd instance configuration
  387. #
  388. if [ -n "${adb_wanif4}" ] && [ -n "${adb_wanif6}" ]
  389. then
  390. f_uhttpd "adbIPv4+6_80" "1" "-p ${adb_ipv4}:${adb_nullport} -p [${adb_ipv6}]:${adb_nullport}"
  391. f_uhttpd "adbIPv4+6_443" "0" "-p ${adb_ipv4}:${adb_nullportssl} -p [${adb_ipv6}]:${adb_nullportssl}"
  392. elif [ -n "${adb_wanif4}" ]
  393. then
  394. f_uhttpd "adbIPv4_80" "1" "-p ${adb_ipv4}:${adb_nullport}"
  395. f_uhttpd "adbIPv4_443" "0" "-p ${adb_ipv4}:${adb_nullportssl}"
  396. else
  397. f_uhttpd "adbIPv6_80" "1" "-p [${adb_ipv6}]:${adb_nullport}"
  398. f_uhttpd "adbIPv6_443" "0" "-p [${adb_ipv6}]:${adb_nullportssl}"
  399. fi
  400. if [ "${uhttpd_ok}" = "true" ]
  401. then
  402. f_log "created volatile uhttpd instances"
  403. fi
  404. # check whitelist entries
  405. #
  406. if [ -s "${adb_whitelist}" ]
  407. then
  408. awk "${adb_whitelist_rset}" "${adb_whitelist}" > "${adb_tmpdir}/tmp.whitelist"
  409. fi
  410. # remove temporary package list
  411. #
  412. unset pkg_list
  413. }
  414. # f_depend: check package dependencies
  415. #
  416. f_depend()
  417. {
  418. local check
  419. local package="${1}"
  420. local check_only="${2}"
  421. package_ok="true"
  422. check="$(printf "${pkg_list}" | grep "^${package} -")"
  423. if [ "${check_only}" = "true" ] && [ -z "${check}" ]
  424. then
  425. package_ok="false"
  426. elif [ -z "${check}" ]
  427. then
  428. rc=-1
  429. f_log "package '${package}' not found"
  430. f_exit
  431. fi
  432. }
  433. # f_firewall: set iptables rules for ipv4/ipv6
  434. #
  435. f_firewall()
  436. {
  437. local ipt="iptables"
  438. local nullip="${adb_nullipv4}"
  439. local proto="${1}"
  440. local table="${2}"
  441. local chsrc="${3}"
  442. local chain="${4}"
  443. local chpos="${5}"
  444. local notes="adb-${6}"
  445. local rules="${7}"
  446. # select appropriate iptables executable for IPv6
  447. #
  448. if [ "${proto}" = "IPv6" ]
  449. then
  450. ipt="ip6tables"
  451. nullip="${adb_nullipv6}"
  452. fi
  453. # check whether iptables chain already exist
  454. #
  455. rc="$("${ipt}" -w -t "${table}" -nL "${chain}" >/dev/null 2>&1; printf ${?})"
  456. if [ $((rc)) -ne 0 ]
  457. then
  458. "${ipt}" -w -t "${table}" -N "${chain}"
  459. "${ipt}" -w -t "${table}" -A "${chain}" -m comment --comment "${notes}" -j RETURN
  460. if [ "${chain}" = "adb-dns" ]
  461. then
  462. "${ipt}" -w -t "${table}" -A "${chsrc}" -i "${adb_landev}+" -m comment --comment "${notes}" -j "${chain}"
  463. else
  464. "${ipt}" -w -t "${table}" -A "${chsrc}" -d "${nullip}" -m comment --comment "${notes}" -j "${chain}"
  465. fi
  466. rc=${?}
  467. if [ $((rc)) -ne 0 ]
  468. then
  469. f_log "failed to initialize volatile ${proto} firewall chain '${chain}'"
  470. f_exit
  471. fi
  472. fi
  473. # check whether iptables rule already exist
  474. #
  475. rc="$("${ipt}" -w -t "${table}" -C "${chain}" -m comment --comment "${notes}" ${rules} >/dev/null 2>&1; printf ${?})"
  476. if [ $((rc)) -ne 0 ]
  477. then
  478. "${ipt}" -w -t "${table}" -I "${chain}" "${chpos}" -m comment --comment "${notes}" ${rules}
  479. rc=${?}
  480. if [ $((rc)) -eq 0 ]
  481. then
  482. firewall_ok="true"
  483. else
  484. f_log "failed to initialize volatile ${proto} firewall rule '${notes}'"
  485. f_exit
  486. fi
  487. fi
  488. }
  489. # f_uhttpd: start uhttpd instances
  490. #
  491. f_uhttpd()
  492. {
  493. local check
  494. local realm="${1}"
  495. local timeout="${2}"
  496. local ports="${3}"
  497. check="$(pgrep -f "uhttpd -h /www/adblock -N 25 -T ${timeout} -r ${realm}")"
  498. if [ -z "${check}" ]
  499. then
  500. uhttpd -h "/www/adblock" -N 25 -T "${timeout}" -r "${realm}" -k 0 -t 0 -R -D -S -E "/index.html" ${ports}
  501. rc=${?}
  502. if [ $((rc)) -eq 0 ]
  503. then
  504. uhttpd_ok="true"
  505. else
  506. f_log "failed to initialize volatile uhttpd instance (${realm})"
  507. f_exit
  508. fi
  509. fi
  510. }
  511. # f_space: check mount points/space requirements
  512. #
  513. f_space()
  514. {
  515. local mp="${1}"
  516. space_ok="true"
  517. if [ -d "${mp}" ]
  518. then
  519. av_space="$(df "${mp}" | tail -n1 | awk '{printf $4}')"
  520. if [ $((av_space)) -lt $((adb_minspace)) ]
  521. then
  522. space_ok="false"
  523. fi
  524. fi
  525. }
  526. # f_cntconfig: calculate counters in config
  527. #
  528. f_cntconfig()
  529. {
  530. local src_name
  531. local count=0
  532. for src_name in $(ls -ASr "${adb_dnsdir}/${adb_dnsprefix}"*)
  533. do
  534. count="$(wc -l < "${src_name}")"
  535. src_name="${src_name##*.}"
  536. if [ -n "${adb_wanif4}" ] && [ -n "${adb_wanif6}" ]
  537. then
  538. count=$((count / 2))
  539. fi
  540. "${adb_uci}" -q set "adblock.${src_name}.adb_src_count=${count}"
  541. adb_count=$((adb_count + count))
  542. done
  543. "${adb_uci}" -q set "adblock.global.adb_overall_count=${adb_count}"
  544. }
  545. # f_rmconfig: remove volatile config entries
  546. #
  547. f_rmconfig()
  548. {
  549. local opt
  550. local options="adb_src_timestamp adb_src_count"
  551. local section="${1}"
  552. "${adb_uci}" -q delete "adblock.global.adb_overall_count"
  553. "${adb_uci}" -q delete "adblock.global.adb_dnstoggle"
  554. "${adb_uci}" -q delete "adblock.global.adb_percentage"
  555. "${adb_uci}" -q delete "adblock.global.adb_lastrun"
  556. for opt in ${options}
  557. do
  558. "${adb_uci}" -q delete "adblock.${section}.${opt}"
  559. done
  560. }
  561. # f_rmdns: remove dns block lists and backups
  562. #
  563. f_rmdns()
  564. {
  565. rm_dns="$(find "${adb_dnsdir}" -maxdepth 1 -type f -name "${adb_dnsprefix}*" -print -exec rm -f "{}" \;)"
  566. if [ -n "${rm_dns}" ]
  567. then
  568. rm -rf "${adb_dnshidedir}"
  569. if [ "${enabled_backup}" = "1" ] && [ -d "${adb_dir_backup}" ]
  570. then
  571. rm -f "${adb_dir_backup}/${adb_dnsprefix}"*.gz
  572. fi
  573. /etc/init.d/dnsmasq restart
  574. fi
  575. }
  576. # f_rmuhttpd: remove uhttpd instances
  577. #
  578. f_rmuhttpd()
  579. {
  580. rm_uhttpd="$(pgrep -f "uhttpd -h /www/adblock")"
  581. if [ -n "${rm_uhttpd}" ]
  582. then
  583. for pid in ${rm_uhttpd}
  584. do
  585. kill -9 "${pid}"
  586. done
  587. fi
  588. }
  589. # f_rmfirewall: remove firewall rulsets
  590. #
  591. f_rmfirewall()
  592. {
  593. rm_fw="$(iptables -w -t nat -vnL | grep -Fo "adb-")"
  594. if [ -n "${rm_fw}" ]
  595. then
  596. iptables-save -t nat | grep -Fv -- "adb-" | iptables-restore
  597. iptables-save -t filter | grep -Fv -- "adb-" | iptables-restore
  598. if [ -n "$(lsmod | grep -Fo "ip6table_nat")" ]
  599. then
  600. ip6tables-save -t nat | grep -Fv -- "adb-" | ip6tables-restore
  601. ip6tables-save -t filter | grep -Fv -- "adb-" | ip6tables-restore
  602. fi
  603. fi
  604. }
  605. # f_log: log messages to stdout and syslog
  606. #
  607. f_log()
  608. {
  609. local log_parm
  610. local log_msg="${1}"
  611. local class="info "
  612. # check for terminal session
  613. #
  614. if [ -t 1 ]
  615. then
  616. log_parm="-s"
  617. fi
  618. # log to different output devices and set log class accordingly
  619. #
  620. if [ -n "${log_msg}" ]
  621. then
  622. if [ $((rc)) -gt 0 ]
  623. then
  624. class="error"
  625. fi
  626. logger ${log_parm} -t "adblock[${adb_pid}] ${class}" "${log_msg}" 2>&1
  627. fi
  628. }
  629. # f_statistics: adblock runtime statistics
  630. f_statistics()
  631. {
  632. local ipv4_blk=0 ipv4_all=0 ipv4_pct=0
  633. local ipv6_blk=0 ipv6_all=0 ipv6_pct=0
  634. if [ -n "${adb_wanif4}" ]
  635. then
  636. ipv4_blk="$(iptables -t nat -vxnL adb-nat | awk '$3 ~ /^DNAT$/ {sum += $1} END {printf sum}')"
  637. ipv4_all="$(iptables -t nat -vxnL PREROUTING | awk '$3 ~ /^(delegate_prerouting|prerouting_rule)$/ {sum += $1} END {printf sum}')"
  638. if [ $((ipv4_all)) -gt 0 ] && [ $((ipv4_blk)) -gt 0 ] && [ $((ipv4_all)) -gt $((ipv4_blk)) ]
  639. then
  640. ipv4_pct="$(printf "${ipv4_blk}" | awk -v all="${ipv4_all}" '{printf( "%5.2f\n",$1/all*100)}')"
  641. elif [ $((ipv4_all)) -lt $((ipv4_blk)) ]
  642. then
  643. iptables -t nat -Z adb-nat
  644. fi
  645. fi
  646. if [ -n "${adb_wanif6}" ]
  647. then
  648. ipv6_blk="$(ip6tables -t nat -vxnL adb-nat | awk '$3 ~ /^DNAT$/ {sum += $1} END {printf sum}')"
  649. ipv6_all="$(ip6tables -t nat -vxnL PREROUTING | awk '$3 ~ /^(adb-nat|DNAT)$/ {sum += $1} END {printf sum}')"
  650. if [ $((ipv6_all)) -gt 0 ] && [ $((ipv6_blk)) -gt 0 ] && [ $((ipv6_all)) -gt $((ipv6_blk)) ]
  651. then
  652. ipv6_pct="$(printf "${ipv6_blk}" | awk -v all="${ipv6_all}" '{printf( "%5.2f\n",$1/all*100)}')"
  653. elif [ $((ipv6_all)) -lt $((ipv6_blk)) ]
  654. then
  655. ip6tables -t nat -Z adb-nat
  656. fi
  657. fi
  658. "${adb_uci}" -q set "adblock.global.adb_percentage=${ipv4_pct}%/${ipv6_pct}%"
  659. f_log "firewall statistics (IPv4/IPv6): ${ipv4_pct}%/${ipv6_pct}% of all packets in prerouting chain are ad related & blocked"
  660. }
  661. # f_exit: delete temporary files, generate statistics and exit
  662. #
  663. f_exit()
  664. {
  665. local lastrun="$(date "+%d.%m.%Y %H:%M:%S")"
  666. if [ "${adb_restricted}" = "1" ]
  667. then
  668. adb_uci="$(which true)"
  669. fi
  670. # delete temp files & directories
  671. #
  672. rm -f "${adb_tmpfile}"
  673. rm -rf "${adb_tmpdir}"
  674. # tidy up on error
  675. #
  676. if [ $((rc)) -lt 0 ] || [ $((rc)) -gt 0 ]
  677. then
  678. f_rmdns
  679. f_rmuhttpd
  680. f_rmfirewall
  681. config_foreach f_rmconfig source
  682. if [ $((rc)) -eq -1 ]
  683. then
  684. "${adb_uci}" -q set "adblock.global.adb_lastrun=${lastrun} => runtime error, please check the log!"
  685. fi
  686. fi
  687. # final log message and iptables statistics
  688. #
  689. if [ $((rc)) -eq 0 ]
  690. then
  691. f_statistics
  692. "${adb_uci}" -q set "adblock.global.adb_lastrun=${lastrun}"
  693. f_log "domain adblock processing finished successfully (${adb_scriptver}, ${adb_sysver}, ${lastrun})"
  694. elif [ $((rc)) -gt 0 ]
  695. then
  696. f_log "domain adblock processing failed (${adb_scriptver}, ${adb_sysver}, ${lastrun})"
  697. else
  698. rc=0
  699. fi
  700. "${adb_uci}" -q commit "adblock"
  701. rm -f "${adb_pidfile}"
  702. exit ${rc}
  703. }