mirror of
https://github.com/openwrt/packages.git
synced 2026-04-15 19:02:09 +00:00
adblock: update 4.5.0-2
* rework DNS reporting: more reliable, more information (request type), better performance * fixed minor issues * readme update * LuCI: added new DNS page (incl. Allowed/Blocked canvas) Signed-off-by: Dirk Brenken <dev@brenken.org>
This commit is contained in:
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=adblock
|
||||
PKG_VERSION:=4.5.0
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
config="adblock"
|
||||
old_options="adb_sources adb_forcedns adb_fetchutil adb_hag_sources adb_hst_sources adb_stb_sources adb_utc_sources \
|
||||
adb_maxqueue adb_backup adb_dnsfilereset adb_tmpbase adb_mailcnt adb_safesearchmod adb_srcfile adb_srcarc adb_nice \
|
||||
adb_hag_feed adb_jaildir adb_dnsdenyip adb_dnsallowip adb_zonelist adb_portlist adb_dnsforce"
|
||||
adb_hag_feed adb_jaildir adb_dnsdenyip adb_dnsallowip adb_zonelist adb_portlist adb_dnsforce adb_replisten"
|
||||
|
||||
for option in ${old_options}; do
|
||||
inplace="0"
|
||||
@@ -44,9 +44,6 @@ for option in ${old_options}; do
|
||||
uci -q add_list ${config}.global.adb_utc_feed="${value}"
|
||||
fi
|
||||
;;
|
||||
"adb_forcedns")
|
||||
uci -q set ${config}.global.adb_dnsforce="${value}"
|
||||
;;
|
||||
"adb_fetchutil")
|
||||
uci -q set ${config}.global.adb_fetchcmd="${value}"
|
||||
;;
|
||||
@@ -63,14 +60,23 @@ for option in ${old_options}; do
|
||||
uci -q add_list ${config}.global.adb_hag_feed="wildcard/${value}"
|
||||
fi
|
||||
;;
|
||||
"adb_dnsforce")
|
||||
"adb_forcedns" | "adb_dnsforce")
|
||||
uci -q set ${config}.global.adb_nftforce="${value}"
|
||||
;;
|
||||
"adb_zonelist")
|
||||
uci -q set ${config}.global.adb_nftdevforce="${value}"
|
||||
if ! uci -q get ${config}.global.adb_nftdevforce | grep -q "${value}"; then
|
||||
uci -q add_list ${config}.global.adb_nftdevforce="${value}"
|
||||
fi
|
||||
;;
|
||||
"adb_portlist")
|
||||
uci -q set ${config}.global.adb_nftportforce="${value}"
|
||||
if ! uci -q get ${config}.global.adb_nftportforce | grep -q "${value}"; then
|
||||
uci -q add_list ${config}.global.adb_nftportforce="${value}"
|
||||
fi
|
||||
;;
|
||||
"adb_replisten")
|
||||
if ! uci -q get ${config}.global.adb_repport | grep -q "${value}"; then
|
||||
uci -q add_list ${config}.global.adb_repport="${value}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -66,6 +66,7 @@ A lot of people already use adblocker plugins within their desktop browsers, but
|
||||
* Overall duplicate removal in generated blocklist file 'adb_list.overall'
|
||||
* Additional local allowlist for manual overrides, located in '/etc/adblock/adblock.allowlist' (only exact matches).
|
||||
* Additional local blocklist for manual overrides, located in '/etc/adblock/adblock.blocklist'
|
||||
* Implements Firewall‑Based DNS Control to force DNS interfaces/ports and to redirect to external unfiltered/filtered DNS server
|
||||
* Connection 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', 'enable', 'disable', 'running', 'status', 'suspend', 'resume', 'query', 'report')
|
||||
@@ -75,6 +76,7 @@ A lot of people already use adblocker plugins within their desktop browsers, but
|
||||
* Provides a detailed DNS Query Report with DNS related information about client requests, top (blocked) domains and more
|
||||
* Provides a powerful query function to quickly find blocked (sub-)domains, e.g. to allow certain domains
|
||||
* Contains an option to route DNS queries to the local resolver via corresponding firewall rules
|
||||
* Implements a jail mode - only domains on the allowlist are permitted, all other DNS requests are rejected
|
||||
* Automatic blocklist backup & restore, these backups will be used in case of download errors and during startup
|
||||
* Send notification E-Mails, see example configuration below
|
||||
* Add new adblock feeds on your own with the 'Custom Feed Editor' in LuCI or via CLI, see example below
|
||||
@@ -155,7 +157,7 @@ Available commands:
|
||||
| adb_map | 0, disabled | enable a GeoIP Map with blocked domains |
|
||||
| adb_reportdir | /tmp/adblock-report | path for DNS related report files |
|
||||
| adb_repiface | -, auto-detected | name of the reporting interface or 'any' used by tcpdump |
|
||||
| adb_replisten | 53 | space separated list of reporting port(s) used by tcpdump |
|
||||
| adb_repport | 53 | list of reporting port(s) used by tcpdump |
|
||||
| adb_repchunkcnt | 5 | report chunk count used by tcpdump |
|
||||
| adb_repchunksize | 1 | report chunk size used by tcpdump in MB |
|
||||
| adb_represolve | 0, disabled | resolve reporting IP addresses using reverse DNS (PTR) lookups |
|
||||
@@ -178,7 +180,7 @@ Available commands:
|
||||
| adb_nftdevallow | -, not set | entire interfaces or VLANs will be routed to the unfiltered DNS server |
|
||||
| adb_allowdnsv4 | -, not set | IPv4 DNS resolver applied to MACs and interfaces using the unfiltered DNS policy |
|
||||
| adb_allowdnsv6 | -, not set | IPv6 DNS resolver applied to MACs and interfaces using the unfiltered DNS policy |
|
||||
| adb_nftblock | 0, disabled | routes MACs or interfaces to an filtered external DNS resolver, bypassing local adblock |
|
||||
| adb_nftblock | 0, disabled | routes MACs or interfaces to a filtered external DNS resolver, bypassing local adblock |
|
||||
| adb_nftmacblock | -, not set | listed MAC addresses will always use the configured filtered DNS server |
|
||||
| adb_nftdevblock | -, not set | entire interfaces or VLANs will be routed to the filtered DNS server |
|
||||
| adb_blockdnsv4 | -, not set | IPv4 DNS resolver applied to MACs and interfaces using the filtered DNS policy |
|
||||
@@ -239,11 +241,12 @@ To get the status in the CLI, just call _/etc/init.d/adblock status_ or _/etc/in
|
||||
## Best practise and tweaks
|
||||
|
||||
**Recommendation for low memory systems**
|
||||
Adblock does use RAM by default and never writes to the flash space of the router. To reduce the memory pressure on low memory systems (i.e. those with 128-256MB RAM), you should optimize your configuration with the following options:
|
||||
adblock uses RAM by design and avoids writing to flash. On devices with 128–256 MB RAM, you can reduce memory pressure with the following optimizations:
|
||||
|
||||
* point 'adb_basedir', 'adb_backupdir' and 'adb_reportdir' to an external usb drive or ssd
|
||||
* set 'adb_cores' to '1' (only useful on a multicore system) to force sequential feed processing
|
||||
* enable the 'adb_dnsshift' option to shift the blocklist to the backup directory and only set a soft link to this file in memory
|
||||
* use external storage: point 'adb_basedir', 'adb_backupdir' and 'adb_reportdir' to an USB drive or SSD
|
||||
* limit CPU processing to one core: set 'adb_cores' to '1' to reduce peak memory usage during feed processing
|
||||
* enable blocklist shifting: activate 'adb_dnsshift' to store the blocklist in the backup directory and expose it via a symlink in RAM.
|
||||
* Firewall DNS redirection: use nftables based DNS routing to external filtered DNS serves and only use a minimal set of local blocklists
|
||||
|
||||
**Sensible choice of blocklists**
|
||||
The following feeds are just my personal recommendation as an initial setup:
|
||||
@@ -287,7 +290,7 @@ force DNS ensures that all DNS traffic on your network by specific devices or en
|
||||
* also prevents DNS bypassing by clients with hardcoded DNS settings on other ports, e.g. on port 853
|
||||
This mode guarantees that adblock’s filtering pipeline is always applied.
|
||||
|
||||
adblock's firewall rules are based on nftables in a separate isolated nftables table (inet adblock) and chains (prerouting), with MAC addresses stored in an nftables set. The configuration is carried out centrally in LuCI on the ‘Firewall Settings’ tab in adblock.
|
||||
adblock's firewall rules are based on nftables in a separate isolated nftables table (inet adblock) and chains (prerouting), with MAC addresses stored in a nftables set. The configuration is carried out centrally in LuCI on the ‘Firewall Settings’ tab in adblock.
|
||||
|
||||
**Jail mode (allowlist-only):**
|
||||
Enforces a strict allowlist‑only DNS policy in which only domains listed in the allowlist file are resolved, while every other query is rejected. This mode is intended for highly restrictive environments and depends on a carefully maintained allowlist, typically managed manually.
|
||||
|
||||
@@ -59,7 +59,7 @@ adb_etagparm=""
|
||||
adb_geoparm=""
|
||||
adb_geourl="http://ip-api.com/json"
|
||||
adb_repiface=""
|
||||
adb_replisten="53"
|
||||
adb_repport="53"
|
||||
adb_repchunkcnt="5"
|
||||
adb_repchunksize="1"
|
||||
adb_represolve="0"
|
||||
@@ -92,7 +92,7 @@ f_cmd() {
|
||||
# load adblock environment
|
||||
#
|
||||
f_load() {
|
||||
local bg_pid iface port ports cpu core
|
||||
local bg_pid iface port filter tcpdump_filter cpu core
|
||||
|
||||
adb_packages="$("${adb_ubuscmd}" -S call rpc-sys packagelist '{ "all": true }' 2>/dev/null)"
|
||||
adb_bver="$(printf "%s" "${adb_packages}" | "${adb_jsoncmd}" -ql1 -e '@.packages.adblock')"
|
||||
@@ -127,26 +127,21 @@ f_load() {
|
||||
fi
|
||||
|
||||
if [ "${adb_report}" = "1" ] && [ ! -x "${adb_dumpcmd}" ]; then
|
||||
f_log "info" "Please install the package 'tcpdump' or 'tcpdump-mini' to use the reporting feature"
|
||||
f_log "info" "please install the package 'tcpdump' or 'tcpdump-mini' to use the reporting feature"
|
||||
elif [ -x "${adb_dumpcmd}" ]; then
|
||||
bg_pid="$("${adb_pgrepcmd}" -f "^${adb_dumpcmd}.*adb_report\\.pcap$" | "${adb_awkcmd}" '{ORS=" "; print $1}')"
|
||||
if [ "${adb_report}" = "0" ] || { [ -n "${bg_pid}" ] && [ "${adb_action}" = "stop" ]; }; then
|
||||
if [ -n "${bg_pid}" ]; then
|
||||
kill -HUP "${bg_pid}" 2>/dev/null
|
||||
bg_pid="$("${adb_pgrepcmd}" -nf "${adb_reportdir}/adb_report.pcap")"
|
||||
if [ "${adb_report}" = "0" ] || { [ -n "${bg_pid}" ] && { [ "${adb_action}" = "stop" ] || [ "${adb_action}" = "restart" ]; }; }; then
|
||||
if kill -HUP "${bg_pid}" 2>/dev/null; then
|
||||
while kill -0 "${bg_pid}" 2>/dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
unset bg_pid
|
||||
fi
|
||||
bg_pid="$("${adb_pgrepcmd}" -nf "${adb_reportdir}/adb_report.pcap")"
|
||||
rm -f "${adb_reportdir}"/adb_report.pcap*
|
||||
fi
|
||||
|
||||
if [ "${adb_report}" = "1" ] && [ -z "${bg_pid}" ] && [ "${adb_action}" != "report" ] && [ "${adb_action}" != "stop" ]; then
|
||||
[ ! -d "${adb_reportdir}" ] && mkdir -p "${adb_reportdir}"
|
||||
|
||||
for port in ${adb_replisten}; do
|
||||
[ -z "${ports}" ] && ports="port ${port}" || ports="${ports} or port ${port}"
|
||||
done
|
||||
if [ -z "${adb_repiface}" ]; then
|
||||
network_get_device iface "lan"
|
||||
[ -z "${iface}" ] && network_get_physdev iface "lan"
|
||||
@@ -156,12 +151,22 @@ f_load() {
|
||||
f_uci "adblock"
|
||||
fi
|
||||
fi
|
||||
|
||||
for port in ${adb_repport}; do
|
||||
[ -n "${filter}" ] && filter="${filter} or "
|
||||
filter="${filter}(udp port ${port}) or (tcp port ${port})"
|
||||
done
|
||||
tcpdump_filter="(${filter}) and greater 28"
|
||||
if [ -n "${adb_repiface}" ] && [ -d "${adb_reportdir}" ]; then
|
||||
("${adb_dumpcmd}" --immediate-mode -nn -p -s0 -l -i ${adb_repiface} ${ports} -C${adb_repchunksize} -W${adb_repchunkcnt} -w "${adb_reportdir}/adb_report.pcap" >/dev/null 2>&1 &)
|
||||
bg_pid="$("${adb_pgrepcmd}" -f "^${adb_dumpcmd}.*adb_report\\.pcap$" | "${adb_awkcmd}" '{ORS=" "; print $1}')"
|
||||
(
|
||||
"${adb_dumpcmd}" --immediate-mode -nn -p -s0 -i "${adb_repiface}" \
|
||||
"${tcpdump_filter}" \
|
||||
-C "${adb_repchunksize}" -W "${adb_repchunkcnt}" \
|
||||
-w "${adb_reportdir}/adb_report.pcap" >/dev/null 2>&1 &
|
||||
)
|
||||
bg_pid="$("${adb_pgrepcmd}" -nf "${adb_reportdir}/adb_report.pcap")"
|
||||
f_log "info" "tcpdump backgound process started (interface: '${adb_repiface}', port: ${adb_repport}, pid: ${bg_pid})"
|
||||
else
|
||||
f_log "info" "Please set the name of the reporting network device 'adb_repiface' manually"
|
||||
f_log "info" "please set the name of the reporting network device 'adb_repiface' manually"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -539,17 +544,12 @@ f_uci() {
|
||||
|
||||
if [ -n "$(uci -q changes "${config}")" ]; then
|
||||
uci_commit "${config}"
|
||||
case "${config}" in
|
||||
"firewall")
|
||||
"/etc/init.d/firewall" reload >/dev/null 2>&1
|
||||
;;
|
||||
"resolver")
|
||||
printf "%b" "${adb_dnsheader}" >"${adb_finaldir}/${adb_dnsfile}"
|
||||
adb_cnt="0"
|
||||
f_jsnup "processing"
|
||||
"/etc/init.d/${adb_dns}" reload >/dev/null 2>&1
|
||||
;;
|
||||
esac
|
||||
if [ "${config}" = "resolver" ]; then
|
||||
printf "%b" "${adb_dnsheader}" >"${adb_finaldir}/${adb_dnsfile}"
|
||||
adb_cnt="0"
|
||||
f_jsnup "processing"
|
||||
"/etc/init.d/${adb_dns}" reload >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1520,55 +1520,99 @@ f_report() {
|
||||
report_srt="${adb_reportdir}/adb_report.srt"
|
||||
report_jsn="${adb_reportdir}/adb_report.jsn"
|
||||
report_txt="${adb_reportdir}/adb_mailreport.txt"
|
||||
top_tmpclients="${adb_reportdir}/top_clients.tmp"
|
||||
top_tmpdomains="${adb_reportdir}/top_domains.tmp"
|
||||
top_tmpblocked="${adb_reportdir}/top_blocked.tmp"
|
||||
map_jsn="${adb_reportdir}/adb_map.jsn"
|
||||
|
||||
# build json file
|
||||
|
||||
# build report
|
||||
#
|
||||
if [ "${action}" != "json" ]; then
|
||||
: >"${report_raw}" >"${report_srt}" >"${report_txt}" >"${report_jsn}"
|
||||
: >"${top_tmpclients}" >"${top_tmpdomains}" >"${top_tmpblocked}"
|
||||
[ "${adb_represolve}" = "1" ] && resolve=""
|
||||
for file in "${adb_reportdir}/adb_report.pcap"*; do
|
||||
(
|
||||
if [ "${adb_repiface}" = "any" ]; then
|
||||
"${adb_dumpcmd}" "${resolve}" --immediate-mode -T domain -tttt -r "${file}" 2>/dev/null |
|
||||
"${adb_awkcmd}" -v cnt="${cnt}" '!/\.lan\. |PTR\? | SOA\? | Flags /&&/ A[A]*\? |NXDomain|0\.0\.0\.0|[0-9]\/[0-9]\/[0-9]/{sub(/\.[0-9]+$/,"",$6);
|
||||
type=substr($(NF-1),length($(NF-1)));
|
||||
if(type=="."&&$(NF-2)!="CNAME")
|
||||
{domain=substr($(NF-1),1,length($(NF-1))-1);type="RQ"}
|
||||
else
|
||||
{if($(NF-2)~/NXDomain/||$(NF-1)=="0.0.0.0"){type="NX"}else{type="OK"};domain=""};
|
||||
if(int($9)>0)
|
||||
printf "%08d\t%s\t%s\t%s\t%-25s\t%s\n",$9,type,$1,substr($2,1,8),$6,domain}' >>"${report_raw}"
|
||||
else
|
||||
"${adb_dumpcmd}" "${resolve}" --immediate-mode -T domain -tttt -r "${file}" 2>/dev/null |
|
||||
"${adb_awkcmd}" -v cnt="${cnt}" '!/\.lan\. |PTR\? | SOA\? | Flags /&&/ A[A]*\? |NXDomain|0\.0\.0\.0|[0-9]\/[0-9]\/[0-9]/{sub(/\.[0-9]+$/,"",$4);
|
||||
type=substr($(NF-1),length($(NF-1)));
|
||||
if(type=="."&&$(NF-2)!="CNAME")
|
||||
{domain=substr($(NF-1),1,length($(NF-1))-1);type="RQ"}
|
||||
else
|
||||
{if($(NF-2)~/NXDomain/||$(NF-1)=="0.0.0.0"){type="NX"}else{type="OK"};domain=""};
|
||||
if(int($7)>0)
|
||||
printf "%08d\t%s\t%s\t%s\t%-25s\t%s\n",$7,type,$1,substr($2,1,8),$4,domain}' >>"${report_raw}"
|
||||
fi
|
||||
"${adb_dumpcmd}" ${resolve} --immediate-mode -tttt -T domain -r "${file}" 2>/dev/null |
|
||||
"${adb_awkcmd}" '
|
||||
BEGIN {
|
||||
pending = 0
|
||||
}
|
||||
# ignore Reverse DNS
|
||||
/\.in-addr\.arpa/ || /\.ip6\.arpa/ { next }
|
||||
# domain request parser
|
||||
/\+[[:space:]]+(A\?|AAAA\?)/ {
|
||||
# drop unresolved previous query
|
||||
if (pending)
|
||||
pending = 0
|
||||
date = $1
|
||||
split($2, t, ":")
|
||||
time = t[1] ":" t[2] ":" substr(t[3],1,2)
|
||||
client = $4
|
||||
sub(/\.[0-9]+$/, "", client)
|
||||
domain = $(NF-1)
|
||||
sub(/[,\.]+$/, "", domain)
|
||||
if (domain ~ /\.lan$/) next
|
||||
qtype = $(NF-2)
|
||||
sub(/\?$/, "", qtype)
|
||||
last_date = date
|
||||
last_time = time
|
||||
last_client = client
|
||||
last_domain = domain
|
||||
last_qtype = qtype
|
||||
pending = 1
|
||||
next
|
||||
}
|
||||
# ok answer
|
||||
/[0-9]+[[:space:]]+[0-9]+\/[0-9]+\/[0-9]+[[:space:]]+(A|AAAA|CNAME)[[:space:]]/ {
|
||||
if (pending) {
|
||||
printf "%s\t%s\t%s\t%s\t%s\tOK\n",
|
||||
last_date, last_time, last_client, last_qtype, last_domain
|
||||
pending = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
# nxdomain answer
|
||||
/ NXDomain/ {
|
||||
if (pending) {
|
||||
printf "%s\t%s\t%s\t%s\t%s\tNX\n",
|
||||
last_date, last_time, last_client, last_qtype, last_domain
|
||||
pending = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
# servfail answer
|
||||
/ ServFail/ {
|
||||
if (pending) {
|
||||
printf "%s\t%s\t%s\t%s\t%s\tSF\n",
|
||||
last_date, last_time, last_client, last_qtype, last_domain
|
||||
pending = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
END {
|
||||
# no fallback
|
||||
}
|
||||
' >> "${report_raw}"
|
||||
) &
|
||||
[ "${cnt}" -gt "${adb_cores}" ] && wait -n
|
||||
cnt="$((cnt + 1))"
|
||||
done
|
||||
wait
|
||||
if [ -s "${report_raw}" ]; then
|
||||
"${adb_sortcmd}" ${adb_srtopts} -k3,3 -k4,4 -k1,1 -k2,2 -u -r "${report_raw}" |
|
||||
"${adb_awkcmd}" '{currA=($1+0);currB=$1;currC=$2;if(reqA==currB){reqA=0;printf "%-90s\t%s\n",d,$2}else if(currC=="RQ"){reqA=currA;d=$3"\t"$4"\t"$5"\t"$6}}' |
|
||||
"${adb_grepcmd}" -v "RQ" | "${adb_sortcmd}" ${adb_srtopts} -u -r >"${report_srt}"
|
||||
: >"${report_raw}"
|
||||
"${adb_sortcmd}" ${adb_srtopts} -ru "${report_raw}" > "${report_srt}"
|
||||
rm -f "${report_raw}"
|
||||
fi
|
||||
|
||||
# build json
|
||||
#
|
||||
if [ -s "${report_srt}" ]; then
|
||||
start="$("${adb_awkcmd}" 'END{printf "%s_%s",$1,$2}' "${report_srt}")"
|
||||
end="$("${adb_awkcmd}" 'NR==1{printf "%s_%s",$1,$2}' "${report_srt}")"
|
||||
total="$(f_count tld "${report_srt}" "var")"
|
||||
blocked="$("${adb_awkcmd}" '{if($5=="NX")cnt++}END{printf "%s",cnt}' "${report_srt}")"
|
||||
percent="$("${adb_awkcmd}" -v t="${total}" -v b="${blocked}" 'BEGIN{printf "%.2f%s",b/t*100,"%"}')"
|
||||
: >"${report_jsn}"
|
||||
blocked="$("${adb_awkcmd}" '{if($6=="NX")cnt++}END{printf "%s",cnt}' "${report_srt}")"
|
||||
percent="$("${adb_awkcmd}" -v t="${total}" -v b="${blocked}" 'BEGIN{ if(t>0) printf "%.2f%s",b/t*100,"%"; else printf "0.00%%"}')"
|
||||
{
|
||||
printf "%s\n" "{ "
|
||||
printf "\t%s\n" "\"start_date\": \"${start%_*}\", "
|
||||
@@ -1578,33 +1622,137 @@ f_report() {
|
||||
printf "\t%s\n" "\"total\": \"${total}\", "
|
||||
printf "\t%s\n" "\"blocked\": \"${blocked}\", "
|
||||
printf "\t%s\n" "\"percent\": \"${percent}\", "
|
||||
} >>"${report_jsn}"
|
||||
} >"${report_jsn}"
|
||||
|
||||
# build top list counters
|
||||
#
|
||||
"${adb_awkcmd}" '
|
||||
{
|
||||
client = $3
|
||||
qtype = $4
|
||||
domain = $5
|
||||
rc = $6
|
||||
# normalize domain
|
||||
gsub(/[\.]+$/, "", domain)
|
||||
domain = tolower(domain)
|
||||
# total client counter
|
||||
clients[client]++
|
||||
# remember OK per domain
|
||||
if (rc == "OK") {
|
||||
ok_domain[domain] = 1
|
||||
ok_rr[domain SUBSEP qtype] = 1
|
||||
}
|
||||
# remember NX per domain
|
||||
if (rc == "NX") {
|
||||
nx_domain[domain]++
|
||||
nx_rr[domain SUBSEP qtype]++
|
||||
}
|
||||
# total queries per domain
|
||||
all_domain[domain]++
|
||||
}
|
||||
END {
|
||||
# top clients
|
||||
for (c in clients)
|
||||
printf "%d %s\n", clients[c], c > "'"${top_tmpclients}"'"
|
||||
# domains & blocked domains
|
||||
for (d in all_domain) {
|
||||
if (ok_domain[d]) {
|
||||
printf "%d %s\n", all_domain[d], d > "'"${top_tmpdomains}"'"
|
||||
continue
|
||||
}
|
||||
if (nx_domain[d]) {
|
||||
printf "%d %s\n", nx_domain[d], d > "'"${top_tmpblocked}"'"
|
||||
}
|
||||
}
|
||||
}' "${report_srt}"
|
||||
|
||||
# build json top lists
|
||||
#
|
||||
top_list="top_clients top_domains top_blocked"
|
||||
for top in ${top_list}; do
|
||||
printf "\t%s" "\"${top}\": [ " >>"${report_jsn}"
|
||||
printf "\t\"%s\": [ " "${top}" >>"${report_jsn}"
|
||||
case "${top}" in
|
||||
"top_clients")
|
||||
"${adb_awkcmd}" '{print $3}' "${report_srt}" | "${adb_sortcmd}" ${adb_srtopts} | uniq -c |
|
||||
"${adb_sortcmd}" ${adb_srtopts} -nr |
|
||||
"${adb_awkcmd}" "{ORS=\" \";if(NR==1)printf \"\n\t\t{\n\t\t\t\\\"count\\\": \\\"%s\\\",\n\t\t\t\\\"address\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2; else if(NR<=${top_count})printf \",\n\t\t{\n\t\t\t\\\"count\\\": \\\"%s\\\",\n\t\t\t\\\"address\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2}" >>"${report_jsn}"
|
||||
;;
|
||||
"top_domains")
|
||||
"${adb_awkcmd}" '{if($5!="NX")print $4}' "${report_srt}" | "${adb_sortcmd}" ${adb_srtopts} | uniq -c |
|
||||
"${adb_sortcmd}" ${adb_srtopts} -nr |
|
||||
"${adb_awkcmd}" "{ORS=\" \";if(NR==1)printf \"\n\t\t{\n\t\t\t\\\"count\\\": \\\"%s\\\",\n\t\t\t\\\"address\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2; else if(NR<=${top_count})printf \",\n\t\t{\n\t\t\t\\\"count\\\": \\\"%s\\\",\n\t\t\t\\\"address\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2}" >>"${report_jsn}"
|
||||
;;
|
||||
"top_blocked")
|
||||
"${adb_awkcmd}" '{if($5=="NX")print $4}' "${report_srt}" |
|
||||
"${adb_sortcmd}" ${adb_srtopts} | uniq -c | "${adb_sortcmd}" ${adb_srtopts} -nr |
|
||||
"${adb_awkcmd}" "{ORS=\" \";if(NR==1)printf \"\n\t\t{\n\t\t\t\\\"count\\\": \\\"%s\\\",\n\t\t\t\\\"address\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2; else if(NR<=${top_count})printf \",\n\t\t{\n\t\t\t\\\"count\\\": \\\"%s\\\",\n\t\t\t\\\"address\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2}" >>"${report_jsn}"
|
||||
;;
|
||||
top_clients)
|
||||
"${adb_sortcmd}" ${adb_srtopts} -nr "${top_tmpclients}" |
|
||||
"${adb_awkcmd}" -v top_count="${top_count}" '
|
||||
BEGIN { ORS=""; OFS="" }
|
||||
NR==1 {
|
||||
printf "\n\t\t{\n\t\t\t\"count\": \"%s\",\n\t\t\t\"address\": \"%s\"\n\t\t}", $1, $2
|
||||
}
|
||||
NR>1 && NR<=top_count {
|
||||
printf ",\n\t\t{\n\t\t\t\"count\": \"%s\",\n\t\t\t\"address\": \"%s\"\n\t\t}", $1, $2
|
||||
}
|
||||
' >>"${report_jsn}"
|
||||
;;
|
||||
top_domains)
|
||||
"${adb_sortcmd}" ${adb_srtopts} -nr "${top_tmpdomains}" |
|
||||
"${adb_awkcmd}" -v top_count="${top_count}" '
|
||||
BEGIN { ORS=""; OFS="" }
|
||||
NR==1 {
|
||||
printf "\n\t\t{\n\t\t\t\"count\": \"%s\",\n\t\t\t\"address\": \"%s\"\n\t\t}", $1, $2
|
||||
}
|
||||
NR>1 && NR<=top_count {
|
||||
printf ",\n\t\t{\n\t\t\t\"count\": \"%s\",\n\t\t\t\"address\": \"%s\"\n\t\t}", $1, $2
|
||||
}
|
||||
' >>"${report_jsn}"
|
||||
;;
|
||||
top_blocked)
|
||||
"${adb_sortcmd}" ${adb_srtopts} -nr "${top_tmpblocked}" |
|
||||
"${adb_awkcmd}" -v top_count="${top_count}" '
|
||||
BEGIN { ORS=""; OFS="" }
|
||||
NR==1 {
|
||||
printf "\n\t\t{\n\t\t\t\"count\": \"%s\",\n\t\t\t\"address\": \"%s\"\n\t\t}", $1, $2
|
||||
}
|
||||
NR>1 && NR<=top_count {
|
||||
printf ",\n\t\t{\n\t\t\t\"count\": \"%s\",\n\t\t\t\"address\": \"%s\"\n\t\t}", $1, $2
|
||||
}
|
||||
' >>"${report_jsn}"
|
||||
;;
|
||||
esac
|
||||
printf "\n\t%s\n" "]," >>"${report_jsn}"
|
||||
printf "\n\t],\n" >>"${report_jsn}"
|
||||
done
|
||||
rm -f "${top_tmpclients}" "${top_tmpdomains}" "${top_tmpblocked}"
|
||||
|
||||
# build json request list
|
||||
#
|
||||
search="${search//./\\.}"
|
||||
search="${search//[+*~%\$&\"\' ]/}"
|
||||
"${adb_awkcmd}" "BEGIN{i=0;printf \"\t\\\"requests\\\": [\n\"}/(${search})/{i++;if(i==1)printf \"\n\t\t{\n\t\t\t\\\"date\\\": \\\"%s\\\",\n\t\t\t\\\"time\\\": \\\"%s\\\",\n\t\t\t\\\"client\\\": \\\"%s\\\",\n\t\t\t\\\"domain\\\": \\\"%s\\\",\n\t\t\t\\\"rc\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2,\$3,\$4,\$5;else if(i<=${res_count})printf \",\n\t\t{\n\t\t\t\\\"date\\\": \\\"%s\\\",\n\t\t\t\\\"time\\\": \\\"%s\\\",\n\t\t\t\\\"client\\\": \\\"%s\\\",\n\t\t\t\\\"domain\\\": \\\"%s\\\",\n\t\t\t\\\"rc\\\": \\\"%s\\\"\n\t\t}\",\$1,\$2,\$3,\$4,\$5}END{printf \"\n\t]\n}\n\"}" "${adb_reportdir}/adb_report.srt" >>"${report_jsn}"
|
||||
: >"${report_srt}"
|
||||
"${adb_awkcmd}" "
|
||||
BEGIN {
|
||||
i = 0
|
||||
printf \"\t\\\"requests\\\": [\n\"
|
||||
}
|
||||
# Only process lines that match the search AND have exactly 6 fields
|
||||
(/(${search})/ && NF == 6) {
|
||||
i++
|
||||
if (i == 1) {
|
||||
printf \"\n\t\t{\
|
||||
\n\t\t\t\\\"date\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"time\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"client\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"type\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"domain\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"rc\\\": \\\"%s\\\"\
|
||||
\n\t\t}\",
|
||||
\$1, \$2, \$3, \$4, \$5, \$6
|
||||
}
|
||||
else if (i <= ${res_count}) {
|
||||
printf \",\n\t\t{\
|
||||
\n\t\t\t\\\"date\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"time\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"client\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"type\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"domain\\\": \\\"%s\\\",\
|
||||
\n\t\t\t\\\"rc\\\": \\\"%s\\\"\
|
||||
\n\t\t}\",
|
||||
\$1, \$2, \$3, \$4, \$5, \$6
|
||||
}
|
||||
}
|
||||
END {
|
||||
printf \"\n\t]\n}\n\"
|
||||
}
|
||||
" "${adb_reportdir}/adb_report.srt" >> "${report_jsn}"
|
||||
rm -f "${report_srt}"
|
||||
fi
|
||||
|
||||
# retrieve/prepare map data
|
||||
@@ -1687,19 +1835,19 @@ f_report() {
|
||||
done
|
||||
elif json_get_type status "${top}" && [ "${top}" = "requests" ] && [ "${status}" = "array" ]; then
|
||||
printf "%s\n%s\n%s\n" ":::" "::: Latest DNS Queries" ":::" >>"${report_txt}"
|
||||
printf "%-15s%-15s%-45s%-80s%s\n" "Date" "Time" "Client" "Domain" "Answer" >>"${report_txt}"
|
||||
printf "%-11s%-9s%-40s%-5s%-70s%s\n" "Date" "Time" "Client" "Type" "Domain" "Answer" >>"${report_txt}"
|
||||
json_select "${top}"
|
||||
index="1"
|
||||
while json_get_type status "${index}" && [ "${status}" = "object" ]; do
|
||||
json_get_values item "${index}"
|
||||
printf "%-15s%-15s%-45s%-80s%s\n" ${item} >>"${report_txt}"
|
||||
printf "%-11s%-9s%-40s%-5s%-70s%s\n" ${item} >>"${report_txt}"
|
||||
index="$((index + 1))"
|
||||
done
|
||||
fi
|
||||
json_select ".."
|
||||
done
|
||||
content="$("${adb_catcmd}" "${report_txt}" 2>/dev/null)"
|
||||
: >"${report_txt}"
|
||||
rm -f "${report_txt}"
|
||||
fi
|
||||
|
||||
# report output
|
||||
@@ -1719,7 +1867,7 @@ f_report() {
|
||||
;;
|
||||
"mail")
|
||||
[ "${adb_mail}" = "1" ] && [ -x "${adb_mailservice}" ] && "${adb_mailservice}" "${content}" >/dev/null 2>&1
|
||||
: >"${report_txt}"
|
||||
rm -f "${report_txt}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user