From 641318d5c5cb1573ec2383f32947a26d0d3ea3de Mon Sep 17 00:00:00 2001 From: Dirk Brenken Date: Thu, 15 Aug 2019 14:02:30 +0200 Subject: [PATCH] adblock: release 3.8.0 * add support for 'DNS File Reset', where the final DNS blockfile will be purged after DNS backend loading (save storage space). A small background service will be started to trace/handle dns backend reloads/restarts * add support for the 'null' blocking variant in dnsmasq (via addn-hosts), which may provide better response times in dnsmasq * enhance the report & search engine to support the new blocking variants. Search now includes backups & black-/whitelist as well * compressed source list backups are now mandatory (default to '/tmp') * speed up TLD compression * E-Mail notification setup is now integrated in UCI/LuCI * update the LuCI frontend to reflect all changes (separate PR) * drop preliminary dnscrypt-proxy-support (use dnsmasq instead) * drop additional 'dnsjail' blocklist support (not used by anyone) * procd cleanups in init * various shellcheck cleanups * update readme Signed-off-by: Dirk Brenken (cherry picked from commit 504412ccdbe9e6f1f65b34cf28641ec9aa9b7c22) --- net/adblock/Makefile | 15 +- net/adblock/files/README.md | 139 +++-- net/adblock/files/adblock.conf | 11 +- net/adblock/files/adblock.init | 11 +- net/adblock/files/adblock.mail | 71 +++ net/adblock/files/adblock.notify | 69 --- net/adblock/files/adblock.service | 27 + net/adblock/files/adblock.sh | 846 +++++++++++++++--------------- 8 files changed, 604 insertions(+), 585 deletions(-) create mode 100755 net/adblock/files/adblock.mail delete mode 100644 net/adblock/files/adblock.notify create mode 100755 net/adblock/files/adblock.service diff --git a/net/adblock/Makefile b/net/adblock/Makefile index 79ffea4a08..a195490d39 100644 --- a/net/adblock/Makefile +++ b/net/adblock/Makefile @@ -6,8 +6,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=adblock -PKG_VERSION:=3.6.5 -PKG_RELEASE:=2 +PKG_VERSION:=3.8.0 +PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0+ PKG_MAINTAINER:=Dirk Brenken @@ -22,7 +22,7 @@ define Package/adblock endef define Package/adblock/description -Powerful adblock script to block ad/abuse domains via dnsmasq, unbound, named, kresd or dnscrypt-proxy. +Powerful adblock script to block ad/abuse domains via dnsmasq, unbound, named or kresd. The script supports many domain blacklist sites plus manual black- and whitelist overrides. Please see https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md for further information. @@ -45,7 +45,7 @@ endef define Package/adblock/install $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) ./files/adblock.sh $(1)/usr/bin/ + $(INSTALL_BIN) ./files/adblock.sh $(1)/usr/bin $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/adblock.init $(1)/etc/init.d/adblock @@ -54,9 +54,10 @@ define Package/adblock/install $(INSTALL_CONF) ./files/adblock.conf $(1)/etc/config/adblock $(INSTALL_DIR) $(1)/etc/adblock - $(INSTALL_CONF) ./files/adblock.notify $(1)/etc/adblock/ - $(INSTALL_CONF) ./files/adblock.blacklist $(1)/etc/adblock/ - $(INSTALL_CONF) ./files/adblock.whitelist $(1)/etc/adblock/ + $(INSTALL_BIN) ./files/adblock.mail $(1)/etc/adblock + $(INSTALL_BIN) ./files/adblock.service $(1)/etc/adblock + $(INSTALL_CONF) ./files/adblock.blacklist $(1)/etc/adblock + $(INSTALL_CONF) ./files/adblock.whitelist $(1)/etc/adblock endef $(eval $(call BuildPackage,adblock)) diff --git a/net/adblock/files/README.md b/net/adblock/files/README.md index 36eeee4129..1e26b015c0 100644 --- a/net/adblock/files/README.md +++ b/net/adblock/files/README.md @@ -61,44 +61,43 @@ A lot of people already use adblocker plugins within their desktop browsers, but * => weekly updates, approx. 2.500 entries (enabled by default) * zero-conf like automatic installation & setup, usually no manual changes needed * simple but yet powerful adblock engine: adblock does not use error prone external iptables rulesets, http pixel server instances and things like that -* supports five different dns backends / blocklist formats: dnsmasq, unbound, named (bind), kresd and dnscrypt-proxy -* supports six different download utilities: uclient-fetch, wget, curl, aria2c, wget-nossl, busybox-wget -* Really fast downloads & list processing as they are handled in parallel as background jobs in a configurable 'Download Queue' -* provides 'http only' mode without installed ssl library for all non-SSL blocklist sources -* supports a wide range of router modes, even AP modes are supported +* support four different dns backends: dnsmasq, unbound, named (bind) and kresd +* support two different dns blocking variants: 'nxdomain' (default, supported by all backends), 'null' (supported only by dnsmasq) +* support six different download utilities: uclient-fetch, wget, curl, aria2c, wget-nossl, busybox-wget +* fast downloads & list processing as they are handled in parallel running background jobs (see 'Download Queue') +* provide 'http only' mode without installed ssl library for all non-SSL blocklist sources +* support a wide range of router modes, even AP modes are supported * full IPv4 and IPv6 support -* provides top level domain compression ('tld compression'), this feature removes thousands of needless host entries from the blocklist and lowers the memory footprint for the dns backend +* provide top level domain compression ('tld compression'), this feature removes thousands of needless host entries from the blocklist and lowers the memory footprint for the dns backend +* provide a 'DNS File Reset', where the final DNS blockfile will be purged after DNS backend loading to save storage space * blocklist source parsing by fast & flexible regex rulesets * overall duplicate removal in central blocklist 'adb_list.overall' -* additional whitelist for manual overrides, located by default in /etc/adblock/adblock.whitelist +* additional blacklist for manual overrides, located by default in /etc/adblock/adblock.blacklist or in LuCI +* additional whitelist for manual overrides, located by default in /etc/adblock/adblock.whitelist or in LuCI * quality checks during blocklist update to ensure a reliable dns backend service * minimal status & error logging to syslog, enable debug logging to receive more output * procd based init system support (start/stop/restart/reload/suspend/resume/query/status) * procd network interface trigger support or classic time based startup * keep the dns cache intact after adblock processing (currently supported by unbound, named and kresd) -* conditional dns backend restarts by old/new blocklist comparison with sha256sum (default) or md5sum * suspend & resume adblock actions temporarily without blocklist reloading * provide comprehensive runtime information via LuCI or via 'status' init command * provide a detailed DNS Query Report with dns related information about client requests, top (blocked) domains and more -* provide a query function to quickly identify blocked (sub-)domains, e.g. for whitelisting. This function is also able to search in adblock backups, to get back the set of blocking lists sources for a certain domain -* force dns requests to local resolver -* force overall sort / duplicate removal for low memory devices (handle with care!) -* automatic blocklist backup & restore, they will be used in case of download errors or during startup in backup mode -* 'backup mode' to re-use blocklist backups during startup, get fresh lists only via reload or restart action -* 'Jail' blocklist generation which builds an additional list (/tmp/adb_list.jail) to block access to all domains except those listed in the whitelist file. You can use this restrictive blocklist manually e.g. for guest wifi or kidsafe configurations -* send notification emails in case of a processing error or if the overall domain count is ≤ 0 +* provide a query function to quickly identify blocked (sub-)domains, e.g. for whitelisting. This function is also able to search in adblock backups and black-/whitelist, to get back the set of blocking lists sources for a certain domain +* option to force dns requests to the local resolver +* automatic blocklist backup & restore, these backups will be used in case of download errors and during startup +* send notification E-Mails in case of a processing error or if the overall domain count is ≤ 0 * add new adblock sources on your own, see example below -* strong LuCI support +* strong LuCI support for all options ## Prerequisites -* [OpenWrt](https://openwrt.org), tested with the stable release series (18.06) and with the latest snapshot +* [OpenWrt](https://openwrt.org), tested with the stable release series (19.07) and with the latest snapshot * a usual setup with an enabled dns backend at minimum - dump AP modes without a working dns backend are _not_ supported * a download utility: * to support all blocklist sources a full version (with ssl support) of 'wget', 'uclient-fetch' with one of the 'libustream-*' ssl libraries, 'aria2c' or 'curl' is required * for limited devices with real memory constraints, adblock provides also a 'http only' option and supports wget-nossl and uclient-fetch (without libustream-ssl) as well * for more configuration options see examples below -* email notification (optional): for email notification support you need to install and configure the additional 'msmtp' package -* DNS Query Report (optional): for this detailed report you need to install the additional package 'tcpdump' or 'tcpdump-mini' +* E-Mail notification (optional): for E-Mail notification support you need the additional 'msmtp' package +* DNS Query Report (optional): for this detailed report you need the additional package 'tcpdump' or 'tcpdump-mini' ## Installation & Usage * install 'adblock' (_opkg install adblock_) @@ -108,56 +107,59 @@ A lot of people already use adblocker plugins within their desktop browsers, but ## LuCI adblock companion package * it's strongly recommended to use the LuCI frontend to easily configure all powerful aspects of adblock * install 'luci-app-adblock' (_opkg install luci-app-adblock_) -* the application is located in LuCI under 'Services' menu +* the application is located in LuCI under the 'Services' menu ## Tweaks * **runtime information:** the adblock status is available via _/etc/init.d/adblock status_ (see example below) * **debug logging:** for script debugging please set the config option 'adb\_debug' to '1' and check the runtime output with _logread -e "adblock"_ -* **storage expansion:** to process and store all blocklist sources at once it might helpful to enlarge your temp directory with a swap partition => see [OpenWrt Wiki](https://wiki.openwrt.org/doc/uci/fstab) for further details -* **add white- / blacklist entries:** add domain white- or blacklist entries to always-allow or -deny certain (sub) domains, by default both lists are empty and located in _/etc/adblock_. Please add one domain per line - ip addresses, wildcards & regex are _not_ allowed (see example below) -* **backup & restore blocklists:** enable this feature, to restore automatically the latest compressed backup of your blocklists in case of any processing error (e.g. a single blocklist source is not available during update). Please use an (external) solid partition and _not_ your volatile router temp directory for this +* **storage expansion:** to process and store all blocklist sources at once it might be helpful to enlarge your temp directory with a swap partition => see [OpenWrt Wiki](https://openwrt.org/docs/guide-user/storage/fstab) for further details +* **add white- / blacklist entries:** add domain black- or whitelist entries to always-deny or -allow certain (sub) domains, by default both lists are empty and located in _/etc/adblock_. Please add one domain per line - ip addresses, wildcards & regex are _not_ allowed (see example below). You need to refresh your blocklists after changes to these static lists. * **download queue size:** for further download & list processing performance improvements you can raise the 'adb\_maxqueue' value, e.g. '8' or '16' should be safe * **scheduled list updates:** for a scheduled call of the adblock service add an appropriate crontab entry (see example below) * **change startup behaviour:** by default the startup will be triggered by the 'wan' procd interface trigger. Choose 'none' to disable automatic startups, 'timed' to use a classic timeout (default 30 sec.) or select another trigger interface * **suspend & resume adblocking:** to quickly switch the adblock service 'on' or 'off', simply use _/etc/init.d/adblock [suspend|resume]_ * **domain query:** to query the active blocklist for a certain domain, please use the LuCI frontend or run _/etc/init.d/adblock query ``_ (see example below) * **add new list sources:** you could add new blocklist sources on your own via uci config, all you need is a source url and an awk one-liner (see example below) -* **disable active dns probing in windows 10:** to prevent a yellow exclamation mark on your internet connection icon (which wrongly means connected, but no internet), please change the following registry key/value from "1" to "0" _HKLM\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet\EnableActiveProbing_ ## Further adblock config options * usually the pre-configured adblock setup works quite well and no manual overrides are needed * the following options apply to the 'global' config section: * adb\_enabled => main switch to enable/disable adblock service (default: '0', disabled) - * adb\_debug => enable/disable adblock debug output (default: '0', disabled) + * adb\_dns => select the dns backend for your environment: 'dnsmasq', 'unbound', 'named' or 'kresd' (default: 'dnsmasq') + * adb\_dnsvariant => select the blocking variant: 'nxdomain' (default, supported by all backends), 'null (IPv4)' and 'null (IPv4/IPv6)' both options are only supported by dnsmasq * adb\_fetchutil => name of the used download utility: 'uclient-fetch', 'wget', 'curl', 'aria2c', 'wget-nossl'. 'busybox' (default: 'uclient-fetch') * adb\_fetchparm => special config options for the download utility (default: not set) - * adb\_dns => select the dns backend for your environment: 'dnsmasq', 'unbound', 'named', 'kresd' or 'dnscrypt-proxy' (default: 'dnsmasq') - * adb\_dnsdir => target directory for the generated blocklist 'adb_list.overall' (default: not set, use dns backend default) * adb\_trigger => set the startup trigger to a certain interface, to 'timed' or to 'none' (default: 'wan') - * the following options apply to the 'extra' config section: + * adb\_debug => enable/disable adblock debug output (default: '0', disabled) * adb\_nice => set the nice level of the adblock process and all sub-processes (int/default: '0', standard priority) - * adb\_triggerdelay => additional trigger delay in seconds before adblock processing begins (int/default: '2') * adb\_forcedns => force dns requests to local resolver (bool/default: '0', disabled) - * adb\_backup => create compressed blocklist backups, they will be used in case of download errors or during startup in backup mode (bool/default: '0', disabled) - * adb\_backupdir => target directory for adblock backups (default: not set) - * adb\_backup_mode => do not automatically update blocklists during startup, use backups instead (bool/default: '0', disabled) + * adb\_maxqueue => size of the download queue to handle downloads & list processing in parallel (int/default: '8') + * adb\_dnsfilereset => the final DNS blockfile will be purged after DNS backend loading to save storage space (bool/default: 'false', disabled) * adb\_report => enable the background tcpdump gathering process to provide a detailed DNS Query Report (bool/default: '0', disabled) * adb\_repdir => target directory for dns related report files generated by tcpdump (default: '/tmp') + * adb\_backupdir => target directory for adblock backups (default: '/tmp') + * adb\_mail => send notification E-Mails in case of a processing errors or if the overall domain count is ≤ 0 (bool/default: '0', disabled) + * adb\_mreceiver => receiver address for adblock notification E-Mails (default: not set) +* the following options could be added via "Additional Field" in LuCI and apply to the 'extra' config section as well: + * adb\_dnsdir => target directory for the generated blocklist 'adb_list.overall' (default: not set, use dns backend default) + * adb\_blacklist => full path to the static blacklist file (default: '/etc/adblock/adblock.blacklist') + * adb\_whitelist => full path to the static whitelist file (default: '/etc/adblock/adblock.whitelist') + * adb\_triggerdelay => additional trigger delay in seconds before adblock processing begins (int/default: '2') + * adb\_dnsflush => flush DNS cache after adblock processing, i.e. enable the old restart behavior (bool/default: '0', disabled) * adb\_repiface => reporting interface used by tcpdump, set to 'any' for multiple interfaces (default: 'br-lan') * adb\_replisten => space separated list of reporting port(s) used by tcpdump (default: '53') - * adb\_repchunksize => report chunk size used by tcpdump in MB (int/default: '1') * adb\_repchunkcnt => report chunk count used by tcpdump (default: '5') - * adb\_maxqueue => size of the download queue to handle downloads & list processing in parallel (int/default: '8') - * adb\_jail => builds an additional 'Jail' list (/tmp/adb_list.jail) to block access to all domains except those listed in the whitelist file (bool/default: '0', disabled) - * adb\_dnsflush => flush DNS cache after adblock processing, i.e. enable the old restart behavior (bool/default: '0', disabled) - * adb\_notify => send notification emails in case of a processing error or if the overall domain count is ≤ 0 (bool/default: '0', disabled) - * adb\_notifycnt => Raise minimum domain count email notification trigger (int/default: '0') + * adb\_repchunksize => report chunk size used by tcpdump in MB (int/default: '1') + * adb\_msender => sender address for adblock notification E-Mails (default: 'no-reply@adblock') + * adb\_mtopic => topic for adblock notification E-Mails (default: 'adblock notification') + * adb\_mprofile => mail profile used in 'msmtp' for adblock notification E-Mails (default: 'adb_notify') + * adb\_mcnt => raise the minimum domain count E-Mmail notification trigger (int/default: '0') ## Examples **change default dns backend to 'unbound':** -Adblock deposits the final blocklist 'adb_list.overall' in '/var/lib/unbound' where unbound can find them in its jail. +Adblock deposits the final blocklist 'adb_list.overall' in '/var/lib/unbound' where unbound can find them in its jail, no further configuration needed. To preserve the DNS cache after adblock processing you need to install 'unbound-control'. **change default dns backend to 'named' (bind):** @@ -183,25 +185,7 @@ and at the end of the file add: The knot-resolver (kresd) is only available on Turris Omnia devices. Adblock deposits the final blocklist 'adb_list.overall' in '/etc/kresd', no further configuration needed. -**change default dns backend to 'dnscrypt-proxy':** - -The required 'blacklist' option of dnscrypt-proxy is not enabled by default, because the package will be compiled without plugins support. -Take a custom OpenWrt build with plugins support to use this feature. Adblock deposits the final blocklist 'adb_list.overall' in '/tmp'. -To use the blocklist please modify '/etc/config/dnscrypt-proxy' per instance: -

