1 #!/bin/sh /etc/rc.common
2 # Copyright 2017-2020 Stan Grishin (stangri@melmac.net)
3 # shellcheck disable=SC2039,SC1091
10 export EXTRA_COMMANDS
='check dl killcache sizes show'
11 export EXTRA_HELP
=' check Checks if specified domain is found in current blacklist
12 dl Force-downloads all enabled block-list
13 sizes Displays the file-sizes of enabled block-lists
14 show Shows the service last-run status'
16 readonly packageName
='simple-adblock'
17 readonly serviceName
="$packageName $PKG_VERSION"
18 readonly addnhostsFile
="/var/run/${packageName}.addnhosts"
19 readonly addnhostsCache
="/var/run/${packageName}.addnhosts.cache"
20 readonly addnhostsGzip
="/etc/${packageName}.addnhosts.gz"
21 readonly addnhostsOutputFilter
='s|^|127.0.0.1 |;s|$||'
22 readonly addnhostsOutputFilterIPv6
='s|^|:: |;s|$||'
23 readonly dnsmasqFile
="/var/dnsmasq.d/${packageName}"
24 readonly dnsmasqCache
="/var/run/${packageName}.dnsmasq.cache"
25 readonly dnsmasqGzip
="/etc/${packageName}.dnsmasq.gz"
26 readonly dnsmasqOutputFilter
='s|^|local=/|;s|$|/|'
27 readonly ipsetFile
="/var/dnsmasq.d/${packageName}.ipset"
28 readonly ipsetCache
="/var/run/${packageName}.ipset.cache"
29 readonly ipsetGzip
="/etc/${packageName}.ipset.gz"
30 readonly ipsetOutputFilter
='s|^|ipset=/|;s|$|/adb|'
31 readonly serversFile
="/var/run/${packageName}.servers"
32 readonly serversCache
="/var/run/${packageName}.servers.cache"
33 readonly serversGzip
="/etc/${packageName}.servers.gz"
34 readonly serversOutputFilter
='s|^|server=/|;s|$|/|'
35 readonly unboundFile
="/var/lib/unbound/adb_list.${packageName}"
36 readonly unboundCache
="/var/run/${packageName}.unbound.cache"
37 readonly unboundGzip
="/etc/${packageName}.unbound.gz"
38 readonly unboundOutputFilter
='s|^|local-zone: "|;s|$|" static|'
39 readonly A_TMP
="/var/${packageName}.hosts.a.tmp"
40 readonly B_TMP
="/var/${packageName}.hosts.b.tmp"
41 readonly PIDFile
="/var/run/${packageName}.pid"
42 readonly jsonFile
="/var/run/${packageName}.json"
43 readonly sharedMemoryError
="/dev/shm/$packageName-error"
44 readonly sharedMemoryOutput
="/dev/shm/$packageName-output"
45 readonly hostsFilter
='/localhost/d;/^#/d;/^[^0-9]/d;s/^0\.0\.0\.0.//;s/^127\.0\.0\.1.//;s/[[:space:]]*#.*$//;s/[[:cntrl:]]$//;s/[[:space:]]//g;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
46 readonly domainsFilter
='/^#/d;s/[[:space:]]*#.*$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
47 readonly checkmark
='\xe2\x9c\x93'
48 readonly xmark
='\xe2\x9c\x97'
49 readonly _OK_
='\033[0;32m\xe2\x9c\x93\033[0m'
50 readonly _FAIL_
='\033[0;31m\xe2\x9c\x97\033[0m'
51 readonly __OK__
='\033[0;32m[\xe2\x9c\x93]\033[0m'
52 readonly __FAIL__
='\033[0;31m[\xe2\x9c\x97]\033[0m'
53 readonly _ERROR_
='\033[0;31mERROR\033[0m'
55 readonly messageSuccess
='Success'
56 readonly messageFail
='Fail'
57 readonly messageDownloading
='Downloading'
58 readonly messageReloading
='Reloading'
59 readonly messageRestarting
='Restarting'
60 readonly messageStarting
='Starting'
61 readonly messageForceReloading
='Force-Reloading'
62 readonly messageProcessing
='Processing'
63 readonly messageStopped
='Stopped'
67 statusNoInstall
) _ret
="$serviceName is not installed or not found";;
68 statusStopped
) _ret
="Stopped";;
69 statusStarting
) _ret
="Starting";;
70 statusRestarting
) _ret
="Restarting";;
71 statusForceReloading
) _ret
="Force Reloading";;
72 statusDownloading
) _ret
="Downloading";;
73 statusError
) _ret
="Error";;
74 statusWarning
) _ret
="Warning";;
75 statusFail
) _ret
="Fail";;
76 statusSuccess
) _ret
="Success";;
83 errorOutputFileCreate
) _ret
="failed to create $outputFile file";;
84 errorFailDNSReload
) _ret
="failed to restart/reload DNS resolver";;
85 errorSharedMemory
) _ret
="failed to access shared memory";;
86 errorSorting
) _ret
="failed to sort data file";;
87 errorOptimization
) _ret
="failed to optimize data file";;
88 errorWhitelistProcessing
) _ret
="failed to process whitelist";;
89 errorDataFileFormatting
) _ret
="failed to format data file";;
90 errorMovingDataFile
) _ret
="failed to move data file '${A_TMP}' to '${outputFile}'";;
91 errorCreatingCompressedCache
) _ret
="failed to create compressed cache";;
92 errorRemovingTempFiles
) _ret
="failed to remove temporary files";;
93 errorRestoreCompressedCache
) _ret
="failed to unpack compressed cache";;
94 errorRestoreCache
) _ret
="failed to move '$outputCache' to '$outputFile'";;
95 errorOhSnap
) _ret
="failed to create blocklist or restart DNS resolver";;
96 errorStopping
) _ret
="failed to stop $serviceName";;
97 errorDNSReload
) _ret
="failed to reload/restart DNS resolver";;
98 errorDownloadingList
) _ret
="failed to download";;
99 errorParsingList
) _ret
="failed to parse";;
104 create_lock
() { [ -e "$PIDFile" ] && return 1; touch "$PIDFile"; }
105 remove_lock
() { [ -e "$PIDFile" ] && rm -f "$PIDFile"; }
106 trap remove_lock EXIT
107 output_ok
() { output
1 "$_OK_"; output
2 "$__OK__\\n"; }
108 output_okn
() { output
1 "$_OK_\\n"; output
2 "$__OK__\\n"; }
109 output_fail
() { output
1 "$_FAIL_"; output
2 "$__FAIL__\\n"; }
110 output_failn
() { output
1 "$_FAIL_\\n"; output
2 "$__FAIL__\\n"; }
111 # str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; }
112 # str_contains() { test "$1" != "$(str_replace "$1" "$2" '')"; }
113 compare_versions
() { test "$(printf '%s\n' "$@
" | sort -V | head -n 1)" != "$1"; }
114 is_chaos_calmer
() { ubus
-S call system board |
grep -q 'Chaos Calmer'; }
115 is_ipset_procd
() { compare_versions
"$(sed -ne 's/^Version: //p' /usr/lib/opkg/info/firewall.control)" "2019-09-18"; }
116 led_on
(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'default-on' > "${1}/trigger" 2>&1; fi; }
117 led_off(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'none' > "${1}/trigger" 2>&1; fi; }
118 dnsmasq_hup
() { killall
-q -HUP dnsmasq
; }
119 dnsmasq_kill
() { killall
-q -KILL dnsmasq
; }
120 dnsmasq_restart
() { /etc
/init.d
/dnsmasq restart
>/dev
/null
2>&1; }
121 unbound_restart
() { /etc
/init.d
/unbound restart
>/dev
/null
2>&1; }
124 # Can take a single parameter (text) to be output at any verbosity
125 # Or target verbosity level and text to be output at specifc verbosity
126 local msg memmsg logmsg
127 if [ $# -ne 1 ]; then
128 if [ $
((verbosity
& $1)) -gt 0 ] ||
[ "$verbosity" = "$1" ]; then shift; else return 0; fi
130 [ -t 1 ] && printf "%b" "$1"
131 msg
="${1//$serviceName /service }";
132 if [ "$(printf "%b
" "$msg" | wc -l)" -gt 0 ]; then
133 [ -s "$sharedMemoryOutput" ] && memmsg
="$(cat "$sharedMemoryOutput")"
134 logmsg
="$(printf "%b
" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
135 logger
-t "${packageName:-service} [$$]" "$(printf "%b
" "$logmsg")"
136 rm -f "$sharedMemoryOutput"
138 printf "%b" "$msg" >> "$sharedMemoryOutput"
142 export serviceEnabled forceDNS parallelDL debug allowIDN compressedCache
143 export targetDNS bootDelay dlTimeout curlRetry verbosity
=1 led dnsInstance
144 export whitelist_domains blacklist_domains
145 export whitelist_domains_urls blacklist_domains_urls blacklist_hosts_urls
146 export wan_if wan_gw wanphysdev dl_command serviceStatus dl_flag
147 export outputFilter outputFilterIPv6 outputFile outputGzip outputCache ipv6Enabled
149 load_package_config
() {
150 config_load
"$packageName"
151 config_get_bool serviceEnabled
'config' 'enabled' 1
152 config_get_bool forceDNS
'config' 'force_dns' 1
153 config_get_bool parallelDL
'config' 'parallel_downloads' 1
154 config_get_bool debug
'config' 'debug' 0
155 config_get_bool compressedCache
'config' 'compressed_cache' 0
156 config_get_bool ipv6Enabled
'config' 'ipv6_enabled' 0
157 config_get bootDelay
'config' 'boot_delay' '120'
158 config_get dlTimeout
'config' 'download_timeout' '20'
159 config_get curlRetry
'config' 'curl_retry' '3'
160 config_get verbosity
'config' 'verbosity' '2'
161 config_get led
'config' 'led'
162 config_get targetDNS
'config' 'dns' 'dnsmasq.servers'
163 config_get dnsInstance
'config' 'dns_instance' '0'
164 config_get whitelist_domains
'config' 'whitelist_domain'
165 config_get blacklist_domains
'config' 'blacklist_domain'
166 config_get whitelist_domains_urls
'config' 'whitelist_domains_url'
167 config_get blacklist_domains_urls
'config' 'blacklist_domains_url'
168 config_get blacklist_hosts_urls
'config' 'blacklist_hosts_url'
170 if [ "$targetDNS" != 'dnsmasq.addnhosts' ] && [ "$targetDNS" != 'dnsmasq.conf' ] && \
171 [ "$targetDNS" != 'dnsmasq.servers' ] && [ "$targetDNS" != 'unbound.adb_list' ] && \
172 [ "$targetDNS" != 'dnsmasq.ipset' ] ; then
173 targetDNS
='dnsmasq.servers'
178 outputFilter
="$addnhostsOutputFilter"
179 outputFile
="$addnhostsFile"
180 outputCache
="$addnhostsCache"
181 outputGzip
="$addnhostsGzip"
182 [ "$ipv6Enabled" -gt 0 ] && outputFilterIPv6
="$addnhostsOutputFilterIPv6"
183 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
184 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
185 rm -f "$serversFile" "$serversCache" "$serversGzip"
186 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
189 outputFilter
="$dnsmasqOutputFilter"
190 outputFile
="$dnsmasqFile"
191 outputCache
="$dnsmasqCache"
192 outputGzip
="$dnsmasqGzip"
193 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
194 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
195 rm -f "$serversFile" "$serversCache" "$serversGzip"
196 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
199 outputFilter
="$ipsetOutputFilter"
200 outputFile
="$ipsetFile"
201 outputCache
="$ipsetCache"
202 outputGzip
="$ipsetGzip"
203 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
204 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
205 rm -f "$serversFile" "$serversCache" "$serversGzip"
206 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
209 outputFilter
="$serversOutputFilter"
210 outputFile
="$serversFile"
211 outputCache
="$serversCache"
212 outputGzip
="$serversGzip"
213 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
214 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
215 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
216 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
219 outputFilter
="$unboundOutputFilter"
220 outputFile
="$unboundFile"
221 outputCache
="$unboundCache"
222 outputGzip
="$unboundGzip"
223 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
224 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
225 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
226 rm -f "$serversFile" "$serversCache" "$serversGzip"
229 if [ -z "${verbosity##*[!0-9]*}" ] ||
[ "$verbosity" -lt 0 ] ||
[ "$verbosity" -gt 2 ]; then
232 .
/lib
/functions
/network.sh
233 .
/usr
/share
/libubox
/jshn.sh
234 # Prefer curl because it supports the file: scheme.
235 if [ -x /usr
/bin
/curl
]; then
236 dl_command
="curl --insecure --retry $curlRetry --connect-timeout $dlTimeout --silent"
238 elif wget
-V 2>/dev
/null |
grep -q "+ssl"; then
239 dl_command
="wget --no-check-certificate --timeout $dlTimeout -q"
242 dl_command
="uclient-fetch --no-check-certificate --timeout $dlTimeout -q"
245 led
="${led:+/sys/class/leds/$led}"
251 if [ "$debug" -ne 0 ]; then
252 exec 1>>/tmp
/simple-adblock.log
257 if [ "$serviceEnabled" -eq 0 ]; then
260 output
"$packageName is currently disabled.\\n"
261 output
"Run the following commands before starting service again:\\n"
262 output
"uci set ${packageName}.config.enabled='1'; uci commit $packageName;\\n"
269 dnsmasq.addnhosts | dnsmasq.conf | dnsmasq.ipset | dnsmasq.servers
)
270 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-IDN' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'IDN'; then
282 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-ipset' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'ipset'; then
283 output
"$_ERROR_: DNSMASQ ipset support is enabled in $packageName, but DNSMASQ is either not installed or installed DNSMASQ does not support ipsets!\\n"
284 targetDNS
='dnsmasq.servers'
286 if ! ipset
help hash:net
>/dev
/null
2>&1; then
287 output
"$_ERROR_: DNSMASQ ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
288 targetDNS
='dnsmasq.servers'
293 [ ! -d "${outputFile%/*}" ] && mkdir
-p "${outputFile%/*}"
294 [ ! -d "${outputCache%/*}" ] && mkdir
-p "${outputFile%/*}"
295 [ ! -d "${outputGzip%/*}" ] && mkdir
-p "${outputFile%/*}"
296 cacheOps
'testGzip' && return 0
297 network_flush_cache
; network_find_wan wan_if
; network_get_gateway wan_gw
"$wan_if";
298 [ -n "$wan_gw" ] && return 0
299 output
"$_ERROR_: $serviceName failed to discover WAN gateway.\\n"; return 1;
303 local cfg
="$1" param
="$2"
306 if [ "$(uci -q get dhcp."$cfg".serversfile)" = "$serversFile" ]; then
307 uci
-q del dhcp.
"$cfg".serversfile
309 if ! uci
-q get dhcp.
"$cfg".addnhosts |
grep -q "$addnhostsFile"; then
310 uci add_list dhcp.
"$cfg".addnhosts
="$addnhostsFile"
313 dnsmasq.conf|dnsmasq.ipset|unbound.adb_list|cleanup
)
314 uci
-q del_list dhcp.
"$cfg".addnhosts
="$addnhostsFile"
315 if [ "$(uci -q get dhcp."$cfg".serversfile)" = "$serversFile" ]; then
316 uci
-q del dhcp.
"$cfg".serversfile
320 uci
-q del_list dhcp.
"$cfg".addnhosts
="$addnhostsFile"
321 if [ "$(uci -q get dhcp."$cfg".serversfile)" != "$serversFile" ]; then
322 uci
set dhcp.
"$cfg".serversfile
="$serversFile"
329 local param output_text i
332 if [ ! -s "$outputFile" ]; then
333 tmpfs
set status
"statusFail"
334 tmpfs add error
"errorOutputFileCreate"
335 output
"$_ERROR_: $(getErrorText 'errorOutputFileCreate')!\\n"
340 if [ "$dnsInstance" = "*" ]; then
341 config_foreach dnsmasqOps
'dnsmasq' "$targetDNS"
342 elif [ -n "$dnsInstance" ]; then
343 for i
in $dnsInstance; do
344 dnsmasqOps
"@dnsmasq[$i]" "$targetDNS"
349 dnsmasq.addnhosts|dnsmasq.servers
)
351 output_text
='Reloading DNSMASQ'
353 dnsmasq.conf|dnsmasq.ipset
)
354 param
=dnsmasq_restart
355 output_text
='Restarting DNSMASQ'
358 param
=unbound_restart
359 output_text
='Restarting Unbound'
363 if [ -n "$(uci changes dhcp)" ]; then
365 if [ "$param" = 'unbound_restart' ]; then
366 param
='dnsmasq_restart; unbound_restart;'
367 output_text
='Restarting Unbound/DNSMASQ'
369 param
=dnsmasq_restart
370 output_text
='Restarting DNSMASQ'
373 output
1 "$output_text "
374 output
2 "$output_text "
375 tmpfs
set message
"$output_text"
376 if eval "$param"; then
377 tmpfs
set status
"statusSuccess"
382 tmpfs
set status
"statusFail"
383 tmpfs add error
"errorDNSReload"
384 output
"$_ERROR_: $(getErrorText 'errorDNSReload')!\\n"
390 dnsmasq.addnhosts | dnsmasq.servers
)
393 dnsmasq.conf | dnsmasq.ipset
)
394 param
=dnsmasq_restart
397 param
=unbound_restart
400 if [ -n "$(uci changes dhcp)" ]; then
402 if [ "$param" = 'unbound_restart' ]; then
403 param
='dnsmasq_restart; unbound_restart;'
405 param
=dnsmasq_restart
413 dnsmasq.addnhosts | dnsmasq.conf | dnsmasq.ipset | dnsmasq.servers
)
414 param
=dnsmasq_restart
417 param
=unbound_restart
427 local action
="$1" instance
="$2" value
="$3"
428 local status message error stats
429 local readReload readRestart curReload curRestart ret
430 if [ -s "$jsonFile" ]; then
431 status
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['status']")"
432 message
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['message']")"
433 error
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['error']")"
434 stats
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['stats']")"
435 readReload
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['reload']")"
436 readRestart
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['restart']")"
442 printf "%b" "$status"; return;;
444 printf "%b" "$message"; return;;
446 printf "%b" "$error"; return;;
448 printf "%b" "$stats"; return;;
450 curReload
="$parallelDL $debug $dlTimeout $whitelist_domains $blacklist_domains $whitelist_domains_urls $blacklist_domains_urls $blacklist_hosts_urls $targetDNS"
451 curRestart
="$compressedCache $forceDNS $led"
452 if [ ! -s "$jsonFile" ]; then
454 elif [ "$curReload" != "$readReload" ]; then
456 elif [ "$curRestart" != "$readRestart" ]; then
466 [ -n "$status" ] && status
="$status $value" || status
="$value";;
468 [ -n "$message" ] && message
="$message $value" || message
="$value";;
470 [ -n "$error" ] && error
="$error $value" || error
="$value";;
472 [ -n "$stats" ] && stats
="$stats $value" || stats
="$value";;
492 unset readReload
; unset readRestart
;;
506 readReload
="$parallelDL $debug $dlTimeout $whitelist_domains $blacklist_domains $whitelist_domains_urls $blacklist_domains_urls $blacklist_hosts_urls $targetDNS"
507 readRestart
="$compressedCache $forceDNS $led"
513 json_add_object
'data'
514 json_add_string version
"$PKG_VERSION"
515 json_add_string status
"$status"
516 json_add_string message
"$message"
517 json_add_string error
"$error"
518 json_add_string stats
"$stats"
519 json_add_string reload
"$readReload"
520 json_add_string restart
"$readRestart"
522 json_dump
> "$jsonFile"
530 [ -s "$outputFile" ] && { mv -f "$outputFile" "$outputCache"; true
> "$outputFile"; } >/dev
/null
2>/dev
/null
534 [ -s "$outputCache" ] && mv "$outputCache" "$outputFile" >/dev
/null
2>/dev
/null
538 [ -s "$outputCache" ]
542 [ -s "$outputGzip" ] && gzip -t -c "$outputGzip"
546 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
547 if gzip < "$outputFile" > "$R_TMP"; then
548 if mv "$R_TMP" "$outputGzip"; then
559 expand|unpack|expandGzip|unpackGzip
)
560 [ -s "$outputGzip" ] && gzip -dc < "$outputGzip" > "$outputCache"
567 local action
="$1" param
="$2" _restart
569 reload
) /etc
/init.d
/firewall reload
>/dev
/null
2>&1;;
570 restart
) /etc
/init.d
/firewall restart
>/dev
/null
2>&1;;
573 dns_redirect
) uci
-q del firewall.simple_adblock_dns_redirect
;;
574 ipset
) uci
-q del firewall.simple_adblock_ipset
575 uci
-q del firewall.simple_adblock_ipset_rule
;;
577 uci
-q del firewall.simple_adblock_dns_redirect
578 uci
-q del firewall.simple_adblock_ipset
579 uci
-q del firewall.simple_adblock_ipset_rule
586 if ! uci
-q get firewall.simple_adblock_dns_redirect
>/dev
/null
; then
587 uci
-q set firewall.simple_adblock_dns_redirect
=redirect
588 uci
-q set firewall.simple_adblock_dns_redirect.name
=simple_adblock_dns_hijack
589 uci
-q set firewall.simple_adblock_dns_redirect.target
=DNAT
590 uci
-q set firewall.simple_adblock_dns_redirect.src
=lan
591 uci
-q set firewall.simple_adblock_dns_redirect.proto
=tcpudp
592 uci
-q set firewall.simple_adblock_dns_redirect.src_dport
=53
593 uci
-q set firewall.simple_adblock_dns_redirect.dest_port
=53
597 if ! uci
-q get firewall.simple_adblock_ipset
>/dev
/null
; then
598 uci
-q set firewall.simple_adblock_ipset
=ipset
599 uci
-q set firewall.simple_adblock_ipset.name
=adb
600 uci
-q set firewall.simple_adblock_ipset.match
=dest_net
601 uci
-q set firewall.simple_adblock_ipset.storage
=hash
602 uci
-q set firewall.simple_adblock_ipset.enabled
=1
605 if ! uci
-q get firewall.simple_adblock_ipset_rule
>/dev
/null
; then
606 uci
-q set firewall.simple_adblock_ipset_rule
=rule
607 uci
-q set firewall.simple_adblock_ipset_rule.name
=simple_adblock_ipset_rule
608 uci
-q set firewall.simple_adblock_ipset_rule.ipset
=adb
609 uci
-q set firewall.simple_adblock_ipset_rule.src
=lan
610 uci
-q set firewall.simple_adblock_ipset_rule.dest
='*'
611 uci
-q set firewall.simple_adblock_ipset_rule.proto
=tcpudp
612 uci
-q set firewall.simple_adblock_ipset_rule.target
=REJECT
613 uci
-q set firewall.simple_adblock_ipset_rule.enabled
=1
617 if ! uci
-q get firewall.simple_adblock_dns_redirect
>/dev
/null
; then
618 uci
-q set firewall.simple_adblock_dns_redirect
=redirect
619 uci
-q set firewall.simple_adblock_dns_redirect.name
=simple_adblock_dns_hijack
620 uci
-q set firewall.simple_adblock_dns_redirect.target
=DNAT
621 uci
-q set firewall.simple_adblock_dns_redirect.src
=lan
622 uci
-q set firewall.simple_adblock_dns_redirect.proto
=tcpudp
623 uci
-q set firewall.simple_adblock_dns_redirect.src_dport
=53
624 uci
-q set firewall.simple_adblock_dns_redirect.dest_port
=53
626 if ! uci
-q get firewall.simple_adblock_ipset
>/dev
/null
; then
627 uci
-q set firewall.simple_adblock_ipset
=ipset
628 uci
-q set firewall.simple_adblock_ipset.name
=adb
629 uci
-q set firewall.simple_adblock_ipset.match
=dest_net
630 uci
-q set firewall.simple_adblock_ipset.storage
=hash
631 uci
-q set firewall.simple_adblock_ipset.enabled
=1
634 if ! uci
-q get firewall.simple_adblock_ipset_rule
>/dev
/null
; then
635 uci
-q set firewall.simple_adblock_ipset_rule
=rule
636 uci
-q set firewall.simple_adblock_ipset_rule.name
=simple_adblock_ipset_rule
637 uci
-q set firewall.simple_adblock_ipset_rule.ipset
=adb
638 uci
-q set firewall.simple_adblock_ipset_rule.src
=lan
639 uci
-q set firewall.simple_adblock_ipset_rule.dest
='*'
640 uci
-q set firewall.simple_adblock_ipset_rule.proto
=tcpudp
641 uci
-q set firewall.simple_adblock_ipset_rule.target
=REJECT
642 uci
-q set firewall.simple_adblock_ipset_rule.enabled
=1
647 if [ -n "$(uci changes firewall)" ]; then
648 uci
-q commit firewall
649 if [ -z "$_restart" ]; then
658 local label
type D_TMP R_TMP
659 if [ -z "$1" ] ||
[ -z "$2" ] ||
[ -z "$3" ]; then return 1; fi
660 label
="${1##*//}"; label
="${label%%/*}";
661 if [ "$2" = 'hosts' ]; then
662 label
="Hosts: $label"; filter
="$hostsFilter";
664 label
="Domains: $label"; filter
="$domainsFilter";
666 if [ "$3" = 'blocked' ]; then
667 type='Blocked'; D_TMP
="$B_TMP";
669 type='Allowed'; D_TMP
="$A_TMP";
671 while [ -z "$R_TMP" ] ||
[ -e "$R_TMP" ]; do
672 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
674 if ! $dl_command "$1" $dl_flag "$R_TMP" 2>/dev
/null ||
[ ! -s "$R_TMP" ]; then
676 output
2 "[DL] $type $label $__FAIL__\\n"
677 echo "errorDownloadingList=${1}" >> "$sharedMemoryError"
679 sed -i "$filter" "$R_TMP"
680 if [ ! -s "$R_TMP" ]; then
682 output
2 "[DL] $type $label $__FAIL__\\n"
683 echo "errorParsingList=${1}" >> "$sharedMemoryError"
685 cat "${R_TMP}" >> "$D_TMP"
687 output
2 "[DL] $type $label $__OK__\\n"
695 local hf w_filter j
=0 R_TMP
697 tmpfs
set message
"${messageDownloading}..."
698 tmpfs
set status
"statusDownloading"
700 rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
701 if [ "$(awk '/^MemFree/ {print int($2/1000)}' "/proc
/meminfo
")" -lt 32 ]; then
702 output
3 'Low free memory, restarting resolver... '
703 if dnsOps
'quiet'; then
709 touch $A_TMP; touch $B_TMP;
710 output
1 'Downloading lists '
711 rm -f "$sharedMemoryError"
712 if [ -n "$blacklist_hosts_urls" ]; then
713 for hf
in ${blacklist_hosts_urls}; do
714 if [ "$parallelDL" -gt 0 ]; then
715 process_url
"$hf" 'hosts' 'blocked' &
717 process_url
"$hf" 'hosts' 'blocked'
721 if [ -n "$blacklist_domains_urls" ]; then
722 for hf
in ${blacklist_domains_urls}; do
723 if [ "$parallelDL" -gt 0 ]; then
724 process_url
"$hf" 'domains' 'blocked' &
726 process_url
"$hf" 'domains' 'blocked'
730 if [ -n "$whitelist_domains_urls" ]; then
731 for hf
in ${whitelist_domains_urls}; do
732 if [ "$parallelDL" -gt 0 ]; then
733 process_url
"$hf" 'domains' 'allowed' &
735 process_url
"$hf" 'domains' 'allowed'
741 if [ -s "$sharedMemoryError" ]; then
742 while IFS
= read -r line
; do
743 tmpfs add error
"$line"
744 done < "$sharedMemoryError"
745 rm -f "$sharedMemoryError"
748 [ -n "$blacklist_domains" ] && for hf
in ${blacklist_domains}; do echo "$hf" |
sed "$domainsFilter" >> $B_TMP; done
749 whitelist_domains
="${whitelist_domains}
751 [ -n "$whitelist_domains" ] && for hf
in ${whitelist_domains}; do hf="$(echo "$hf" | sed 's/\./\\./g')"; w_filter="$w_filter/^${hf}$/d;/\\.${hf}$
/d
;"; done
753 [ ! -s "$B_TMP" ] && return 1
755 output 1 'Processing downloads '
756 output 2 'Sorting combined list '
757 tmpfs set message "$messageProcessing: sorting combined list
"
758 if [ "$allowIDN" -gt 0 ]; then
759 if sort -u "$B_TMP" > "$A_TMP"; then
763 tmpfs add error "errorSorting
"
766 if sort -u "$B_TMP" | grep -E -v '[^a-zA-Z0-9=/.-]' > "$A_TMP"; then
770 tmpfs add error "errorSorting
"
774 if [ "$targetDNS" = 'dnsmasq.conf' ] || \
775 [ "$targetDNS" = 'dnsmasq.ipset' ] || \
776 [ "$targetDNS" = 'dnsmasq.servers' ] || \
777 [ "$targetDNS" = 'unbound.adb_list' ]; then
778 # TLD optimization written by Dirk Brenken (dev@brenken.org)
779 output 2 'Optimizing combined list '
780 tmpfs set message "$messageProcessing: optimizing combined list
"
781 # sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/' is actually slower than awk
782 if awk -F ".
" '{for(f=NF;f>1;f--)printf "%s.
",$f;print $1}' "$A_TMP" > "$B_TMP"; then
783 if sort "$B_TMP" > "$A_TMP"; then
784 if awk '{if(NR=1){tld=$NF};while(getline){if($NF!~tld"\\.
"){print tld;tld=$NF}}print tld}' "$A_TMP" > "$B_TMP"; then
785 if awk -F ".
" '{for(f=NF;f>1;f--)printf "%s.
",$f;print $1}' "$B_TMP" > "$A_TMP"; then
786 if sort -u "$A_TMP" > "$B_TMP"; then
790 tmpfs add error "errorOptimization
"
795 tmpfs add error "errorOptimization
"
799 tmpfs add error "errorOptimization
"
804 tmpfs add error "errorOptimization
"
808 tmpfs add error "errorOptimization
"
815 output 2 'Whitelisting domains '
816 tmpfs set message "$messageProcessing: whitelisting domains
"
817 if sed -i "$w_filter" "$B_TMP"; then
821 tmpfs add error "errorWhitelistProcessing
"
824 output 2 'Formatting merged file '
825 tmpfs set message "$messageProcessing: formatting merged
file"
826 if [ -z "$outputFilterIPv6" ]; then
827 if sed "$outputFilter" "$B_TMP" > "$A_TMP"; then
831 tmpfs add error "errorDataFileFormatting
"
836 if sed "$outputFilter" "$B_TMP" > "$A_TMP" && \
837 sed "$outputFilterIPv6" "$B_TMP" >> "$A_TMP"; then
841 tmpfs add error "errorDataFileFormatting
"
849 output 2 'Creating DNSMASQ addnhosts file '
850 tmpfs set message "$messageProcessing: creating DNSMASQ addnhosts
file"
853 output 2 'Creating DNSMASQ config file '
854 tmpfs set message "$messageProcessing: creating DNSMASQ config
file"
857 output 2 'Creating DNSMASQ ipset file '
858 tmpfs set message "$messageProcessing: creating DNSMASQ ipset
file"
861 output 2 'Creating DNSMASQ servers file '
862 tmpfs set message "$messageProcessing: creating DNSMASQ servers
file"
865 output 2 'Creating Unbound adb_list file '
866 tmpfs set message "$messageProcessing: creating Unbound adb_list
file"
869 if mv "$A_TMP" "$outputFile"; then
873 tmpfs add error "errorMovingDataFile
"
875 if [ "$compressedCache" -gt 0 ]; then
876 output 2 'Creating compressed cache '
877 tmpfs set message "$messageProcessing: creating compressed cache
"
878 if cacheOps 'createGzip'; then
882 tmpfs add error "errorCreatingCompressedCache
"
887 output 2 'Removing temporary files '
888 tmpfs set message "$messageProcessing: removing temporary files
"
889 rm -f "/tmp
/${packageName}_tmp.
*" "$A_TMP" "$B_TMP" "$outputCache" || j=1
890 if [ $j -eq 0 ]; then
894 tmpfs add error "errorRemovingTempFiles
"
904 rc_procd start_service 'on_boot' && rc_procd service_triggers
909 is_enabled 'on_start' || return 1
910 local action status error message stats c
911 if ! create_lock; then
912 output 3 "$serviceName: another instance is starting up
"; output_fail
916 status="$
(tmpfs get status
)"
917 error="$
(tmpfs get error
)"
918 message="$
(tmpfs get message
)"
919 stats="$
(tmpfs get stats
)"
920 action="$
(tmpfs get triggers
)"
922 if [ "$action" = 'on_boot' ] || [ "$1" = 'on_boot' ]; then
923 if cacheOps 'testGzip' || cacheOps 'test'; then
928 elif [ "$action" = 'download' ] || [ "$1" = 'download' ] || [ -n "$error" ]; then
930 elif [ ! -s "$outputFile" ]; then
931 if cacheOps 'testGzip' || cacheOps 'test'; then
936 elif [ "$action" = 'restart' ] || [ "$1" = 'restart' ]; then
938 elif [ -s "$outputFile" ] && [ "$status" = "statusSuccess
" ] && [ -z "$error" ]; then
939 [ "$1" != 'hotplug' ] && showstatus
948 if is_chaos_calmer || ! is_ipset_procd; then
949 if [ "$forceDNS" -ne 0 ]; then
950 fw3Ops 'insert' 'dns_redirect'
952 fw3Ops 'remove' 'dns_redirect'
954 if [ "$targetDNS" = 'dnsmasq.ipset' ]; then
955 fw3Ops 'insert' 'ipset'
957 fw3Ops 'remove' 'ipset'
959 procd_open_instance 'main'
960 procd_set_param command /bin/true
961 procd_set_param stdout 1
962 procd_set_param stderr 1
965 procd_open_instance 'main'
966 procd_set_param command /bin/true
967 procd_set_param stdout 1
968 procd_set_param stderr 1
970 json_add_array firewall
971 if [ "$forceDNS" -ne 0 ]; then
973 json_add_string type redirect
974 json_add_string name simple_adblock_dns_redirect
975 json_add_string target DNAT
976 json_add_string src lan
977 json_add_string proto tcpudp
978 json_add_string src_dport 53
979 json_add_string dest_port 53
980 json_add_string reflection 0
983 if [ "$targetDNS" = 'dnsmasq.ipset' ]; then
985 json_add_string type ipset
986 json_add_string name adb
987 json_add_string match dest_net
988 json_add_string storage hash
989 json_add_string enabled 1
992 json_add_string type rule
993 json_add_string name simple_adblock_ipset_rule
994 json_add_string ipset adb
995 json_add_string src lan
996 json_add_string dest '*'
997 json_add_string proto tcpudp
998 json_add_string target REJECT
999 json_add_string enabled 1
1004 procd_close_instance
1007 if [ "$action" = 'restore' ]; then
1008 output 0 "Starting
$serviceName...
"
1009 output 3 "Starting
$serviceName...
\\n
"
1010 tmpfs set status "statusStarting
"
1011 if cacheOps 'testGzip' && ! cacheOps 'test' && [ ! -s "$outputFile" ]; then
1012 output 3 'Found compressed cache file, unpacking it '
1013 tmpfs set message 'found compressed cache file, unpacking it.'
1014 if cacheOps 'unpackGzip'; then
1018 tmpfs add error "errorRestoreCompressedCache
"
1019 output "$_ERROR_: $
(getErrorText
'errorRestoreCompressedCache')!\\n
"
1023 if cacheOps 'test' && [ ! -s "$outputFile" ]; then
1024 output 3 'Found cache file, reusing it '
1025 tmpfs set message 'found cache file, reusing it.'
1026 if cacheOps 'restore'; then
1031 tmpfs add error "errorRestoreCache
"
1032 output "$_ERROR_: $
(getErrorText
'errorRestoreCache')!\\n
"
1039 if [ -s "$outputFile" ] || cacheOps 'test' || cacheOps 'testGzip'; then
1040 output 0 "Force-reloading
$serviceName...
"
1041 output 3 "Force-reloading
$serviceName...
\\n
"
1042 tmpfs set status "statusForceReloading
"
1044 output 0 "Starting
$serviceName...
"
1045 output 3 "Starting
$serviceName...
\\n
"
1046 tmpfs set status "statusStarting
"
1052 output 0 "Restarting
$serviceName...
"
1053 output 3 "Restarting
$serviceName...
\\n
"
1054 tmpfs set status "statusRestarting
"
1058 output 0 "Starting
$serviceName...
"
1059 output 3 "Starting
$serviceName...
\\n
"
1060 tmpfs set status "statusStarting
"
1064 if [ -s "$outputFile" ] && [ "$
(tmpfs get status
)" != "statusFail
" ]; then
1065 output 0 "$__OK__\\n
";
1067 tmpfs set status "statusSuccess
"
1068 c="$
(wc -l < "$outputFile")"
1069 tmpfs set stats "$serviceName is blocking
$c domains
(with
${targetDNS})"
1072 output 0 "$__FAIL__\\n
";
1073 tmpfs set status "statusFail
"
1074 tmpfs add error "errorOhSnap
"
1080 service_started() { is_ipset_procd && procd_set_config_changed firewall; }
1081 service_stopped() { is_ipset_procd && procd_set_config_changed firewall; }
1082 restart_service() { rc_procd start_service 'restart'; }
1083 reload_service() { restart_service; }
1084 restart() { restart_service; }
1085 reload() { restart_service; }
1086 dl() { rc_procd start_service 'download'; }
1088 rm -f "$addnhostsCache" "$addnhostsGzip"
1089 rm -f "$dnsmasqCache" "$dnsmasqGzip"
1090 rm -f "$ipsetCache" "$ipsetGzip"
1091 rm -f "$serversCache" "$serversGzip"
1092 rm -f "$unboundCache" "$unboundGzip"
1094 config_foreach dnsmasqOps 'dnsmasq' 'cleanup'
1095 uci -q commit 'dhcp'
1099 show() { showstatus; }
1100 status_service() { showstatus; }
1102 local status="$
(tmpfs get status
)"
1103 local message="$
(tmpfs get message
)"
1104 local error="$
(tmpfs get error
)"
1105 local stats="$
(tmpfs get stats
)"
1107 if [ "$status" = "statusSuccess
" ]; then
1108 output "$stats "; output_okn;
1110 [ -n "$status" ] && status="$
(getStatusText
"$status")"
1111 if [ -n "$status" ] && [ -n "$message" ]; then
1112 status="${status}: $message"
1114 [ -n "$status" ] && output "$serviceName $status\\n
"
1116 if [ -n "$error" ]; then
1121 errorDownloadingList|errorParsingList)
1122 output "$_ERROR_: $
(getErrorText
"$c") $url!\\n
";;
1124 output "$_ERROR_: $
(getErrorText
"$c")!\\n
";;
1133 fw3Ops 'remove' 'all'
1134 if [ -s "$outputFile" ]; then
1135 output "Stopping
$serviceName...
"
1137 if dnsOps 'on_stop'; then
1139 output 0 "$__OK__\\n
"; output_okn;
1140 tmpfs set status "statusStopped
"
1143 output 0 "$__FAIL__\\n
"; output_fail;
1144 tmpfs set status "statusFail
"
1145 tmpfs add error "errorStopping
"
1146 output "$_ERROR_: $
(getErrorText
'errorStopping')!\\n
"
1151 service_triggers() {
1152 procd_add_reload_trigger 'simple-adblock'
1158 local c="$
(grep -c "$string" "$outputFile")"
1159 if [ ! -s "$outputFile" ]; then
1160 echo "No blacklist
('$outputFile') found.
"
1161 elif [ -z "$string" ]; then
1162 echo "Usage
: /etc
/init.d
/${packageName} check string
"
1163 elif [ "$c" -gt 0 ]; then
1164 if [ "$c" -gt 1 ]; then
1165 echo "Found
$c matches
for '$string' in '$outputFile':"
1167 echo "Found
1 match
for '$string' in '$outputFile':"
1169 case "$targetDNS" in
1171 grep "$string" "$outputFile" | sed 's|^127.0.0.1 ||;s|^:: ||;';;
1173 grep "$string" "$outputFile" | sed 's|local=/||;s|/$||;';;
1175 grep "$string" "$outputFile" | sed 's|ipset=/||;s|/adb$||;';;
1177 grep "$string" "$outputFile" | sed 's|server=/||;s|/$||;';;
1179 grep "$string" "$outputFile" | sed 's|^local-zone: "||
;s|
" static$||;';;
1182 echo "The
$string is not found
in current blacklist
('$outputFile').
"
1191 for i
in $blacklist_domains_urls; do
1192 [ "${i//melmac}" != "$i" ] && continue
1193 if $dl_command "$i" $dl_flag /tmp
/sast
2>/dev
/null
&& [ -s /tmp
/sast
]; then
1194 echo "# File size: $(du -sh /tmp/sast | awk '{print $1}')"
1195 if compare_versions
"$(du -sk /tmp/sast)" "500"; then
1196 echo "# blocklist too big for most routers"
1197 elif compare_versions
"$(du -sk /tmp/sast)" "100"; then
1198 echo "# blocklist may be too big for some routers"
1201 echo " list blacklist_domains_url '$i'"
1204 echo "# site was down on last check"
1205 echo "# list blacklist_domains_url '$i'"
1210 for i
in $blacklist_hosts_urls; do
1211 if $dl_command "$i" $dl_flag /tmp
/sast
2>/dev
/null
&& [ -s /tmp
/sast
]; then
1212 echo "# File size: $(du -sh /tmp/sast | awk '{print $1}')"
1213 if compare_versions
"$(du -sk /tmp/sast)" "500"; then
1214 echo "# blocklist too big for most routers"
1215 elif compare_versions
"$(du -sk /tmp/sast)" "100"; then
1216 echo "# blocklist may be too big for some routers"
1219 echo " list blacklist_hosts_url '$i'"
1222 echo "# site was down on last check"
1223 echo "# list blacklist_hosts_url '$i'"