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
148 export is_ssl_supported
150 load_package_config
() {
151 config_load
"$packageName"
152 config_get_bool serviceEnabled
'config' 'enabled' 1
153 config_get_bool forceDNS
'config' 'force_dns' 1
154 config_get_bool parallelDL
'config' 'parallel_downloads' 1
155 config_get_bool debug
'config' 'debug' 0
156 config_get_bool compressedCache
'config' 'compressed_cache' 0
157 config_get_bool ipv6Enabled
'config' 'ipv6_enabled' 0
158 config_get bootDelay
'config' 'boot_delay' '120'
159 config_get dlTimeout
'config' 'download_timeout' '20'
160 config_get curlRetry
'config' 'curl_retry' '3'
161 config_get verbosity
'config' 'verbosity' '2'
162 config_get led
'config' 'led'
163 config_get targetDNS
'config' 'dns' 'dnsmasq.servers'
164 config_get dnsInstance
'config' 'dns_instance' '0'
165 config_get whitelist_domains
'config' 'whitelist_domain'
166 config_get blacklist_domains
'config' 'blacklist_domain'
167 config_get whitelist_domains_urls
'config' 'whitelist_domains_url'
168 config_get blacklist_domains_urls
'config' 'blacklist_domains_url'
169 config_get blacklist_hosts_urls
'config' 'blacklist_hosts_url'
171 if [ "$targetDNS" != 'dnsmasq.addnhosts' ] && [ "$targetDNS" != 'dnsmasq.conf' ] && \
172 [ "$targetDNS" != 'dnsmasq.servers' ] && [ "$targetDNS" != 'unbound.adb_list' ] && \
173 [ "$targetDNS" != 'dnsmasq.ipset' ] ; then
174 targetDNS
='dnsmasq.servers'
179 outputFilter
="$addnhostsOutputFilter"
180 outputFile
="$addnhostsFile"
181 outputCache
="$addnhostsCache"
182 outputGzip
="$addnhostsGzip"
183 [ "$ipv6Enabled" -gt 0 ] && outputFilterIPv6
="$addnhostsOutputFilterIPv6"
184 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
185 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
186 rm -f "$serversFile" "$serversCache" "$serversGzip"
187 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
190 outputFilter
="$dnsmasqOutputFilter"
191 outputFile
="$dnsmasqFile"
192 outputCache
="$dnsmasqCache"
193 outputGzip
="$dnsmasqGzip"
194 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
195 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
196 rm -f "$serversFile" "$serversCache" "$serversGzip"
197 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
200 outputFilter
="$ipsetOutputFilter"
201 outputFile
="$ipsetFile"
202 outputCache
="$ipsetCache"
203 outputGzip
="$ipsetGzip"
204 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
205 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
206 rm -f "$serversFile" "$serversCache" "$serversGzip"
207 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
210 outputFilter
="$serversOutputFilter"
211 outputFile
="$serversFile"
212 outputCache
="$serversCache"
213 outputGzip
="$serversGzip"
214 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
215 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
216 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
217 rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
220 outputFilter
="$unboundOutputFilter"
221 outputFile
="$unboundFile"
222 outputCache
="$unboundCache"
223 outputGzip
="$unboundGzip"
224 rm -f "$addnhostsFile" "$addnhostsCache" "$addnhostsGzip"
225 rm -f "$dnsmasqFile" "$dnsmasqCache" "$dnsmasqGzip"
226 rm -f "$ipsetFile" "$ipsetCache" "$ipsetGzip"
227 rm -f "$serversFile" "$serversCache" "$serversGzip"
230 if [ -z "${verbosity##*[!0-9]*}" ] ||
[ "$verbosity" -lt 0 ] ||
[ "$verbosity" -gt 2 ]; then
233 .
/lib
/functions
/network.sh
234 .
/usr
/share
/libubox
/jshn.sh
235 # Prefer curl because it supports the file:// scheme.
236 if [ -x /usr
/bin
/curl
]; then
237 dl_command
="curl --insecure --retry $curlRetry --connect-timeout $dlTimeout --silent"
239 elif wget
--version 2>/dev
/null |
grep -q "+https"; then
240 dl_command
="wget --no-check-certificate --timeout $dlTimeout -q"
243 dl_command
="uclient-fetch --no-check-certificate --timeout $dlTimeout -q"
246 led
="${led:+/sys/class/leds/$led}"
247 if curl
--version 2>/dev
/null |
grep -q "https" \
248 || wget
--version 2>/dev
/null |
grep -q "+https" \
249 ||
grep -q "libustream-mbedtls" /usr
/lib
/opkg
/status \
250 ||
grep -q "libustream-openssl" /usr
/lib
/opkg
/status \
251 ||
grep -q "libustream-wolfssl" /usr
/lib
/opkg
/status
; then
254 unset is_ssl_supported
261 if [ "$debug" -ne 0 ]; then
262 exec 1>>/tmp
/simple-adblock.log
267 if [ "$serviceEnabled" -eq 0 ]; then
270 output
"$packageName is currently disabled.\\n"
271 output
"Run the following commands before starting service again:\\n"
272 output
"uci set ${packageName}.config.enabled='1'; uci commit $packageName;\\n"
279 dnsmasq.addnhosts | dnsmasq.conf | dnsmasq.ipset | dnsmasq.servers
)
280 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-IDN' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'IDN'; then
292 if dnsmasq
-v 2>/dev
/null |
grep -q 'no-ipset' ||
! dnsmasq
-v 2>/dev
/null |
grep -q -w 'ipset'; then
293 output
"$_ERROR_: DNSMASQ ipset support is enabled in $packageName, but DNSMASQ is either not installed or installed DNSMASQ does not support ipsets!\\n"
294 targetDNS
='dnsmasq.servers'
296 if ! ipset
help hash:net
>/dev
/null
2>&1; then
297 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"
298 targetDNS
='dnsmasq.servers'
303 [ ! -d "${outputFile%/*}" ] && mkdir
-p "${outputFile%/*}"
304 [ ! -d "${outputCache%/*}" ] && mkdir
-p "${outputFile%/*}"
305 [ ! -d "${outputGzip%/*}" ] && mkdir
-p "${outputFile%/*}"
306 cacheOps
'testGzip' && return 0
307 network_flush_cache
; network_find_wan wan_if
; network_get_gateway wan_gw
"$wan_if";
308 [ -n "$wan_gw" ] && return 0
309 output
"$_ERROR_: $serviceName failed to discover WAN gateway.\\n"; return 1;
313 local cfg
="$1" param
="$2"
316 if [ "$(uci -q get dhcp."$cfg".serversfile)" = "$serversFile" ]; then
317 uci
-q del dhcp.
"$cfg".serversfile
319 if ! uci
-q get dhcp.
"$cfg".addnhosts |
grep -q "$addnhostsFile"; then
320 uci add_list dhcp.
"$cfg".addnhosts
="$addnhostsFile"
323 dnsmasq.conf|dnsmasq.ipset|unbound.adb_list|cleanup
)
324 uci
-q del_list dhcp.
"$cfg".addnhosts
="$addnhostsFile"
325 if [ "$(uci -q get dhcp."$cfg".serversfile)" = "$serversFile" ]; then
326 uci
-q del dhcp.
"$cfg".serversfile
330 uci
-q del_list dhcp.
"$cfg".addnhosts
="$addnhostsFile"
331 if [ "$(uci -q get dhcp."$cfg".serversfile)" != "$serversFile" ]; then
332 uci
set dhcp.
"$cfg".serversfile
="$serversFile"
339 local param output_text i
342 if [ ! -s "$outputFile" ]; then
343 tmpfs
set status
"statusFail"
344 tmpfs add error
"errorOutputFileCreate"
345 output
"$_ERROR_: $(getErrorText 'errorOutputFileCreate')!\\n"
350 if [ "$dnsInstance" = "*" ]; then
351 config_foreach dnsmasqOps
'dnsmasq' "$targetDNS"
352 elif [ -n "$dnsInstance" ]; then
353 for i
in $dnsInstance; do
354 dnsmasqOps
"@dnsmasq[$i]" "$targetDNS"
359 dnsmasq.addnhosts|dnsmasq.servers
)
361 output_text
='Reloading DNSMASQ'
363 dnsmasq.conf|dnsmasq.ipset
)
364 param
=dnsmasq_restart
365 output_text
='Restarting DNSMASQ'
368 param
=unbound_restart
369 output_text
='Restarting Unbound'
373 if [ -n "$(uci changes dhcp)" ]; then
375 if [ "$param" = 'unbound_restart' ]; then
376 param
='dnsmasq_restart; unbound_restart;'
377 output_text
='Restarting Unbound/DNSMASQ'
379 param
=dnsmasq_restart
380 output_text
='Restarting DNSMASQ'
383 output
1 "$output_text "
384 output
2 "$output_text "
385 tmpfs
set message
"$output_text"
386 if eval "$param"; then
387 tmpfs
set status
"statusSuccess"
392 tmpfs
set status
"statusFail"
393 tmpfs add error
"errorDNSReload"
394 output
"$_ERROR_: $(getErrorText 'errorDNSReload')!\\n"
400 dnsmasq.addnhosts | dnsmasq.servers
)
403 dnsmasq.conf | dnsmasq.ipset
)
404 param
=dnsmasq_restart
407 param
=unbound_restart
410 if [ -n "$(uci changes dhcp)" ]; then
412 if [ "$param" = 'unbound_restart' ]; then
413 param
='dnsmasq_restart; unbound_restart;'
415 param
=dnsmasq_restart
423 dnsmasq.addnhosts | dnsmasq.conf | dnsmasq.ipset | dnsmasq.servers
)
424 param
=dnsmasq_restart
427 param
=unbound_restart
437 local action
="$1" instance
="$2" value
="$3"
438 local status message error stats
439 local readReload readRestart curReload curRestart ret
440 if [ -s "$jsonFile" ]; then
441 status
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['status']")"
442 message
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['message']")"
443 error
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['error']")"
444 stats
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['stats']")"
445 readReload
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['reload']")"
446 readRestart
="$(jsonfilter -i $jsonFile -l1 -e "@
['data']['restart']")"
452 printf "%b" "$status"; return;;
454 printf "%b" "$message"; return;;
456 printf "%b" "$error"; return;;
458 printf "%b" "$stats"; return;;
460 curReload
="$parallelDL $debug $dlTimeout $whitelist_domains $blacklist_domains $whitelist_domains_urls $blacklist_domains_urls $blacklist_hosts_urls $targetDNS"
461 curRestart
="$compressedCache $forceDNS $led"
462 if [ ! -s "$jsonFile" ]; then
464 elif [ "$curReload" != "$readReload" ]; then
466 elif [ "$curRestart" != "$readRestart" ]; then
476 [ -n "$status" ] && status
="$status $value" || status
="$value";;
478 [ -n "$message" ] && message
="$message $value" || message
="$value";;
480 [ -n "$error" ] && error
="$error $value" || error
="$value";;
482 [ -n "$stats" ] && stats
="$stats $value" || stats
="$value";;
502 unset readReload
; unset readRestart
;;
516 readReload
="$parallelDL $debug $dlTimeout $whitelist_domains $blacklist_domains $whitelist_domains_urls $blacklist_domains_urls $blacklist_hosts_urls $targetDNS"
517 readRestart
="$compressedCache $forceDNS $led"
523 json_add_object
'data'
524 json_add_string version
"$PKG_VERSION"
525 json_add_string status
"$status"
526 json_add_string message
"$message"
527 json_add_string error
"$error"
528 json_add_string stats
"$stats"
529 json_add_string reload
"$readReload"
530 json_add_string restart
"$readRestart"
532 json_dump
> "$jsonFile"
540 [ -s "$outputFile" ] && { mv -f "$outputFile" "$outputCache"; true
> "$outputFile"; } >/dev
/null
2>/dev
/null
544 [ -s "$outputCache" ] && mv "$outputCache" "$outputFile" >/dev
/null
2>/dev
/null
548 [ -s "$outputCache" ]
552 [ -s "$outputGzip" ] && gzip -t -c "$outputGzip"
556 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
557 if gzip < "$outputFile" > "$R_TMP"; then
558 if mv "$R_TMP" "$outputGzip"; then
569 expand|unpack|expandGzip|unpackGzip
)
570 [ -s "$outputGzip" ] && gzip -dc < "$outputGzip" > "$outputCache"
577 local action
="$1" param
="$2" _restart
579 reload
) /etc
/init.d
/firewall reload
>/dev
/null
2>&1;;
580 restart
) /etc
/init.d
/firewall restart
>/dev
/null
2>&1;;
583 dns_redirect
) uci
-q del firewall.simple_adblock_dns_redirect
;;
584 ipset
) uci
-q del firewall.simple_adblock_ipset
585 uci
-q del firewall.simple_adblock_ipset_rule
;;
587 uci
-q del firewall.simple_adblock_dns_redirect
588 uci
-q del firewall.simple_adblock_ipset
589 uci
-q del firewall.simple_adblock_ipset_rule
596 if ! uci
-q get firewall.simple_adblock_dns_redirect
>/dev
/null
; then
597 uci
-q set firewall.simple_adblock_dns_redirect
=redirect
598 uci
-q set firewall.simple_adblock_dns_redirect.name
=simple_adblock_dns_hijack
599 uci
-q set firewall.simple_adblock_dns_redirect.target
=DNAT
600 uci
-q set firewall.simple_adblock_dns_redirect.src
=lan
601 uci
-q set firewall.simple_adblock_dns_redirect.proto
=tcpudp
602 uci
-q set firewall.simple_adblock_dns_redirect.src_dport
=53
603 uci
-q set firewall.simple_adblock_dns_redirect.dest_port
=53
607 if ! uci
-q get firewall.simple_adblock_ipset
>/dev
/null
; then
608 uci
-q set firewall.simple_adblock_ipset
=ipset
609 uci
-q set firewall.simple_adblock_ipset.name
=adb
610 uci
-q set firewall.simple_adblock_ipset.match
=dest_net
611 uci
-q set firewall.simple_adblock_ipset.storage
=hash
612 uci
-q set firewall.simple_adblock_ipset.enabled
=1
615 if ! uci
-q get firewall.simple_adblock_ipset_rule
>/dev
/null
; then
616 uci
-q set firewall.simple_adblock_ipset_rule
=rule
617 uci
-q set firewall.simple_adblock_ipset_rule.name
=simple_adblock_ipset_rule
618 uci
-q set firewall.simple_adblock_ipset_rule.ipset
=adb
619 uci
-q set firewall.simple_adblock_ipset_rule.src
=lan
620 uci
-q set firewall.simple_adblock_ipset_rule.dest
='*'
621 uci
-q set firewall.simple_adblock_ipset_rule.proto
=tcpudp
622 uci
-q set firewall.simple_adblock_ipset_rule.target
=REJECT
623 uci
-q set firewall.simple_adblock_ipset_rule.enabled
=1
627 if ! uci
-q get firewall.simple_adblock_dns_redirect
>/dev
/null
; then
628 uci
-q set firewall.simple_adblock_dns_redirect
=redirect
629 uci
-q set firewall.simple_adblock_dns_redirect.name
=simple_adblock_dns_hijack
630 uci
-q set firewall.simple_adblock_dns_redirect.target
=DNAT
631 uci
-q set firewall.simple_adblock_dns_redirect.src
=lan
632 uci
-q set firewall.simple_adblock_dns_redirect.proto
=tcpudp
633 uci
-q set firewall.simple_adblock_dns_redirect.src_dport
=53
634 uci
-q set firewall.simple_adblock_dns_redirect.dest_port
=53
636 if ! uci
-q get firewall.simple_adblock_ipset
>/dev
/null
; then
637 uci
-q set firewall.simple_adblock_ipset
=ipset
638 uci
-q set firewall.simple_adblock_ipset.name
=adb
639 uci
-q set firewall.simple_adblock_ipset.match
=dest_net
640 uci
-q set firewall.simple_adblock_ipset.storage
=hash
641 uci
-q set firewall.simple_adblock_ipset.enabled
=1
644 if ! uci
-q get firewall.simple_adblock_ipset_rule
>/dev
/null
; then
645 uci
-q set firewall.simple_adblock_ipset_rule
=rule
646 uci
-q set firewall.simple_adblock_ipset_rule.name
=simple_adblock_ipset_rule
647 uci
-q set firewall.simple_adblock_ipset_rule.ipset
=adb
648 uci
-q set firewall.simple_adblock_ipset_rule.src
=lan
649 uci
-q set firewall.simple_adblock_ipset_rule.dest
='*'
650 uci
-q set firewall.simple_adblock_ipset_rule.proto
=tcpudp
651 uci
-q set firewall.simple_adblock_ipset_rule.target
=REJECT
652 uci
-q set firewall.simple_adblock_ipset_rule.enabled
=1
657 if [ -n "$(uci changes firewall)" ]; then
658 uci
-q commit firewall
659 if [ -z "$_restart" ]; then
668 local label
type D_TMP R_TMP
669 if [ -z "$1" ] ||
[ -z "$2" ] ||
[ -z "$3" ]; then return 1; fi
670 label
="${1##*//}"; label
="${label%%/*}";
671 if [ "$2" = 'hosts' ]; then
672 label
="Hosts: $label"; filter
="$hostsFilter";
674 label
="Domains: $label"; filter
="$domainsFilter";
676 if [ "$3" = 'blocked' ]; then
677 type='Blocked'; D_TMP
="$B_TMP";
679 type='Allowed'; D_TMP
="$A_TMP";
681 if [ "${1:0:5}" == "https" ] && [ -z "$is_ssl_supported" ]; then
683 output
2 "[DL] $type $label $__FAIL__\\n"
684 echo "errorNoSSLSupport|${1}" >> "$sharedMemoryError"
687 while [ -z "$R_TMP" ] ||
[ -e "$R_TMP" ]; do
688 R_TMP
="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
690 if ! $dl_command "$1" $dl_flag "$R_TMP" 2>/dev
/null ||
[ ! -s "$R_TMP" ]; then
692 output
2 "[DL] $type $label $__FAIL__\\n"
693 echo "errorDownloadingList|${1}" >> "$sharedMemoryError"
695 sed -i "$filter" "$R_TMP"
696 if [ ! -s "$R_TMP" ]; then
698 output
2 "[DL] $type $label $__FAIL__\\n"
699 echo "errorParsingList|${1}" >> "$sharedMemoryError"
701 cat "${R_TMP}" >> "$D_TMP"
703 output
2 "[DL] $type $label $__OK__\\n"
711 local hf w_filter j
=0 R_TMP
713 tmpfs
set message
"${messageDownloading}..."
714 tmpfs
set status
"statusDownloading"
716 rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
717 if [ "$(awk '/^MemFree/ {print int($2/1000)}' "/proc
/meminfo
")" -lt 32 ]; then
718 output
3 'Low free memory, restarting resolver... '
719 if dnsOps
'quiet'; then
725 touch $A_TMP; touch $B_TMP;
726 output
1 'Downloading lists '
727 rm -f "$sharedMemoryError"
728 if [ -n "$blacklist_hosts_urls" ]; then
729 for hf
in ${blacklist_hosts_urls}; do
730 if [ "$parallelDL" -gt 0 ]; then
731 process_url
"$hf" 'hosts' 'blocked' &
733 process_url
"$hf" 'hosts' 'blocked'
737 if [ -n "$blacklist_domains_urls" ]; then
738 for hf
in ${blacklist_domains_urls}; do
739 if [ "$parallelDL" -gt 0 ]; then
740 process_url
"$hf" 'domains' 'blocked' &
742 process_url
"$hf" 'domains' 'blocked'
746 if [ -n "$whitelist_domains_urls" ]; then
747 for hf
in ${whitelist_domains_urls}; do
748 if [ "$parallelDL" -gt 0 ]; then
749 process_url
"$hf" 'domains' 'allowed' &
751 process_url
"$hf" 'domains' 'allowed'
757 if [ -s "$sharedMemoryError" ]; then
758 while IFS
= read -r line
; do
759 tmpfs add error
"$line"
760 done < "$sharedMemoryError"
761 rm -f "$sharedMemoryError"
764 [ -n "$blacklist_domains" ] && for hf
in ${blacklist_domains}; do echo "$hf" |
sed "$domainsFilter" >> $B_TMP; done
765 whitelist_domains
="${whitelist_domains}
767 [ -n "$whitelist_domains" ] && for hf
in ${whitelist_domains}; do hf="$(echo "$hf" | sed 's/\./\\./g')"; w_filter="$w_filter/^${hf}$/d;/\\.${hf}$
/d
;"; done
769 [ ! -s "$B_TMP" ] && return 1
771 output 1 'Processing downloads '
772 output 2 'Sorting combined list '
773 tmpfs set message "$messageProcessing: sorting combined list
"
774 if [ "$allowIDN" -gt 0 ]; then
775 if sort -u "$B_TMP" > "$A_TMP"; then
779 tmpfs add error "errorSorting
"
782 if sort -u "$B_TMP" | grep -E -v '[^a-zA-Z0-9=/.-]' > "$A_TMP"; then
786 tmpfs add error "errorSorting
"
790 if [ "$targetDNS" = 'dnsmasq.conf' ] || \
791 [ "$targetDNS" = 'dnsmasq.ipset' ] || \
792 [ "$targetDNS" = 'dnsmasq.servers' ] || \
793 [ "$targetDNS" = 'unbound.adb_list' ]; then
794 # TLD optimization written by Dirk Brenken (dev@brenken.org)
795 output 2 'Optimizing combined list '
796 tmpfs set message "$messageProcessing: optimizing combined list
"
797 # sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/' is actually slower than awk
798 if awk -F ".
" '{for(f=NF;f>1;f--)printf "%s.
",$f;print $1}' "$A_TMP" > "$B_TMP"; then
799 if sort "$B_TMP" > "$A_TMP"; then
800 if awk '{if(NR=1){tld=$NF};while(getline){if($NF!~tld"\\.
"){print tld;tld=$NF}}print tld}' "$A_TMP" > "$B_TMP"; then
801 if awk -F ".
" '{for(f=NF;f>1;f--)printf "%s.
",$f;print $1}' "$B_TMP" > "$A_TMP"; then
802 if sort -u "$A_TMP" > "$B_TMP"; then
806 tmpfs add error "errorOptimization
"
811 tmpfs add error "errorOptimization
"
815 tmpfs add error "errorOptimization
"
820 tmpfs add error "errorOptimization
"
824 tmpfs add error "errorOptimization
"
831 output 2 'Whitelisting domains '
832 tmpfs set message "$messageProcessing: whitelisting domains
"
833 if sed -i "$w_filter" "$B_TMP"; then
837 tmpfs add error "errorWhitelistProcessing
"
840 output 2 'Formatting merged file '
841 tmpfs set message "$messageProcessing: formatting merged
file"
842 if [ -z "$outputFilterIPv6" ]; then
843 if sed "$outputFilter" "$B_TMP" > "$A_TMP"; then
847 tmpfs add error "errorDataFileFormatting
"
852 if sed "$outputFilter" "$B_TMP" > "$A_TMP" && \
853 sed "$outputFilterIPv6" "$B_TMP" >> "$A_TMP"; then
857 tmpfs add error "errorDataFileFormatting
"
865 output 2 'Creating DNSMASQ addnhosts file '
866 tmpfs set message "$messageProcessing: creating DNSMASQ addnhosts
file"
869 output 2 'Creating DNSMASQ config file '
870 tmpfs set message "$messageProcessing: creating DNSMASQ config
file"
873 output 2 'Creating DNSMASQ ipset file '
874 tmpfs set message "$messageProcessing: creating DNSMASQ ipset
file"
877 output 2 'Creating DNSMASQ servers file '
878 tmpfs set message "$messageProcessing: creating DNSMASQ servers
file"
881 output 2 'Creating Unbound adb_list file '
882 tmpfs set message "$messageProcessing: creating Unbound adb_list
file"
885 if mv "$A_TMP" "$outputFile"; then
889 tmpfs add error "errorMovingDataFile
"
891 if [ "$compressedCache" -gt 0 ]; then
892 output 2 'Creating compressed cache '
893 tmpfs set message "$messageProcessing: creating compressed cache
"
894 if cacheOps 'createGzip'; then
898 tmpfs add error "errorCreatingCompressedCache
"
903 output 2 'Removing temporary files '
904 tmpfs set message "$messageProcessing: removing temporary files
"
905 rm -f "/tmp
/${packageName}_tmp.
*" "$A_TMP" "$B_TMP" "$outputCache" || j=1
906 if [ $j -eq 0 ]; then
910 tmpfs add error "errorRemovingTempFiles
"
920 rc_procd start_service 'on_boot' && rc_procd service_triggers
925 is_enabled 'on_start' || return 1
926 local action status error message stats c
927 if ! create_lock; then
928 output 3 "$serviceName: another instance is starting up
"; output_fail
932 status="$
(tmpfs get status
)"
933 error="$
(tmpfs get error
)"
934 message="$
(tmpfs get message
)"
935 stats="$
(tmpfs get stats
)"
936 action="$
(tmpfs get triggers
)"
938 if [ "$action" = 'on_boot' ] || [ "$1" = 'on_boot' ]; then
939 if cacheOps 'testGzip' || cacheOps 'test'; then
944 elif [ "$action" = 'download' ] || [ "$1" = 'download' ] || [ -n "$error" ]; then
946 elif [ ! -s "$outputFile" ]; then
947 if cacheOps 'testGzip' || cacheOps 'test'; then
952 elif [ "$action" = 'restart' ] || [ "$1" = 'restart' ]; then
954 elif [ -s "$outputFile" ] && [ "$status" = "statusSuccess
" ] && [ -z "$error" ]; then
955 [ "$1" != 'hotplug' ] && showstatus
964 if is_chaos_calmer || ! is_ipset_procd; then
965 if [ "$forceDNS" -ne 0 ]; then
966 fw3Ops 'insert' 'dns_redirect'
968 fw3Ops 'remove' 'dns_redirect'
970 if [ "$targetDNS" = 'dnsmasq.ipset' ]; then
971 fw3Ops 'insert' 'ipset'
973 fw3Ops 'remove' 'ipset'
975 procd_open_instance 'main'
976 procd_set_param command /bin/true
977 procd_set_param stdout 1
978 procd_set_param stderr 1
981 procd_open_instance 'main'
982 procd_set_param command /bin/true
983 procd_set_param stdout 1
984 procd_set_param stderr 1
986 json_add_array firewall
987 if [ "$forceDNS" -ne 0 ]; then
989 json_add_string type redirect
990 json_add_string name simple_adblock_dns_redirect
991 json_add_string target DNAT
992 json_add_string src lan
993 json_add_string proto tcpudp
994 json_add_string src_dport 53
995 json_add_string dest_port 53
996 json_add_string reflection 0
999 if [ "$targetDNS" = 'dnsmasq.ipset' ]; then
1001 json_add_string type ipset
1002 json_add_string name adb
1003 json_add_string match dest_net
1004 json_add_string storage hash
1005 json_add_string enabled 1
1008 json_add_string type rule
1009 json_add_string name simple_adblock_ipset_rule
1010 json_add_string ipset adb
1011 json_add_string src lan
1012 json_add_string dest '*'
1013 json_add_string proto tcpudp
1014 json_add_string target REJECT
1015 json_add_string enabled 1
1020 procd_close_instance
1023 if [ "$action" = 'restore' ]; then
1024 output 0 "Starting
$serviceName...
"
1025 output 3 "Starting
$serviceName...
\\n
"
1026 tmpfs set status "statusStarting
"
1027 if cacheOps 'testGzip' && ! cacheOps 'test' && [ ! -s "$outputFile" ]; then
1028 output 3 'Found compressed cache file, unpacking it '
1029 tmpfs set message 'found compressed cache file, unpacking it.'
1030 if cacheOps 'unpackGzip'; then
1034 tmpfs add error "errorRestoreCompressedCache
"
1035 output "$_ERROR_: $
(getErrorText
'errorRestoreCompressedCache')!\\n
"
1039 if cacheOps 'test' && [ ! -s "$outputFile" ]; then
1040 output 3 'Found cache file, reusing it '
1041 tmpfs set message 'found cache file, reusing it.'
1042 if cacheOps 'restore'; then
1047 tmpfs add error "errorRestoreCache
"
1048 output "$_ERROR_: $
(getErrorText
'errorRestoreCache')!\\n
"
1055 if [ -s "$outputFile" ] || cacheOps 'test' || cacheOps 'testGzip'; then
1056 output 0 "Force-reloading
$serviceName...
"
1057 output 3 "Force-reloading
$serviceName...
\\n
"
1058 tmpfs set status "statusForceReloading
"
1060 output 0 "Starting
$serviceName...
"
1061 output 3 "Starting
$serviceName...
\\n
"
1062 tmpfs set status "statusStarting
"
1068 output 0 "Restarting
$serviceName...
"
1069 output 3 "Restarting
$serviceName...
\\n
"
1070 tmpfs set status "statusRestarting
"
1074 output 0 "Starting
$serviceName...
"
1075 output 3 "Starting
$serviceName...
\\n
"
1076 tmpfs set status "statusStarting
"
1080 if [ -s "$outputFile" ] && [ "$
(tmpfs get status
)" != "statusFail
" ]; then
1081 output 0 "$__OK__\\n
";
1083 tmpfs set status "statusSuccess
"
1084 c="$
(wc -l < "$outputFile")"
1085 tmpfs set stats "$serviceName is blocking
$c domains
(with
${targetDNS})"
1088 output 0 "$__FAIL__\\n
";
1089 tmpfs set status "statusFail
"
1090 tmpfs add error "errorOhSnap
"
1096 service_started() { is_ipset_procd && procd_set_config_changed firewall; }
1097 service_stopped() { is_ipset_procd && procd_set_config_changed firewall; }
1098 restart_service() { rc_procd start_service 'restart'; }
1099 reload_service() { restart_service; }
1100 restart() { restart_service; }
1101 reload() { restart_service; }
1102 dl() { rc_procd start_service 'download'; }
1104 rm -f "$addnhostsCache" "$addnhostsGzip"
1105 rm -f "$dnsmasqCache" "$dnsmasqGzip"
1106 rm -f "$ipsetCache" "$ipsetGzip"
1107 rm -f "$serversCache" "$serversGzip"
1108 rm -f "$unboundCache" "$unboundGzip"
1110 config_foreach dnsmasqOps 'dnsmasq' 'cleanup'
1111 uci -q commit 'dhcp'
1115 show() { showstatus; }
1116 status_service() { showstatus; }
1118 local status="$
(tmpfs get status
)"
1119 local message="$
(tmpfs get message
)"
1120 local error="$
(tmpfs get error
)"
1121 local stats="$
(tmpfs get stats
)"
1123 if [ "$status" = "statusSuccess
" ]; then
1124 output "$stats "; output_okn;
1126 [ -n "$status" ] && status="$
(getStatusText
"$status")"
1127 if [ -n "$status" ] && [ -n "$message" ]; then
1128 status="${status}: $message"
1130 [ -n "$status" ] && output "$serviceName $status\\n
"
1132 if [ -n "$error" ]; then
1137 errorDownloadingList|errorParsingList)
1138 output "$_ERROR_: $
(getErrorText
"$c") $url!\\n
";;
1140 output "$_ERROR_: $
(getErrorText
"$c")!\\n
";;
1149 fw3Ops 'remove' 'all'
1150 if [ -s "$outputFile" ]; then
1151 output "Stopping
$serviceName...
"
1153 if dnsOps 'on_stop'; then
1155 output 0 "$__OK__\\n
"; output_okn;
1156 tmpfs set status "statusStopped
"
1159 output 0 "$__FAIL__\\n
"; output_fail;
1160 tmpfs set status "statusFail
"
1161 tmpfs add error "errorStopping
"
1162 output "$_ERROR_: $
(getErrorText
'errorStopping')!\\n
"
1167 service_triggers() {
1168 procd_add_reload_trigger 'simple-adblock'
1174 local c="$
(grep -c "$string" "$outputFile")"
1175 if [ ! -s "$outputFile" ]; then
1176 echo "No blacklist
('$outputFile') found.
"
1177 elif [ -z "$string" ]; then
1178 echo "Usage
: /etc
/init.d
/${packageName} check string
"
1179 elif [ "$c" -gt 0 ]; then
1180 if [ "$c" -gt 1 ]; then
1181 echo "Found
$c matches
for '$string' in '$outputFile':"
1183 echo "Found
1 match
for '$string' in '$outputFile':"
1185 case "$targetDNS" in
1187 grep "$string" "$outputFile" | sed 's|^127.0.0.1 ||;s|^:: ||;';;
1189 grep "$string" "$outputFile" | sed 's|local=/||;s|/$||;';;
1191 grep "$string" "$outputFile" | sed 's|ipset=/||;s|/adb$||;';;
1193 grep "$string" "$outputFile" | sed 's|server=/||;s|/$||;';;
1195 grep "$string" "$outputFile" | sed 's|^local-zone: "||
;s|
" static$||;';;
1198 echo "The
$string is not found
in current blacklist
('$outputFile').
"
1207 for i
in $blacklist_domains_urls; do
1208 [ "${i//melmac}" != "$i" ] && continue
1209 if $dl_command "$i" $dl_flag /tmp
/sast
2>/dev
/null
&& [ -s /tmp
/sast
]; then
1210 echo "# File size: $(du -sh /tmp/sast | awk '{print $1}')"
1211 if compare_versions
"$(du -sk /tmp/sast)" "500"; then
1212 echo "# blocklist too big for most routers"
1213 elif compare_versions
"$(du -sk /tmp/sast)" "100"; then
1214 echo "# blocklist may be too big for some routers"
1217 echo " list blacklist_domains_url '$i'"
1220 echo "# site was down on last check"
1221 echo "# list blacklist_domains_url '$i'"
1226 for i
in $blacklist_hosts_urls; do
1227 if $dl_command "$i" $dl_flag /tmp
/sast
2>/dev
/null
&& [ -s /tmp
/sast
]; then
1228 echo "# File size: $(du -sh /tmp/sast | awk '{print $1}')"
1229 if compare_versions
"$(du -sk /tmp/sast)" "500"; then
1230 echo "# blocklist too big for most routers"
1231 elif compare_versions
"$(du -sk /tmp/sast)" "100"; then
1232 echo "# blocklist may be too big for some routers"
1235 echo " list blacklist_hosts_url '$i'"
1238 echo "# site was down on last check"
1239 echo "# list blacklist_hosts_url '$i'"