-  list blacklist 'domains:/tmp/adb_list.overall'
-
- -**reference the jail block list manually in a 'kidsafe' dhcp config:** - -The additional 'Jail' blocklist (by default in /tmp/adb_list.jail) block access to all domains except those listed in the whitelist file. -

-config dnsmasq 'kidsafe'
-        [...]
-        option serversfile '/tmp/adb_list.jail'
-
- -**enable email notification via msmtp:** +**enable E-Mail notification via msmtp:** To use the email notification you have to install & configure the package 'msmtp'. Modify the file '/etc/msmtprc': @@ -221,8 +205,7 @@ from dev.adblock@gmail.com user dev.adblock password xxx -Edit the file '/etc/adblock/adblock.notify' and change at least the 'mail_receiver'. -Finally make this file executable via 'chmod' and test it directly. If no more errors come up you can comment 'mail_debug', too. +Finally enable E-Mail support and add a valid E-Mail address in LuCI. **receive adblock runtime information:** @@ -230,12 +213,14 @@ Finally make this file executable via 'chmod' and test it directly. If no more e /etc/init.d/adblock status ::: adblock runtime information + adblock_status : enabled - + adblock_version : 3.6.0 - + overall_domains : 30267 (backup mode) + + adblock_version : 3.8.0 + + overall_domains : 48359 + fetch_utility : /bin/uclient-fetch (libustream-ssl) - + dns_backend : dnsmasq (/tmp) - + last_rundate : 19.12.2018 16:29:25 - + system_release : GL-AR750S, OpenWrt SNAPSHOT r8814-6835c13e5a + + dns_backend : dnsmasq, /tmp + + dns_variant : null (IPv4/IPv6), true + + backup_dir : /mnt/data/adblock + + last_rundate : 15.08.2019 08:43:16 + + system_release : GL.iNet GL-AR750S, OpenWrt SNAPSHOT r10720-ccb4b96b8a **receive adblock DNS Query Report information:** @@ -272,6 +257,7 @@ Finally make this file executable via 'chmod' and test it directly. If no more e + 2 ::: v10.events.data.microsoft.com + 2 ::: settings-win.data.microsoft.com + 2 ::: nexusrules.officeapps.live.com +[...] **cronjob for a regular block list update (/etc/crontabs/root):** @@ -309,23 +295,28 @@ This entry does not remove: www.adwhere.com -**query the active blocklist for a certain (sub-)domain, e.g. for whitelisting:** +**query the active blocklist, the backups and black-/whitelist for a certain (sub-)domain, e.g. for whitelisting:** The query function checks against the submitted (sub-)domain and recurses automatically to the upper top level domain. For every (sub-)domain it returns the first ten relevant results.

 /etc/init.d/adblock query google.com
 :::
-::: results for domain 'google.com'
+::: results for domain 'google.com' in active blocklist
 :::
+  + adservice.google.com
+  + adservice.google.com.au
+  + adservice.google.com.vn
+  + adservices.google.com
   + analytics.google.com
   + googleadapis.l.google.com
   + pagead.l.google.com
   + partnerad.l.google.com
   + ssl-google-analytics.l.google.com
-  + www-google-analytics.l.google.com
   + video-stats.video.google.com
+  + [...]
+
 :::
-::: results for domain 'google.com' in backups
+::: results for domain 'google.com' in backups and black-/whitelist
 :::
   + adb_list.adguard.gz           partnerad.l.google.com
   + adb_list.adguard.gz           googleadapis.l.google.com
@@ -335,9 +326,13 @@ The query function checks against the submitted (sub-)domain and recurses automa
   + adb_list.disconnect.gz        partnerad.l.google.com
   + adb_list.disconnect.gz        video-stats.video.google.com
   + adb_list.disconnect.gz        [...]
+  + adb_list.whocares.gz          video-stats.video.google.com
+  + adb_list.whocares.gz          adservice.google.com
+  + adb_list.whocares.gz          adservice.google.com.au
+  + adb_list.whocares.gz          [...]
+  + adb_list.yoyo.gz              adservice.google.com
   + adb_list.yoyo.gz              analytics.google.com
   + adb_list.yoyo.gz              pagead.l.google.com
-  + adb_list.yoyo.gz              partnerad.l.google.com
   + adb_list.yoyo.gz              [...]
 
@@ -361,9 +356,5 @@ To add a really new source with different domain/host format you have to write a ## Support Please join the adblock discussion in this [forum thread](https://forum.openwrt.org/t/adblock-support-thread/507) or contact me by mail -## Removal -* stop all adblock related services with _/etc/init.d/adblock stop_ -* optional: remove the adblock package (_opkg remove adblock_) - Have fun! Dirk diff --git a/net/adblock/files/adblock.conf b/net/adblock/files/adblock.conf index 8b47627d41..fad665ba49 100644 --- a/net/adblock/files/adblock.conf +++ b/net/adblock/files/adblock.conf @@ -1,16 +1,17 @@ config adblock 'global' + option adb_basever '3.8' option adb_enabled '0' option adb_dns 'dnsmasq' + option adb_dnsvariant 'nxdomain' option adb_fetchutil 'uclient-fetch' option adb_trigger 'wan' config adblock 'extra' option adb_debug '0' option adb_forcedns '0' - option adb_backup '0' option adb_report '0' - option adb_maxqueue '8' + option adb_maxqueue '4' config source 'adaway' option adb_src 'https://adaway.org/hosts.txt' @@ -30,12 +31,6 @@ config source 'bitcoin' option adb_src_desc 'focus on malicious bitcoin mining sites, infrequent updates, approx. 80 entries' option enabled '0' -config source 'blacklist' - option adb_src '/etc/adblock/adblock.blacklist' - option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}' - option adb_src_desc 'static local domain blacklist, always deny these domains' - option enabled '1' - config source 'disconnect' option adb_src 'https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt' option adb_src_rset '/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}' diff --git a/net/adblock/files/adblock.init b/net/adblock/files/adblock.init index 74cbf01bb3..b5369230ae 100755 --- a/net/adblock/files/adblock.init +++ b/net/adblock/files/adblock.init @@ -52,7 +52,6 @@ reload_service() stop_service() { rc_procd "${adb_script}" stop - rc_procd start_service } restart() @@ -63,13 +62,13 @@ restart() suspend() { [ -s "${adb_pidfile}" ] && return 1 - rc_procd "${adb_script}" suspend + rc_procd start_service suspend } resume() { [ -s "${adb_pidfile}" ] && return 1 - rc_procd "${adb_script}" resume + rc_procd start_service resume } query() @@ -91,17 +90,17 @@ status() rtfile="${rtfile:-"/tmp/adb_runtime.json"}" if [ -s "${rtfile}" ] then - printf "%s\n" "::: adblock runtime information" + printf "%s\\n" "::: adblock runtime information" json_load_file "${rtfile}" json_select data json_get_keys keylist for key in ${keylist} do json_get_var value "${key}" - printf " + %-15s : %s\n" "${key}" "${value}" + printf " + %-15s : %s\\n" "${key}" "${value}" done else - printf "%s\n" "::: no adblock runtime information available" + printf "%s\\n" "::: no adblock runtime information available" fi } diff --git a/net/adblock/files/adblock.mail b/net/adblock/files/adblock.mail new file mode 100755 index 0000000000..3b4d69cb6c --- /dev/null +++ b/net/adblock/files/adblock.mail @@ -0,0 +1,71 @@ +#!/bin/sh +# +# send mail script for adblock notifications +# written by Dirk Brenken (dev@brenken.org) +# Please note: you have to manually install and configure the package 'msmtp' before using this script + +# This is free software, licensed under the GNU General Public License v3. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +LC_ALL=C +PATH="/usr/sbin:/usr/bin:/sbin:/bin" + +if [ -r "/lib/functions.sh" ] +then + . "/lib/functions.sh" + adb_basever="$(uci_get adblock global adb_basever)" + adb_debug="$(uci_get adblock extra adb_debug "0")" + adb_msender="$(uci_get adblock extra adb_msender "no-reply@adblock")" + adb_mreceiver="$(uci_get adblock extra adb_mreceiver)" + adb_mtopic="$(uci_get adblock extra adb_mtopic "adblock notification")" + adb_mprofile="$(uci_get adblock extra adb_mprofile "adb_notify")" +fi +adb_mail="$(command -v msmtp)" +adb_rc=1 + +if [ "${adb_debug}" -eq 1 ] +then + debug="--debug" +fi + +# mail header & receiver check +# +if [ -z "${adb_mreceiver}" ] +then + logger -p "err" -t "adblock-${adb_basever} [${$}]" "please set the mail receiver with the 'adb_mreceiver' option" + exit ${adb_rc} +fi +adb_mhead="From: ${adb_msender}\\nTo: ${adb_mreceiver}\\nSubject: ${adb_mtopic}\\nReply-to: ${adb_msender}\\nMime-Version: 1.0\\nContent-Type: text/html\\nContent-Disposition: inline\\n\\n" + +# info preparation +# +sys_info="$(strings /etc/banner 2>/dev/null; ubus call system board | sed -e 's/\"release\": {//' | sed -e 's/^[ \t]*//' | sed -e 's/[{}\",]//g' | sed -e 's/[ ]/ \t/' | sed '/^$/d' 2>/dev/null)" +adb_info="$(/etc/init.d/adblock status 2>/dev/null)" +if [ -f "/var/log/messages" ] +then + log_info="$(awk '/adblock-/{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"↵"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}' /var/log/messages)" +else + log_info="$(logread -e "adblock-" | awk '{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"↵"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')" +fi + +# mail body +# +adb_mtext="
"
+adb_mtext="${adb_mtext}\\n++\\n++ System Information ++\\n++\\n${sys_info}"
+adb_mtext="${adb_mtext}\\n\\n++\\n++ Adblock Information ++\\n++\\n${adb_info}"
+adb_mtext="${adb_mtext}\\n\\n++\\n++ Logfile Information ++\\n++\\n${log_info}"
+adb_mtext="${adb_mtext}
" + +# send mail +# +if [ -x "${adb_mail}" ] +then + printf "%b" "${adb_mhead}${adb_mtext}" 2>/dev/null | "${adb_mail}" ${debug} -a "${adb_mprofile}" "${adb_mreceiver}" >/dev/null 2>&1 + adb_rc=${?} + logger -p "info" -t "adblock-${adb_basever} [${$}]" "mail sent to '${adb_mreceiver}' with rc '${adb_rc}'" +else + logger -p "err" -t "adblock-${adb_basever} [${$}]" "msmtp mail daemon not found" +fi + +exit ${adb_rc} diff --git a/net/adblock/files/adblock.notify b/net/adblock/files/adblock.notify deleted file mode 100644 index 54f0288d57..0000000000 --- a/net/adblock/files/adblock.notify +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh -# -# adblock send mail script for msmtp -# written by Dirk Brenken (dev@brenken.org) -# Please note: you have to install and configure the package 'msmtp' before using this script. - -# This is free software, licensed under the GNU General Public License v3. -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -LC_ALL=C -PATH="/usr/sbin:/usr/bin:/sbin:/bin" -mail_ver="1.0.4" -mail_daemon="$(command -v msmtp)" -mail_profile="adb_notify" -#mail_debug="--debug" -mail_rc=1 - -# mail header & mail receiver check -# -mail_receiver="" -mail_sender="no-reply@adblock" -mail_topic="${HOSTNAME}: adblock notification" -mail_head="From: ${mail_sender}\nTo: ${mail_receiver}\nSubject: ${mail_topic}\nReply-to: ${mail_sender}\nMime-Version: 1.0\nContent-Type: text/html\nContent-Disposition: inline\n\n" - -if [ -z "${mail_receiver}" ] -then - logger -p "err" -t "adblock-notify-${mail_ver}[${$}]" "please supply/customize the 'mail_receiver' in '/etc/adblock/adblock.notify'" - exit ${mail_rc} -fi - -# mail daemon check -# -if [ ! -x "${mail_daemon}" ] -then - mail_daemon="$(command -v sendmail)" -fi - -# info preparation -# -sys_info="$(strings /etc/banner 2>/dev/null; ubus call system board | sed -e 's/\"release\": {//' | sed -e 's/^[ \t]*//' | sed -e 's/[{}\",]//g' | sed -e 's/[ ]/ \t/' | sed '/^$/d' 2>/dev/null)" -adb_info="$(/etc/init.d/adblock status 2>/dev/null)" -if [ -f "/var/log/messages" ] -then - log_info="$(awk '/adblock-/{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"↵"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}' /var/log/messages)" -else - log_info="$(logread -e "adblock-" | awk '{NR=1;max=79;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max),"↵"} else {print " ",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')" -fi - -# mail body -# -mail_text="
"
-mail_text="${mail_text}\n++\n++ System Information ++\n++\n${sys_info}"
-mail_text="${mail_text}\n\n++\n++ Adblock Information ++\n++\n${adb_info}"
-mail_text="${mail_text}\n\n++\n++ Logfile Information ++\n++\n${log_info}"
-mail_text="${mail_text}
" - -# send mail -# -if [ -x "${mail_daemon}" ] -then - printf "%b" "${mail_head}${mail_text}" 2>/dev/null | "${mail_daemon}" ${mail_debug} -a "${mail_profile}" "${mail_receiver}" >/dev/null 2>&1 - mail_rc=${?} - logger -p "info" -t "adblock-notify-${mail_ver}[${$}]" "mail sent to '${mail_receiver}' with rc '${mail_rc}'" -else - logger -p "err" -t "adblock-notify-${mail_ver}[${$}]" "msmtp mail daemon not found" -fi - -exit ${mail_rc} diff --git a/net/adblock/files/adblock.service b/net/adblock/files/adblock.service new file mode 100755 index 0000000000..1265c139e3 --- /dev/null +++ b/net/adblock/files/adblock.service @@ -0,0 +1,27 @@ +#!/bin/sh +# ubus monitor to trace dns backend events and conditionally restart adblock +# written by Dirk Brenken (dev@brenken.org) + +# This is free software, licensed under the GNU General Public License v3. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +LC_ALL=C +PATH="/usr/sbin:/usr/bin:/sbin:/bin" + +if [ -r "/lib/functions.sh" ] +then + . "/lib/functions.sh" + adb_basever="$(uci_get adblock global adb_basever)" + adb_dns="$(uci_get adblock global adb_dns)" +fi +adb_ubus="$(command -v ubus)" + +if [ -x "${adb_ubus}" ] && [ -n "${adb_dns}" ] +then + logger -p "info" -t "adblock-${adb_basever} [${$}]" "ubus/adblock service started" + "${adb_ubus}" -S -M r -m invoke monitor | \ + { grep -qF "\"method\":\"set\",\"data\":{\"name\":\"${adb_dns}\""; [ $? -eq 0 ] && /etc/init.d/adblock start; } +else + logger -p "err" -t "adblock-${adb_basever} [${$}]" "can't start ubus/adblock service" +fi diff --git a/net/adblock/files/adblock.sh b/net/adblock/files/adblock.sh index 24e58b28f3..e4bba187a4 100755 --- a/net/adblock/files/adblock.sh +++ b/net/adblock/files/adblock.sh @@ -10,30 +10,27 @@ # LC_ALL=C PATH="/usr/sbin:/usr/bin:/sbin:/bin" -adb_ver="3.6.5-2" +adb_ver="3.8.0" adb_sysver="unknown" adb_enabled=0 adb_debug=0 adb_forcedns=0 -adb_jail=0 -adb_maxqueue=8 -adb_notify=0 -adb_notifycnt=0 +adb_maxqueue=4 +adb_mail=0 +adb_mcnt=0 +adb_trigger="wan" adb_triggerdelay=0 -adb_backup=0 -adb_backup_mode=0 -adb_backupdir="/mnt" +adb_backupdir="/tmp" adb_fetchutil="uclient-fetch" adb_dns="dnsmasq" +adb_dnsvariant="nxdomain" adb_dnsprefix="adb_list" adb_dnsfile="${adb_dnsprefix}.overall" -adb_dnsjail="${adb_dnsprefix}.jail" +adb_dnsfilereset="false" adb_dnsflush=0 +adb_blacklist="/etc/adblock/adblock.blacklist" adb_whitelist="/etc/adblock/adblock.whitelist" adb_rtfile="/tmp/adb_runtime.json" -adb_hashutil="$(command -v sha256sum)" -adb_hashold="" -adb_hashnew="" adb_report=0 adb_repiface="br-lan" adb_replisten="53" @@ -45,10 +42,13 @@ adb_cnt="" adb_rc=0 adb_action="${1:-"start"}" adb_pidfile="/var/run/adblock.pid" +adb_ubusservice="/etc/adblock/adblock.service" +adb_mailservice="/etc/adblock/adblock.mail" +adb_sources="" # load adblock environment # -f_envload() +f_load() { local dns_up sys_call sys_desc sys_model cnt=0 @@ -57,18 +57,11 @@ f_envload() sys_call="$(ubus -S call system board 2>/dev/null)" if [ -n "${sys_call}" ] then - sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')" - sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')" + sys_desc="$(printf "%s" "${sys_call}" | jsonfilter -e '@.release.description')" + sys_model="$(printf "%s" "${sys_call}" | jsonfilter -e '@.model')" adb_sysver="${sys_model}, ${sys_desc}" fi - # check hash utility - # - if [ ! -x "${adb_hashutil}" ] - then - adb_hashutil="$(command -v md5sum)" - fi - # parse 'global' and 'extra' section by callback # config_cb() @@ -108,71 +101,78 @@ f_envload() config_load adblock config_foreach parse_config source - # check dns backend + # version check + # + if [ -z "${adb_basever}" ] || [ "${adb_ver%.*}" != "${adb_basever}" ] + then + f_log "info" "your adblock config seems to be too old, please update your config with the '--force-maintainer' opkg option" + exit 0 + fi + + # set dns backend # case "${adb_dns}" in - dnsmasq) + "dnsmasq") adb_dnsinstance="${adb_dnsinstance:-"0"}" adb_dnsuser="${adb_dnsuser:-"dnsmasq"}" adb_dnsdir="${adb_dnsdir:-"/tmp"}" adb_dnsheader="" - adb_dnsdeny="awk '{print \"server=/\"\$0\"/\"}'" - adb_dnsallow="awk '{print \"server=/\"\$0\"/#\"}'" - adb_dnshalt="server=/#/" + if [ "${adb_dnsvariant}" = "nxdomain" ] + then + adb_dnsdeny="awk '{print \"server=/\"\$0\"/\"}'" + adb_dnsallow="awk '{print \"server=/\"\$0\"/#\"}'" + elif [ "${adb_dnsvariant}" = "null (IPv4)" ] + then + adb_dnsdeny="awk '{print \"0.0.0.0\\t\"\$0\"\"}'" + elif [ "${adb_dnsvariant}" = "null (IPv4/IPv6)" ] + then + adb_dnsdeny="awk '{print \"0.0.0.0\\t\"\$0\"\\n::\\t\"\$0\"\"}'" + fi + adb_dnsallow="" ;; - unbound) + "unbound") adb_dnsinstance="${adb_dnsinstance:-"0"}" adb_dnsuser="${adb_dnsuser:-"unbound"}" adb_dnsdir="${adb_dnsdir:-"/var/lib/unbound"}" adb_dnsheader="" - adb_dnsdeny="awk '{print \"local-zone: \042\"\$0\"\042 static\"}'" - adb_dnsallow="awk '{print \"local-zone: \042\"\$0\"\042 transparent\"}'" - adb_dnshalt="local-zone: \".\" static" + adb_dnsdeny="awk '{print \"local-zone: \\042\"\$0\"\\042 static\"}'" + adb_dnsallow="awk '{print \"local-zone: \\042\"\$0\"\\042 transparent\"}'" ;; - named) + "named") adb_dnsinstance="${adb_dnsinstance:-"0"}" adb_dnsuser="${adb_dnsuser:-"bind"}" adb_dnsdir="${adb_dnsdir:-"/var/lib/bind"}" adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'" IN NS localhost." - adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'" - adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'" - adb_dnshalt="* CNAME ." + adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\\n*.\"\$0\" CNAME .\"}'" + adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\\n*.\"\$0\" CNAME rpz-passthru.\"}'" ;; - kresd) + "kresd") adb_dnsinstance="${adb_dnsinstance:-"0"}" adb_dnsuser="${adb_dnsuser:-"root"}" adb_dnsdir="${adb_dnsdir:-"/etc/kresd"}" adb_dnsheader="\$TTL 2h"$'\n'"@ IN SOA localhost. root.localhost. (1 6h 1h 1w 2h)"$'\n'" IN NS localhost." - adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\n*.\"\$0\" CNAME .\"}'" - adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\n*.\"\$0\" CNAME rpz-passthru.\"}'" - adb_dnshalt="* CNAME ." - ;; - dnscrypt-proxy) - adb_dnsinstance="${adb_dnsinstance:-"0"}" - adb_dnsuser="${adb_dnsuser:-"nobody"}" - adb_dnsdir="${adb_dnsdir:-"/tmp"}" - adb_dnsheader="" - adb_dnsdeny="awk '{print \$0}'" - adb_dnsallow="" - adb_dnshalt="" + adb_dnsdeny="awk '{print \"\"\$0\" CNAME .\\n*.\"\$0\" CNAME .\"}'" + adb_dnsallow="awk '{print \"\"\$0\" CNAME rpz-passthru.\\n*.\"\$0\" CNAME rpz-passthru.\"}'" ;; esac - # check adblock status + # status check # - if [ ${adb_enabled} -eq 0 ] + if [ "${adb_enabled}" -eq 0 ] then f_extconf f_temp f_rmdns f_jsnup "disabled" - f_log "info" "adblock is currently disabled, please set adb_enabled to '1' to use this service" + f_log "info" "adblock is currently disabled, please set the config option 'adb_enabled' to '1' to use this service" exit 0 fi + # dns backend check + # if [ -d "${adb_dnsdir}" ] && [ ! -f "${adb_dnsdir}/${adb_dnsfile}" ] then - printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}" + printf "%s\\n" "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}" fi if [ "${adb_action}" = "start" ] && [ "${adb_trigger}" = "timed" ] @@ -180,7 +180,7 @@ f_envload() sleep ${adb_triggerdelay} fi - while [ ${cnt} -le 30 ] + while [ "${cnt}" -le 30 ] do dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" 2>/dev/null | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running" 2>/dev/null)" if [ "${dns_up}" = "true" ] @@ -193,27 +193,29 @@ f_envload() if [ "${dns_up}" != "true" ] || [ -z "${adb_dns}" ] || [ ! -x "$(command -v ${adb_dns})" ] then - f_log "err" "'${adb_dns}' not running or not executable" + f_log "err" "'${adb_dns}' not running or executable" elif [ ! -d "${adb_dnsdir}" ] then f_log "err" "'${adb_dnsdir}' backend directory not found" fi } -# check environment +# check & set environment # -f_envcheck() +f_env() { local ssl_lib - # startup message - # f_log "info" "adblock instance started ::: action: ${adb_action}, priority: ${adb_nice:-"0"}, pid: ${$}" f_jsnup "running" + f_extconf - # check external uci config files + # check backup directory # - f_extconf + if [ ! -d "${adb_backupdir}" ] + then + f_log "err" "the backup directory '${adb_backupdir}' does not exist/is not mounted yet, please create the directory or raise the 'adb_triggerdelay' to defer the adblock start" + fi # check fetch utility # @@ -260,15 +262,18 @@ f_envcheck() # f_temp() { - if [ -z "${adb_tmpdir}" ] + if [ -d "/tmp" ] && [ -z "${adb_tmpdir}" ] then adb_tmpdir="$(mktemp -p /tmp -d)" - adb_tmpload="$(mktemp -p ${adb_tmpdir} -tu)" - adb_tmpfile="$(mktemp -p ${adb_tmpdir} -tu)" + adb_tmpload="$(mktemp -p "${adb_tmpdir}" -tu)" + adb_tmpfile="$(mktemp -p "${adb_tmpdir}" -tu)" + elif [ ! -d "/tmp" ] + then + f_log "err" "the temp directory '/tmp' does not exist/is not mounted yet, please create the directory or raise the 'adb_triggerdelay' to defer the adblock start" fi if [ ! -s "${adb_pidfile}" ] then - printf '%s' "${$}" > "${adb_pidfile}" + printf "%s" "${$}" > "${adb_pidfile}" fi } @@ -283,22 +288,16 @@ f_rmtemp() > "${adb_pidfile}" } -# remove dns related files and directories +# remove dns related files, services and directories # f_rmdns() { if [ -n "${adb_dns}" ] then - f_hash - printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}" - > "${adb_dnsdir}/.${adb_dnsfile}" + printf "%s\\n" "${adb_dnsheader}" > "${adb_dnsdir}"/"${adb_dnsfile}" > "${adb_rtfile}" - rm -f "${adb_backupdir}/${adb_dnsprefix}"*.gz - f_hash - if [ ${?} -eq 1 ] - then - f_dnsup - fi + rm -f "${adb_backupdir}"/"${adb_dnsprefix}"*".gz" + f_dnsup f_rmtemp fi 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}" @@ -317,7 +316,7 @@ f_uci() then uci_commit "${config}" case "${config}" in - firewall) + "firewall") /etc/init.d/firewall reload >/dev/null 2>&1 ;; *) @@ -336,17 +335,23 @@ f_count() local mode="${1}" adb_cnt=0 - if [ -s "${adb_dnsdir}/${adb_dnsfile}" ] && ([ -z "${mode}" ] || [ "${mode}" = "final" ]) + if [ -s "${adb_dnsdir}/${adb_dnsfile}" ] && { [ -z "${mode}" ] || [ "${mode}" = "final" ]; } then adb_cnt="$(wc -l 2>/dev/null < "${adb_dnsdir}/${adb_dnsfile}")" - if [ -s "${adb_tmpdir}/tmp.add_whitelist" ] + if [ -s "${adb_tmpdir}/tmp.add.whitelist" ] then - adb_cnt="$(( ${adb_cnt} - $(wc -l 2>/dev/null < "${adb_tmpdir}/tmp.add_whitelist") ))" + adb_cnt="$((adb_cnt-$(wc -l 2>/dev/null < "${adb_tmpdir}/tmp.add.whitelist")))" fi - if [ "${adb_dns}" = "named" ] || [ "${adb_dns}" = "kresd" ] + if [ "${adb_dns}" = "named" ] || [ "${adb_dns}" = "kresd" ] || { [ "${adb_dns}" = "dnsmasq" ] && [ "${adb_dnsvariant}" = "null (IPv4/IPv6)" ]; } then - adb_cnt="$(( (${adb_cnt} - $(printf '%s' "${adb_dnsheader}" | grep -c "^")) / 2 ))" + adb_cnt="$(((adb_cnt-$(printf "%s" "${adb_dnsheader}" | grep -c "^"))/2))" fi + elif [ "${mode}" = "blacklist" ] && [ -s "${adb_tmpfile}.blacklist" ] + then + adb_cnt="$(wc -l 2>/dev/null < "${adb_tmpfile}.blacklist")" + elif [ "${mode}" = "whitelist" ] && [ -s "${adb_tmpdir}/tmp.raw.whitelist" ] + then + adb_cnt="$(wc -l 2>/dev/null < "${adb_tmpdir}/tmp.raw.whitelist")" elif [ -s "${adb_tmpfile}" ] then adb_cnt="$(wc -l 2>/dev/null < "${adb_tmpfile}")" @@ -360,31 +365,49 @@ f_extconf() local uci_config port port_list="53 853 5353" case "${adb_dns}" in - dnsmasq) + "dnsmasq") uci_config="dhcp" - if [ ${adb_enabled} -eq 1 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]")" ] && \ - [ -z "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] && \ - [ -z "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsjail}")" ] + if [ "${adb_dnsvariant}" = "nxdomain" ] then - uci_set dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile "${adb_dnsdir}/${adb_dnsfile}" - elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + if [ "${adb_enabled}" -eq 1 ] && [ -z "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + then + uci_set dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile "${adb_dnsdir}/${adb_dnsfile}" + if [ "${adb_enabled}" -eq 1 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" addnhosts | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + then + uci -q del_list dhcp.@dnsmasq[${adb_dnsinstance}].addnhosts="${adb_dnsdir}/${adb_dnsfile}" + fi + elif [ "${adb_enabled}" -eq 0 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + then + uci_remove dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile + fi + elif [ "${adb_dnsvariant% *}" = "null" ] then - uci_remove dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile + if [ "${adb_enabled}" -eq 1 ] && [ -z "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" addnhosts | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + then + uci -q add_list dhcp.@dnsmasq[${adb_dnsinstance}].addnhosts="${adb_dnsdir}/${adb_dnsfile}" + if [ "${adb_enabled}" -eq 1 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + then + uci_remove dhcp "@dnsmasq[${adb_dnsinstance}]" serversfile + fi + elif [ "${adb_enabled}" -eq 0 ] && [ -n "$(uci_get dhcp "@dnsmasq[${adb_dnsinstance}]" addnhosts | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + then + uci_remove dhcp "@dnsmasq[${adb_dnsinstance}]" addnhosts + fi fi ;; - kresd) + "kresd") uci_config="resolver" - if [ ${adb_enabled} -eq 1 ] && [ -z "$(uci_get resolver kresd rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + if [ "${adb_enabled}" -eq 1 ] && [ -z "$(uci_get resolver kresd rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] then uci -q add_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}" - elif [ ${adb_enabled} -eq 0 ] && [ -n "$(uci_get resolver kresd rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] + elif [ "${adb_enabled}" -eq 0 ] && [ -n "$(uci_get resolver kresd rpz_file | grep -Fo "${adb_dnsdir}/${adb_dnsfile}")" ] then uci -q del_list resolver.kresd.rpz_file="${adb_dnsdir}/${adb_dnsfile}" fi - if [ ${adb_enabled} -eq 1 ] && [ ${adb_dnsflush} -eq 0 ] && [ "$(uci_get resolver kresd keep_cache)" != "1" ] + if [ "${adb_enabled}" -eq 1 ] && [ "${adb_dnsflush}" -eq 0 ] && [ "$(uci_get resolver kresd keep_cache)" != "1" ] then uci_set resolver kresd keep_cache "1" - elif [ ${adb_enabled} -eq 0 ] || ([ ${adb_dnsflush} -eq 1 ] && [ "$(uci_get resolver kresd keep_cache)" = "1" ]) + elif [ "${adb_enabled}" -eq 0 ] || { [ "${adb_dnsflush}" -eq 1 ] && [ "$(uci_get resolver kresd keep_cache)" = "1" ]; } then uci_set resolver kresd keep_cache "0" fi @@ -393,8 +416,8 @@ f_extconf() f_uci "${uci_config}" uci_config="firewall" - if [ ${adb_enabled} -eq 1 ] && [ ${adb_forcedns} -eq 1 ] && \ - [ -z "$(uci_get firewall adblock_dns_53)" ] && [ $(/etc/init.d/firewall enabled; printf '%u' ${?}) -eq 0 ] + if [ "${adb_enabled}" -eq 1 ] && [ "${adb_forcedns}" -eq 1 ] && \ + [ -z "$(uci_get firewall adblock_dns_53)" ] && [ "$(/etc/init.d/firewall enabled; printf "%u" ${?})" -eq 0 ] then for port in ${port_list} do @@ -406,7 +429,7 @@ f_extconf() uci_set firewall "adblock_dns_${port}" "dest_port" "${port}" uci_set firewall "adblock_dns_${port}" "target" "DNAT" done - elif [ -n "$(uci_get firewall adblock_dns_53)" ] && ([ ${adb_enabled} -eq 0 ] || [ ${adb_forcedns} -eq 0 ]) + elif [ -n "$(uci_get firewall adblock_dns_53)" ] && { [ "${adb_enabled}" -eq 0 ] || [ "${adb_forcedns}" -eq 0 ]; } then for port in ${port_list} do @@ -422,14 +445,20 @@ f_dnsup() { local dns_up cache_util cache_rc cnt=0 - if [ ${adb_dnsflush} -eq 0 ] && [ ${adb_enabled} -eq 1 ] && [ "${adb_rc}" -eq 0 ] + if [ "${adb_dnsflush}" -eq 0 ] && [ "${adb_enabled}" -eq 1 ] && [ "${adb_rc}" -eq 0 ] then case "${adb_dns}" in - dnsmasq) - killall -q -HUP "${adb_dns}" - cache_rc=${?} + "dnsmasq") + if [ "${adb_dnsvariant}" = "nxdomain" ] + then + killall -q -HUP "${adb_dns}" + cache_rc=${?} + elif [ "${adb_dnsvariant% *}" = "null" ] + then + "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1 + fi ;; - unbound) + "unbound") cache_util="$(command -v unbound-control)" if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -f "${adb_dnsdir}"/unbound.conf ] then @@ -437,12 +466,12 @@ f_dnsup() fi "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1 ;; - kresd) + "kresd") cache_util="keep_cache" "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1 cache_rc=${?} ;; - named) + "named") cache_util="$(command -v rndc)" if [ -x "${cache_util}" ] && [ -f /etc/bind/rndc.conf ] then @@ -452,30 +481,25 @@ f_dnsup() "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1 fi ;; - *) - "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1 - ;; esac - else - "/etc/init.d/${adb_dns}" restart >/dev/null 2>&1 fi adb_rc=1 - while [ ${cnt} -le 10 ] + while [ "${cnt}" -le 10 ] do dns_up="$(ubus -S call service list "{\"name\":\"${adb_dns}\"}" | jsonfilter -l1 -e "@[\"${adb_dns}\"].instances.*.running")" if [ "${dns_up}" = "true" ] then case "${adb_dns}" in - unbound) + "unbound") cache_util="$(command -v unbound-control)" if [ -x "${cache_util}" ] && [ -d "${adb_tmpdir}" ] && [ -s "${adb_tmpdir}"/adb_cache.dump ] then - while [ ${cnt} -le 10 ] + while [ "${cnt}" -le 10 ] do "${cache_util}" -c "${adb_dnsdir}"/unbound.conf load_cache < "${adb_tmpdir}"/adb_cache.dump >/dev/null 2>&1 cache_rc=${?} - if [ ${cache_rc} -eq 0 ] + if [ "${cache_rc}" -eq 0 ] then break fi @@ -485,6 +509,7 @@ f_dnsup() fi ;; esac + sleep 1 adb_rc=0 break fi @@ -499,35 +524,69 @@ f_dnsup() # f_list() { - local file mode="${1}" in_rc="${adb_rc}" + local file name tmp_file="${adb_tmpfile}" mode="${1}" in_rc="${adb_rc}" case "${mode}" in - backup) + "blacklist") + if [ -s "${adb_blacklist}" ] + then + src_name="${mode}" + adb_blacklist_rset="/^([[:alnum:]_-]+\\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}" + awk "${adb_blacklist_rset}" "${adb_blacklist}" > "${adb_tmpfile}"."${src_name}" + fi + ;; + "whitelist") + if [ -s "${adb_whitelist}" ] + then + src_name="${mode}" + adb_whitelist_rset="/^([[:alnum:]_-]+\\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}" + awk "${adb_whitelist_rset}" "${adb_whitelist}" > "${adb_tmpdir}"/tmp.raw."${src_name}" + + adb_whitelist_rset="/^([[:alnum:]_-]+\\.)+[[:alpha:]]+([[:space:]]|$)/{gsub(\"\\\.\",\"\\\.\",\$1);print tolower(\"^\"\$1\"\\\|\\\.\"\$1)}" + awk "${adb_whitelist_rset}" "${adb_tmpdir}"/tmp.raw."${src_name}" > "${adb_tmpdir}"/tmp.rem."${src_name}" + + if [ -n "${adb_dnsallow}" ] + then + eval "${adb_dnsallow}" "${adb_tmpdir}"/tmp.raw."${src_name}" > "${adb_tmpdir}"/tmp.add."${src_name}" + fi + fi + ;; + "backup") if [ -d "${adb_backupdir}" ] then gzip -cf "${adb_tmpfile}" 2>/dev/null > "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" adb_rc=${?} fi ;; - restore) - if [ -d "${adb_backupdir}" ] && [ -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" ] + "restore") + if [ -d "${adb_backupdir}" ] then - gunzip -cf "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" 2>/dev/null > "${adb_tmpfile}" + if [ -n "${src_name}" ] && [ -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" ] + then + zcat "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" 2>/dev/null > "${adb_tmpfile}" + else + for file in "${adb_backupdir}/${adb_dnsprefix}."*".gz" + do + name="${file##*/}" + name="${name%.*}" + zcat "${file}" 2>/dev/null > "${adb_tmpfile}"."${name}" + done + fi adb_rc=${?} fi ;; - remove) + "remove") if [ -d "${adb_backupdir}" ] then rm -f "${adb_backupdir}/${adb_dnsprefix}.${src_name}.gz" fi adb_rc=${?} ;; - merge) + "merge") for file in "${adb_tmpfile}".* do cat "${file}" 2>/dev/null >> "${adb_tmpdir}/${adb_dnsfile}" - if [ ${?} -ne 0 ] + if [ "${?}" -ne 0 ] then adb_rc=${?} break @@ -536,24 +595,24 @@ f_list() done adb_tmpfile="${adb_tmpdir}/${adb_dnsfile}" ;; - final) + "final") > "${adb_dnsdir}/${adb_dnsfile}" - if [ -s "${adb_tmpdir}/tmp.add_whitelist" ] + if [ -s "${adb_tmpdir}/tmp.add.whitelist" ] then - cat "${adb_tmpdir}/tmp.add_whitelist" >> "${adb_dnsdir}/${adb_dnsfile}" + cat "${adb_tmpdir}/tmp.add.whitelist" >> "${adb_dnsdir}/${adb_dnsfile}" fi - if [ -s "${adb_tmpdir}/tmp.rem_whitelist" ] + if [ -s "${adb_tmpdir}/tmp.rem.whitelist" ] then - grep -vf "${adb_tmpdir}/tmp.rem_whitelist" "${adb_tmpdir}/${adb_dnsfile}" | eval "${adb_dnsdeny}" >> "${adb_dnsdir}/${adb_dnsfile}" + grep -vf "${adb_tmpdir}/tmp.rem.whitelist" "${adb_tmpdir}/${adb_dnsfile}" | eval "${adb_dnsdeny}" >> "${adb_dnsdir}/${adb_dnsfile}" else eval "${adb_dnsdeny}" "${adb_tmpdir}/${adb_dnsfile}" >> "${adb_dnsdir}/${adb_dnsfile}" fi - if [ ${?} -eq 0 ] && [ -n "${adb_dnsheader}" ] + if [ "${?}" -eq 0 ] && [ -n "${adb_dnsheader}" ] then - printf '%s\n' "${adb_dnsheader}" | cat - "${adb_dnsdir}/${adb_dnsfile}" > "${adb_tmpdir}/${adb_dnsfile}" + printf "%s\\n" "${adb_dnsheader}" | cat - "${adb_dnsdir}/${adb_dnsfile}" > "${adb_tmpdir}/${adb_dnsfile}" mv -f "${adb_tmpdir}/${adb_dnsfile}" "${adb_dnsdir}/${adb_dnsfile}" fi adb_rc=${?} @@ -567,24 +626,23 @@ f_list() # f_tld() { - local cnt cnt_srt cnt_tld source="${1}" temp_src="${1}.src.gz" temp_tld="${1}.tld" tld_ok="false" + local cnt cnt_srt cnt_tld source="${1}" temp_tld="${1}.tld" tld_ok="false" - gzip -cf "${source}" 2>/dev/null > "${temp_src}" - if [ ${?} -eq 0 ] - then - cnt="$(wc -l 2>/dev/null < "${source}")" + cnt="$(wc -l 2>/dev/null < "${source}")" + if [ "${adb_dns}" != "dnsmasq" ] && [ "${adb_dnsvariant% *}" != "null" ] + then awk 'BEGIN{FS="."}{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${source}" > "${temp_tld}" - if [ ${?} -eq 0 ] + if [ "${?}" -eq 0 ] then sort -u "${temp_tld}" > "${source}" - if [ ${?} -eq 0 ] + if [ "${?}" -eq 0 ] then cnt_srt="$(wc -l 2>/dev/null < "${source}")" awk '{if(NR==1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "${source}" > "${temp_tld}" - if [ ${?} -eq 0 ] + if [ "${?}" -eq 0 ] then awk 'BEGIN{FS="."}{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "${temp_tld}" > "${source}" - if [ ${?} -eq 0 ] + if [ "${?}" -eq 0 ] then rm -f "${temp_src}" "${temp_tld}" cnt_tld="$(wc -l 2>/dev/null < "${source}")" @@ -593,90 +651,72 @@ f_tld() fi fi fi + else + sort -u "${source}" > "${temp_tld}" + if [ "${?}" -eq 0 ] + then + mv -f "${temp_tld}" "${source}" + cnt_srt="$(wc -l 2>/dev/null < "${source}")" + tld_ok="true" + fi fi - if [ "${tld_ok}" = "false" ] then + unset cnt_srt cnt_tld rm -f "${temp_tld}" - gunzip -cf "${temp_src}" 2>/dev/null > "${source}" - if [ ${?} -ne 0 ] - then - rm -f "${temp_src}" - > "${source}" - fi + f_list blacklist + f_list whitelist + f_list restore + f_list merge + f_list final + cnt="$(wc -l 2>/dev/null < "${adb_tmpdir}"/"${adb_dnsfile}")" fi f_log "debug" "f_tld ::: source: ${source}, cnt: ${cnt:-"-"}, cnt_srt: ${cnt_srt:-"-"}, cnt_tld: ${cnt_tld:-"-"}, tld_ok: ${tld_ok}" } -# blocklist hash compare -# -f_hash() -{ - local hash hash_rc=1 - - if [ -x "${adb_hashutil}" ] && [ -f "${adb_dnsdir}/${adb_dnsfile}" ] - then - hash="$(${adb_hashutil} "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null | awk '{print $1}')" - if [ -z "${adb_hashold}" ] && [ -n "${hash}" ] - then - adb_hashold="${hash}" - elif [ -z "${adb_hashnew}" ] && [ -n "${hash}" ] - then - adb_hashnew="${hash}" - fi - if [ -n "${adb_hashold}" ] && [ -n "${adb_hashnew}" ] - then - if [ "${adb_hashold}" = "${adb_hashnew}" ] - then - hash_rc=0 - fi - adb_hashold="" - adb_hashnew="" - fi - fi - f_log "debug" "f_hash ::: hash_util: ${adb_hashutil}, hash: ${hash}, out_rc: ${hash_rc}" - return ${hash_rc} -} - # suspend/resume adblock processing # f_switch() { - local status cnt mode="${1}" + local status done="false" mode="${1}" json_load_file "${adb_rtfile}" >/dev/null 2>&1 - json_select "data" + json_select "data" >/dev/null 2>&1 json_get_var status "adblock_status" - json_get_var cnt "overall_domains" - + f_temp if [ "${mode}" = "suspend" ] && [ "${status}" = "enabled" ] then - if [ ${cnt%% *} -gt 0 ] && [ -s "${adb_dnsdir}/${adb_dnsfile}" ] + > "${adb_dnsdir}/${adb_dnsfile}" + if [ -n "${adb_dnsheader}" ] then - f_hash - cat "${adb_dnsdir}/${adb_dnsfile}" > "${adb_dnsdir}/.${adb_dnsfile}" - printf '%s\n' "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}" - f_hash + printf "%s\\n" "${adb_dnsheader}" > "${adb_dnsdir}/${adb_dnsfile}" fi + done="true" elif [ "${mode}" = "resume" ] && [ "${status}" = "paused" ] then - if [ ${cnt%% *} -gt 0 ] && [ -s "${adb_dnsdir}/.${adb_dnsfile}" ] - then - f_hash - cat "${adb_dnsdir}/.${adb_dnsfile}" > "${adb_dnsdir}/${adb_dnsfile}" - > "${adb_dnsdir}/.${adb_dnsfile}" - f_hash - fi + f_list blacklist + f_list whitelist + f_list restore + f_list merge + f_tld "${adb_tmpdir}"/"${adb_dnsfile}" + f_list final + done="true" fi - if [ ${?} -eq 1 ] + if [ "${done}" = "true" ] then - f_temp + if [ "${mode}" = "suspend" ] + then + f_bgserv "stop" + fi f_dnsup + if [ "${mode}" = "resume" ] + then + f_bgserv "start" + fi f_jsnup "${mode}" f_log "info" "${mode} adblock processing" - f_rmtemp - exit 0 fi + f_rmtemp } # query blocklist for certain (sub-)domains @@ -687,54 +727,65 @@ f_query() if [ -z "${domain}" ] || [ "${domain}" = "${tld}" ] then - printf '%s\n' "::: invalid domain input, please submit a single domain, e.g. 'doubleclick.net'" + printf "%s\\n" "::: invalid domain input, please submit a single domain, e.g. 'doubleclick.net'" else case "${adb_dns}" in - dnsmasq) - prefix=".*[\/\.]" - suffix="(\/)" - field=2 + "dnsmasq") + if [ "${adb_dnsvariant}" = "nxdomain" ] + then + prefix=".*[\\/\\.]" + suffix="(\\/)" + field=2 + elif [ "${adb_dnsvariant% *}" = "null" ] + then + prefix=".*[\\t\\.]" + suffix="" + field=2 + fi ;; - unbound) - prefix=".*[\"\.]" + "unbound") + prefix=".*[\"\\.]" suffix="(static)" field=3 ;; - named) - prefix="[^\*].*[\.]" - suffix="( \.)" + "named") + prefix="[^\\*].*[\\.]" + suffix="( \\.)" field=1 ;; - kresd) - prefix="[^\*].*[\.]" - suffix="( \.)" - field=1 - ;; - dnscrypt-proxy) - prefix=".*[\.]" - suffix="" + "kresd") + prefix="[^\\*].*[\\.]" + suffix="( \\.)" field=1 ;; esac - while [ "${domain}" != "${tld}" ] - do - search="${domain//./\\.}" - search="${search//[+*~%\$&\"\']/}" - result="$(awk -F '/|\"| ' "/^(${search}|${prefix}+${search}.*${suffix}$)/{i++;{printf(\" + %s\n\",\$${field})};if(i>9){printf(\" + %s\n\",\"[...]\");exit}}" "${adb_dnsdir}/${adb_dnsfile}")" - printf '%s\n%s\n%s\n' ":::" "::: results for domain '${domain}'" ":::" - printf '%s\n' "${result:-" - no match"}" - domain="${tld}" - tld="${domain#*.}" - done - - if [ ${adb_backup} -eq 1 ] && [ -d "${adb_backupdir}" ] + if [ "${adb_dnsfilereset}" = "false" ] + then + while [ "${domain}" != "${tld}" ] + do + search="${domain//./\\.}" + search="${search//[+*~%\$&\"\']/}" + result="$(awk -F '/|\"|\t| ' "/^(${prefix}+${search}.*${suffix}$)/{i++;{printf(\" + %s\\n\",\$${field})};if(i>9){printf(\" + %s\\n\",\"[...]\");exit}}" "${adb_dnsdir}/${adb_dnsfile}")" + printf "%s\\n%s\\n%s\\n" ":::" "::: results for domain '${domain}' in active blocklist" ":::" + printf "%s\n\n" "${result:-" - no match"}" + domain="${tld}" + tld="${domain#*.}" + done + fi + if [ -d "${adb_backupdir}" ] then search="${1//./\\.}" search="${search//[+*~%\$&\"\']/}" - printf '%s\n%s\n%s\n' ":::" "::: results for domain '${1}' in backups" ":::" - for file in ${adb_backupdir}/${adb_dnsprefix}.*.gz + printf "%s\\n%s\\n%s\\n" ":::" "::: results for domain '${1}' in backups and black-/whitelist" ":::" + for file in "${adb_backupdir}"/"${adb_dnsprefix}".*.gz "${adb_blacklist}" "${adb_whitelist}" do - zcat "${file}" 2>/dev/null | awk -v f="${file##*/}" "/^($search|.*\.${search})/{i++;{printf(\" + %-30s%s\n\",f,\$1)};if(i>=3){printf(\" + %-30s%s\n\",f,\"[...]\");exit}}" + suffix="${file##*.}" + if [ "${suffix}" = "gz" ] + then + zcat "${file}" 2>/dev/null | awk -v f="${file##*/}" "/^($search|.*\\.${search})/{i++;{printf(\" + %-30s%s\\n\",f,\$1)};if(i>=3){printf(\" + %-30s%s\\n\",f,\"[...]\");exit}}" + else + cat "${file}" 2>/dev/null | awk -v f="${file##*/}" "/^($search|.*\\.${search})/{i++;{printf(\" + %-30s%s\\n\",f,\$1)};if(i>=3){printf(\" + %-30s%s\\n\",f,\"[...]\");exit}}" + fi done fi fi @@ -744,9 +795,9 @@ f_query() # f_jsnup() { - local run_time bg_pid status="${1:-"enabled"}" mode="normal mode" + local run_time bg_pid status="${1:-"enabled"}" - if [ ${adb_rc} -gt 0 ] + if [ "${adb_rc}" -gt 0 ] then status="error" run_time="$(/bin/date "+%d.%m.%Y %H:%M:%S")" @@ -763,14 +814,10 @@ f_jsnup() then status="" fi - if [ ${adb_backup_mode} -eq 1 ] - then - mode="backup mode" - fi json_load_file "${adb_rtfile}" >/dev/null 2>&1 json_select "data" >/dev/null 2>&1 - if [ ${?} -eq 0 ] + if [ "${?}" -eq 0 ] then if [ -z "${adb_fetchinfo}" ] then @@ -793,21 +840,23 @@ f_jsnup() json_add_object "data" json_add_string "adblock_status" "${status:-"enabled"}" json_add_string "adblock_version" "${adb_ver}" - json_add_string "overall_domains" "${adb_cnt:-0} (${mode})" + json_add_string "overall_domains" "${adb_cnt:-0}" json_add_string "fetch_utility" "${adb_fetchinfo:-"-"}" - json_add_string "dns_backend" "${adb_dns} (${adb_dnsdir})" + json_add_string "dns_backend" "${adb_dns}, ${adb_dnsdir}" + json_add_string "dns_variant" "${adb_dnsvariant}, ${adb_dnsfilereset:-"false"}" + json_add_string "backup_dir" "${adb_backupdir}" json_add_string "last_rundate" "${run_time:-"-"}" json_add_string "system_release" "${adb_sysver}" json_close_object json_dump > "${adb_rtfile}" - if [ ${adb_notify} -eq 1 ] && [ -x /etc/adblock/adblock.notify ] && \ - ([ "${status}" = "error" ] || ([ "${status}" = "enabled" ] && [ ${adb_cnt} -le ${adb_notifycnt} ])) + if [ ${adb_mail} -eq 1 ] && [ -x "${adb_mailservice}" ] && \ + { [ "${status}" = "error" ] || { [ "${status}" = "enabled" ] && [ "${adb_cnt}" -le "${adb_mcnt}" ]; } } then - (/etc/adblock/adblock.notify >/dev/null 2>&1)& + ("${adb_mailservice}" >/dev/null 2>&1)& bg_pid=${!} fi - f_log "debug" "f_jsnup ::: status: ${status:-"-"}, mode: ${mode}, cnt: ${adb_cnt}, notify: ${adb_notify}, notify_cnt: ${adb_notifycnt}, notify_pid: ${bg_pid:-"-"}" + f_log "debug" "f_jsnup ::: status: ${status:-"-"}, cnt: ${adb_cnt}, mail: ${adb_mail}, mail_service: ${adb_mailservice}, mail_cnt: ${adb_mcnt}, mail_pid: ${bg_pid:-"-"}" } # write to syslog @@ -816,7 +865,7 @@ f_log() { local class="${1}" log_msg="${2}" - if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${adb_debug} -eq 1 ]) + if [ -n "${log_msg}" ] && { [ "${class}" != "debug" ] || [ ${adb_debug} -eq 1 ]; } then logger -p "${class}" -t "adblock-${adb_ver}[${$}]" "${log_msg}" if [ "${class}" = "err" ] @@ -829,6 +878,24 @@ f_log() fi } +# start ubus monitor service to trace dns backend events +# +f_bgserv() +{ + local bg_pid status="${1}" + + bg_pid="$(pgrep -f "^/bin/sh ${adb_ubusservice}|^/bin/ubus -S -M r -m invoke monitor|^grep -qF \"method\":\"set\",\"data\":\\{\"name\":\"${adb_dns}\"" | awk '{ORS=" "; print $1}')" + if [ -z "${bg_pid}" ] && [ "${status}" = "start" ] \ + && [ -x "${adb_ubusservice}" ] && [ "${adb_dnsfilereset}" = "true" ] + then + ( "${adb_ubusservice}" &) + elif [ -n "${bg_pid}" ] && [ "${status}" = "stop" ] + then + kill -HUP ${bg_pid} + fi + f_log "debug" "f_bgserv ::: status: ${status:-"-"}, bg_pid: ${bg_pid:-"-"}, dns_filereset: ${adb_dnsfilereset:-"-"}, ubus_service: ${adb_ubusservice:-"-"}" +} + # main function for blocklist processing # f_main() @@ -839,57 +906,25 @@ f_main() mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)" tmp_load="${adb_tmpload}" tmp_file="${adb_tmpfile}" - > "${adb_dnsdir}/.${adb_dnsfile}" - > "${adb_tmpdir}/tmp.raw_whitelist" - > "${adb_tmpdir}/tmp.add_whitelist" - > "${adb_tmpdir}/tmp.rem_whitelist" - 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_dns: ${adb_forcedns}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${adb_maxqueue}" - - # prepare whitelist entries - # - if [ -s "${adb_whitelist}" ] - then - adb_whitelist_rset="/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{print tolower(\$1)}" - awk "${adb_whitelist_rset}" "${adb_whitelist}" > "${adb_tmpdir}/tmp.raw_whitelist" - f_tld "${adb_tmpdir}/tmp.raw_whitelist" - - adb_whitelist_rset="/^([[:alnum:]_-]+\.)+[[:alpha:]]+([[:space:]]|$)/{gsub(\"\\\.\",\"\\\.\",\$1);print tolower(\"^\"\$1\"\\\|\\\.\"\$1)}" - awk "${adb_whitelist_rset}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.rem_whitelist" - - if [ -n "${adb_dnsallow}" ] - then - eval "${adb_dnsallow}" "${adb_tmpdir}/tmp.raw_whitelist" > "${adb_tmpdir}/tmp.add_whitelist" - fi - fi - - # build 'dnsjail' list - # - if [ ${adb_jail} -eq 1 ] - then - cat "${adb_tmpdir}/tmp.add_whitelist" > "/tmp/${adb_dnsjail}" - printf '%s\n' "${adb_dnshalt}" >> "/tmp/${adb_dnsjail}" - if [ -n "${adb_dnsheader}" ] - then - printf '%s\n' "${adb_dnsheader}" | cat - "/tmp/${adb_dnsjail}" > "${adb_tmpdir}/tmp.dnsjail" - cat "${adb_tmpdir}/tmp.dnsjail" > "/tmp/${adb_dnsjail}" - fi - fi - + f_log "debug" "f_main ::: dns: ${adb_dns}, fetch_util: ${adb_fetchinfo}, force_dns: ${adb_forcedns}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${adb_maxqueue}" + # main loop # + f_list blacklist + f_list whitelist for src_name in ${adb_sources} do - enabled="$(eval printf '%s' \"\${enabled_${src_name}\}\")" - src_url="$(eval printf '%s' \"\${adb_src_${src_name}\}\")" - src_rset="$(eval printf '%s' \"\${adb_src_rset_${src_name}\}\")" - src_cat="$(eval printf '%s' \"\${adb_src_cat_${src_name}\}\")" - adb_tmpload="${tmp_load}.${src_name}" - adb_tmpfile="${tmp_file}.${src_name}" + enabled="$(eval printf "%s" \"\$\{enabled_${src_name}\}\")" + src_url="$(eval printf "%s" \"\$\{adb_src_${src_name}\}\")" + src_rset="$(eval printf "%s" \"\$\{adb_src_rset_${src_name}\}\")" + src_cat="$(eval printf "%s" \"\$\{adb_src_cat_${src_name}\}\")" + adb_tmpload="${tmp_load}"."${src_name}" + adb_tmpfile="${tmp_file}"."${src_name}" # basic pre-checks # f_log "debug" "f_main ::: name: ${src_name}, enabled: ${enabled}" - if [ "${enabled}" != "1" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ] + if [ "${enabled}" != "1" ] || [ -f "${src_url}" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ] then f_list remove continue @@ -897,10 +932,10 @@ f_main() # backup mode # - if [ ${adb_backup_mode} -eq 1 ] && [ "${adb_action}" = "start" ] && [ "${src_name}" != "blacklist" ] + if [ "${adb_action}" = "start" ] then f_list restore - if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ] + if [ "${adb_rc}" -eq 0 ] && [ -s "${adb_tmpfile}" ] then continue fi @@ -908,76 +943,47 @@ f_main() # download queue processing # - if [ "${src_name}" = "blacklist" ] - then - if [ -s "${src_url}" ] - then - ( - src_log="$(cat "${src_url}" > "${adb_tmpload}" 2>&1)" - adb_rc=${?} - if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ] - then - awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}" - adb_rc=${?} - if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ] - then - rm -f "${adb_tmpload}" - f_list download - fi - else - src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')" - f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}" - fi - ) & - else - continue - fi - elif [ -n "${src_cat}" ] + if [ -n "${src_cat}" ] then ( - src_arc="${adb_tmpdir}/${src_url##*/}" + src_arc="${adb_tmpdir}"/"${src_url##*/}" src_log="$("${adb_fetchutil}" ${adb_fetchparm} "${src_arc}" "${src_url}" 2>&1)" adb_rc=${?} - if [ ${adb_rc} -eq 0 ] && [ -s "${src_arc}" ] + if [ "${adb_rc}" -eq 0 ] && [ -s "${src_arc}" ] then list="$(tar -tzf "${src_arc}")" - suffix="$(eval printf '%s' \"\${adb_src_suffix_${src_name}:-\"domains\"\}\")" + suffix="$(eval printf "%s" \"\$\{adb_src_suffix_${src_name}:-\"domains\"\}\")" for cat in ${src_cat} do - entry="$(printf '%s' "${list}" | grep -E "[\^/]+${cat}/${suffix}")" + entry="$(printf "%s" "${list}" | grep -E "[\\^/]+${cat}/${suffix}")" if [ -n "${entry}" ] then tar -xOzf "${src_arc}" "${entry}" >> "${adb_tmpload}" adb_rc=${?} - if [ ${adb_rc} -ne 0 ] + if [ "${adb_rc}" -ne 0 ] then break fi fi done else - src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')" + src_log="$(printf "%s" "${src_log}" | awk '{ORS=" ";print $0}')" f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}" fi - if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpload}" ] + if [ "${adb_rc}" -eq 0 ] && [ -s "${adb_tmpload}" ] then rm -f "${src_arc}" awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}" adb_rc=${?} - if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ] + if [ "${adb_rc}" -eq 0 ] && [ -s "${adb_tmpfile}" ] then rm -f "${adb_tmpload}" f_list download - if [ ${adb_backup} -eq 1 ] - then - f_list backup - fi - elif [ ${adb_backup} -eq 1 ] - then + f_list backup + else f_list restore fi - elif [ ${adb_backup} -eq 1 ] - then + else f_list restore fi ) & @@ -989,34 +995,27 @@ f_main() then awk "${src_rset}" "${adb_tmpload}" 2>/dev/null > "${adb_tmpfile}" adb_rc=${?} - if [ ${adb_rc} -eq 0 ] && [ -s "${adb_tmpfile}" ] + if [ "${adb_rc}" -eq 0 ] && [ -s "${adb_tmpfile}" ] then rm -f "${adb_tmpload}" f_list download - if [ ${adb_backup} -eq 1 ] - then - f_list backup - fi - elif [ ${adb_backup} -eq 1 ] - then + f_list backup + else f_list restore fi else - src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')" + src_log="$(printf "%s" "${src_log}" | awk '{ORS=" ";print $0}')" f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${adb_rc}, log: ${src_log:-"-"}" - if [ ${adb_backup} -eq 1 ] - then - f_list restore - fi + f_list restore fi ) & fi - hold=$(( cnt % adb_maxqueue )) - if [ ${hold} -eq 0 ] + hold=$((cnt%adb_maxqueue)) + if [ "${hold}" -eq 0 ] then wait fi - cnt=$(( cnt + 1 )) + cnt=$((cnt+1)) done # list merge @@ -1026,26 +1025,28 @@ f_main() adb_tmpfile="${tmp_file}" f_list merge - # overall sort and conditional dns restart + # overall sort and dns restart # - f_hash - if [ -s "${adb_tmpdir}/${adb_dnsfile}" ] + if [ -s "${adb_tmpdir}"/"${adb_dnsfile}" ] then - f_tld "${adb_tmpdir}/${adb_dnsfile}" + f_tld "${adb_tmpdir}"/"${adb_dnsfile}" f_list final else - > "${adb_dnsdir}/${adb_dnsfile}" - fi - chown "${adb_dnsuser}" "${adb_dnsdir}/${adb_dnsfile}" 2>/dev/null - f_hash - if [ ${?} -eq 1 ] - then - f_dnsup + > "${adb_dnsdir}"/"${adb_dnsfile}" fi + chown "${adb_dnsuser}" "${adb_dnsdir}"/"${adb_dnsfile}" 2>/dev/null + f_dnsup f_jsnup - if [ ${?} -eq 0 ] + if [ "${?}" -eq 0 ] then - f_log "info" "blocklist with overall ${adb_cnt} domains loaded successfully (${adb_sysver})" + if [ "${adb_dnsfilereset}" = "true" ] + then + f_bgserv "start" + > "${adb_dnsdir}"/"${adb_dnsfile}" + f_log "info" "blocklist with overall ${adb_cnt} domains loaded successfully and reset afterwards (${adb_sysver})" + else + f_log "info" "blocklist with overall ${adb_cnt} domains loaded successfully (${adb_sysver})" + fi else f_log "err" "dns backend restart with active blocklist failed" fi @@ -1057,20 +1058,20 @@ f_main() # f_report() { - local bg_pid total blocked percent rep_clients rep_domains rep_blocked index hold ports cnt=0 search="${1}" count="${2}" filter="${3}" print="${4}" + local bg_pid status total blocked percent rep_clients rep_domains rep_blocked index hold ports cnt=0 search="${1}" count="${2}" filter="${3}" print="${4}" - if [ ${adb_report} -eq 1 ] && [ ! -x "${adb_reputil}" ] + if [ "${adb_report}" -eq 1 ] && [ ! -x "${adb_reputil}" ] then f_log "info" "Please install the package 'tcpdump' or 'tcpdump-mini' to use the adblock reporting feature!" - elif [ ${adb_report} -eq 0 ] && [ "${adb_action}" = "report" ] + elif [ "${adb_report}" -eq 0 ] && [ "${adb_action}" = "report" ] then f_log "info" "Please enable the extra option 'adb_report' to use the adblock reporting feature!" fi if [ -x "${adb_reputil}" ] then - bg_pid="$(pgrep -f "^${adb_reputil}.*adb_report\.pcap$" | awk '{ORS=" "; print $1}')" - if [ ${adb_report} -eq 0 ] || ([ -n "${bg_pid}" ] && ([ "${adb_action}" = "stop" ] || [ "${adb_action}" = "restart" ])) + bg_pid="$(pgrep -f "^${adb_reputil}.*adb_report\\.pcap$" | awk '{ORS=" "; print $1}')" + if [ "${adb_report}" -eq 0 ] || { [ -n "${bg_pid}" ] && { [ "${adb_action}" = "stop" ] || [ "${adb_action}" = "restart" ]; } } then if [ -n "${bg_pid}" ] then @@ -1084,7 +1085,7 @@ f_report() fi fi - if [ -x "${adb_reputil}" ] && [ ${adb_report} -eq 1 ] + if [ -x "${adb_reputil}" ] && [ "${adb_report}" -eq 1 ] then if [ -z "${bg_pid}" ] && [ "${adb_action}" != "report" ] && [ "${adb_action}" != "stop" ] then @@ -1097,53 +1098,53 @@ f_report() ports="${ports} or port ${port}" fi done - ("${adb_reputil}" -nn -s0 -l -i ${adb_repiface} ${ports} -C${adb_repchunksize} -W${adb_repchunkcnt} -w "${adb_repdir}/adb_report.pcap" >/dev/null 2>&1 &) - bg_pid="$(pgrep -f "^${adb_reputil}.*adb_report\.pcap$" | awk '{ORS=" "; print $1}')" + ( "${adb_reputil}" -nn -s0 -l -i ${adb_repiface} ${ports} -C${adb_repchunksize} -W${adb_repchunkcnt} -w "${adb_repdir}"/adb_report.pcap >/dev/null 2>&1 & ) + bg_pid="$(pgrep -f "^${adb_reputil}.*adb_report\\.pcap$" | awk '{ORS=" "; print $1}')" fi if [ "${adb_action}" = "report" ] && [ "${filter}" = "false" ] then - > "${adb_repdir}/adb_report.raw" + > "${adb_repdir}"/adb_report.raw for file in "${adb_repdir}"/adb_report.pcap* do ( - "${adb_reputil}" -tttt -r $file 2>/dev/null | \ - awk -v cnt=${cnt} '!/\.lan\. /&&/ A[\? ]+|NXDomain/{a=$1;b=substr($2,0,8);c=$4;sub(/\.[0-9]+$/,"",c); \ - d=cnt $7;e=$(NF-1);sub(/[0-9]\/[0-9]\/[0-9]/,"NX",e);sub(/\.$/,"",e);sub(/([0-9]{1,3}\.){3}[0-9]{1,3}/,"OK",e);printf("%s\t%s\t%s\t%s\t%s\n", a,b,c,d,e)}' >> "${adb_repdir}/adb_report.raw" + "${adb_reputil}" -tttt -r "${file}" 2>/dev/null | \ + awk -v cnt=${cnt} '!/\.lan\. /&&/ A[\? ]+|NXDomain|0\.0\.0\.0/{a=$1;b=substr($2,0,8);c=$4;sub(/\.[0-9]+$/,"",c); \ + d=cnt $7;sub(/\*$/,"",d);e=$(NF-1);sub(/[0-9]\/[0-9]\/[0-9]|0\.0\.0\.0/,"NX",e);sub(/\.$/,"",e);sub(/([0-9]{1,3}\.){3}[0-9]{1,3}/,"OK",e);printf("%s\t%s\t%s\t%s\t%s\n", a,b,c,d,e)}' >> "${adb_repdir}/adb_report.raw" )& - hold=$(( cnt % adb_maxqueue )) - if [ ${hold} -eq 0 ] + hold=$((cnt%adb_maxqueue)) + if [ "${hold}" -eq 0 ] then wait fi - cnt=$(( cnt + 1 )) + cnt=$((cnt+1)) done wait - if [ -s "${adb_repdir}/adb_report.raw" ] + if [ -s "${adb_repdir}"/adb_report.raw ] then awk '{printf("%s\t%s\t%s\t%s\t%s\t%s\n", $4,$5,$1,$2,$3,$4)}' "${adb_repdir}/adb_report.raw" | \ sort -ur | uniq -uf2 | awk '{currA=($6+0);currB=$6;currC=substr($6,length($6),1); \ if(reqA==currB){reqA=0;printf("%s\t%s\n",d,$2)}else if(currC=="+"){reqA=currA;d=$3"\t"$4"\t"$5"\t"$2}}' | sort -ur > "${adb_repdir}/adb_report" fi - if [ -s "${adb_repdir}/adb_report" ] + if [ -s "${adb_repdir}"/adb_report ] then - total="$(wc -l < ${adb_repdir}/adb_report)" - blocked="$(awk '{if($5=="NX")print $4}' ${adb_repdir}/adb_report | wc -l)" - percent="$(awk -v t=${total} -v b=${blocked} 'BEGIN{printf("%.2f %s\n",b/t*100, "%")}')" - rep_clients="$(awk '{print $3}' ${adb_repdir}/adb_report | sort | uniq -c | sort -r | awk '{ORS=" ";if(NR<=10) printf("%s_%s ",$1,$2)}')" - rep_domains="$(awk '{if($5!="NX")print $4}' ${adb_repdir}/adb_report | sort | uniq -c | sort -r | awk '{ORS=" ";if(NR<=10)printf("%s_%s ",$1,$2)}')" - rep_blocked="$(awk '{if($5=="NX")print $4}' ${adb_repdir}/adb_report | sort | uniq -c | sort -r | awk '{ORS=" ";if(NR<=10)printf("%s_%s ",$1,$2)}')" - - > "${adb_repdir}/adb_report.json" - json_load_file "${adb_repdir}/adb_report.json" >/dev/null 2>&1 + total="$(wc -l < "${adb_repdir}"/adb_report)" + blocked="$(awk '{if($5=="NX")print $4}' "${adb_repdir}"/adb_report | wc -l)" + percent="$(awk -v t="${total}" -v b="${blocked}" 'BEGIN{printf("%.2f %s\n",b/t*100, "%")}')" + rep_clients="$(awk '{print $3}' "${adb_repdir}"/adb_report | sort | uniq -c | sort -r | awk '{ORS=" ";if(NR<=10) printf("%s_%s ",$1,$2)}')" + rep_domains="$(awk '{if($5!="NX")print $4}' "${adb_repdir}"/adb_report | sort | uniq -c | sort -r | awk '{ORS=" ";if(NR<=10)printf("%s_%s ",$1,$2)}')" + rep_blocked="$(awk '{if($5=="NX")print $4}' "${adb_repdir}"/adb_report | sort | uniq -c | sort -r | awk '{ORS=" ";if(NR<=10)printf("%s_%s ",$1,$2)}')" + + > "${adb_repdir}"/adb_report.json + json_load_file "${adb_repdir}"/adb_report.json >/dev/null 2>&1 json_init json_add_object "data" - json_add_string "start_date" "$(awk 'END{printf("%s",$1)}' ${adb_repdir}/adb_report)" - json_add_string "start_time" "$(awk 'END{printf("%s",$2)}' ${adb_repdir}/adb_report)" - json_add_string "end_date" "$(awk 'NR==1{printf("%s",$1)}' ${adb_repdir}/adb_report)" - json_add_string "end_time" "$(awk 'NR==1{printf("%s",$2)}' ${adb_repdir}/adb_report)" + json_add_string "start_date" "$(awk 'END{printf("%s",$1)}' "${adb_repdir}"/adb_report)" + json_add_string "start_time" "$(awk 'END{printf("%s",$2)}' "${adb_repdir}"/adb_report)" + json_add_string "end_date" "$(awk 'NR==1{printf("%s",$1)}' "${adb_repdir}"/adb_report)" + json_add_string "end_time" "$(awk 'NR==1{printf("%s",$2)}' "${adb_repdir}"/adb_report)" json_add_string "total" "${total}" json_add_string "blocked" "${blocked}" json_add_string "percent" "${percent}" @@ -1175,29 +1176,29 @@ f_report() json_close_object done json_close_object - json_dump > "${adb_repdir}/adb_report.json" + json_dump > "${adb_repdir}"/adb_report.json fi - rm -f "${adb_repdir}/adb_report.raw" + rm -f "${adb_repdir}"/adb_report.raw fi - if [ -s "${adb_repdir}/adb_report" ] + if [ -s "${adb_repdir}"/adb_report ] then search="${search//./\\.}" search="${search//[+*~%\$&\"\' ]/}" - > "${adb_repdir}/adb_report.final" - awk "BEGIN{i=0}/(${search})/{i++;if(i<=${count}){printf \"%s\t%s\t%s\t%s\t%s\n\",\$1,\$2,\$3,\$4,\$5}}" "${adb_repdir}/adb_report" > "${adb_repdir}/adb_report.final" - if [ ! -s "${adb_repdir}/adb_report.final" ] + > "${adb_repdir}"/adb_report.final + awk "BEGIN{i=0}/(${search})/{i++;if(i<=${count}){printf \"%s\\t%s\\t%s\\t%s\\t%s\\n\",\$1,\$2,\$3,\$4,\$5}}" "${adb_repdir}"/adb_report > "${adb_repdir}"/adb_report.final + if [ ! -s "${adb_repdir}"/adb_report.final ] then - printf "%s\t%s\t%s\t%s\t%s\n" "-" "-" "-" "-" "-" > "${adb_repdir}/adb_report.final" + printf "%s\\t%s\\t%s\\t%s\\t%s\\n" "-" "-" "-" "-" "-" > "${adb_repdir}"/adb_report.final fi fi if [ "${print}" = "true" ] then - if [ -s "${adb_repdir}/adb_report.json" ] + if [ -s "${adb_repdir}"/adb_report.json ] then - printf "%s\n%s\n%s\n" ":::" "::: Adblock DNS-Query Report" ":::" - json_load_file "${adb_repdir}/adb_report.json" + printf "%s\\n%s\\n%s\\n" ":::" "::: Adblock DNS-Query Report" ":::" + json_load_file "${adb_repdir}"/adb_report.json json_select "data" json_get_keys keylist for key in ${keylist} @@ -1205,55 +1206,55 @@ f_report() json_get_var value "${key}" eval "${key}=\"${value}\"" done - printf " + %s\n + %s\n" "Start ::: ${start_date}, ${start_time}" "End ::: ${end_date}, ${end_time}" - printf " + %s\n + %s %s\n" "Total ::: ${total}" "Blocked ::: ${blocked}" "(${percent})" + printf " + %s\\n + %s\\n" "Start ::: ${start_date}, ${start_time}" "End ::: ${end_date}, ${end_time}" + printf " + %s\\n + %s %s\\n" "Total ::: ${total}" "Blocked ::: ${blocked}" "(${percent})" json_select ".." - if json_get_type Status "top_clients" && [ "${Status}" = "array" ] + if json_get_type status "top_clients" && [ "${status}" = "array" ] then - printf "%s\n%s\n%s\n" ":::" "::: Top 10 Clients" ":::" + printf "%s\\n%s\\n%s\\n" ":::" "::: Top 10 Clients" ":::" json_select "top_clients" index=1 - while json_get_type Status ${index} && [ "${Status}" = "object" ] + while json_get_type status "${index}" && [ "${status}" = "object" ] do - json_get_values client ${index} - printf " + %-9s::: %s\n" ${client} - index=$((index + 1)) + json_get_values client "${index}" + printf " + %-9s::: %s\\n" ${client} + index=$((index+1)) done fi json_select ".." - if json_get_type Status "top_domains" && [ "${Status}" = "array" ] + if json_get_type status "top_domains" && [ "${status}" = "array" ] then - printf "%s\n%s\n%s\n" ":::" "::: Top 10 Domains" ":::" + printf "%s\\n%s\\n%s\\n" ":::" "::: Top 10 Domains" ":::" json_select "top_domains" index=1 - while json_get_type Status ${index} && [ "${Status}" = "object" ] + while json_get_type status "${index}" && [ "${status}" = "object" ] do - json_get_values domain ${index} - printf " + %-9s::: %s\n" ${domain} - index=$((index + 1)) + json_get_values domain "${index}" + printf " + %-9s::: %s\\n" ${domain} + index=$((index+1)) done fi json_select ".." - if json_get_type Status "top_blocked" && [ "${Status}" = "array" ] + if json_get_type status "top_blocked" && [ "${status}" = "array" ] then - printf "%s\n%s\n%s\n" ":::" "::: Top 10 Blocked Domains" ":::" + printf "%s\\n%s\\n%s\\n" ":::" "::: Top 10 Blocked Domains" ":::" json_select "top_blocked" index=1 - while json_get_type Status ${index} && [ "${Status}" = "object" ] + while json_get_type status "${index}" && [ "${status}" = "object" ] do - json_get_values blocked ${index} - printf " + %-9s::: %s\n" ${blocked} - index=$((index + 1)) + json_get_values blocked "${index}" + printf " + %-9s::: %s\\n" ${blocked} + index=$((index+1)) done fi - if [ -s "${adb_repdir}/adb_report.final" ] + if [ -s "${adb_repdir}"/adb_report.final ] then - printf "%s\n%s\n%s\n" ":::" "::: Latest DNS Queries" ":::" - printf "%-15s%-15s%-45s%-50s%s\n" "Date" "Time" "Client" "Domain" "Answer" - awk '{printf "%-15s%-15s%-45s%-50s%s\n",$1,$2,$3,$4,$5}' "${adb_repdir}/adb_report.final" + printf "%s\\n%s\\n%s\\n" ":::" "::: Latest DNS Queries" ":::" + printf "%-15s%-15s%-45s%-50s%s\\n" "Date" "Time" "Client" "Domain" "Answer" + awk '{printf "%-15s%-15s%-45s%-50s%s\n",$1,$2,$3,$4,$5}' "${adb_repdir}"/adb_report.final fi else - printf "%s\n%s\n%s\n" ":::" "::: no reporting data available yet" ":::" + printf "%s\\n%s\\n%s\\n" ":::" "::: no reporting data available yet" ":::" fi fi fi @@ -1272,16 +1273,18 @@ fi # handle different adblock actions # -f_envload +f_load case "${adb_action}" in stop) + f_bgserv "stop" f_report "+" "50" "false" "false" f_rmdns ;; restart) + f_bgserv "stop" f_report "+" "50" "false" "false" f_rmdns - f_envcheck + f_env f_main ;; suspend) @@ -1297,8 +1300,9 @@ case "${adb_action}" in f_query "${2}" ;; start|reload) + f_bgserv "stop" f_report "+" "50" "false" "false" - f_envcheck + f_env f_main ;; esac -- 2.30.2