banip: release 0.9.5-1
[feed/packages.git] / net / banip / files / banip-service.sh
1 #!/bin/sh
2 # banIP main service script - ban incoming and outgoing IPs via named nftables Sets
3 # Copyright (c) 2018-2024 Dirk Brenken (dev@brenken.org)
4 # This is free software, licensed under the GNU General Public License v3.
5
6 # (s)hellcheck exceptions
7 # shellcheck disable=all
8
9 ban_action="${1}"
10 ban_starttime="$(date "+%s")"
11 ban_funlib="/usr/lib/banip-functions.sh"
12 [ -z "${ban_ver}" ] && . "${ban_funlib}"
13
14 # load config and set banIP environment
15 #
16 [ "${ban_action}" = "boot" ] && sleep "$(uci_get banip global ban_triggerdelay "20")"
17 f_conf
18 f_log "info" "start banIP processing (${ban_action})"
19 f_log "debug" "f_system ::: system: ${ban_sysver:-"n/a"}, version: ${ban_ver:-"n/a"}, memory: ${ban_memory:-"0"}, cpu_cores: ${ban_cores}"
20 f_genstatus "processing"
21 f_tmp
22 f_getfetch
23 f_getif
24 f_getdev
25 f_getuplink
26 f_mkdir "${ban_backupdir}"
27 f_mkfile "${ban_allowlist}"
28 f_mkfile "${ban_blocklist}"
29
30 # firewall check
31 #
32 if [ "${ban_action}" != "reload" ]; then
33 if [ -x "${ban_fw4cmd}" ]; then
34 cnt="0"
35 while [ "${cnt}" -lt "30" ] && ! /etc/init.d/firewall status >/dev/null 2>&1; do
36 cnt="$((cnt + 1))"
37 sleep 1
38 done
39 if ! /etc/init.d/firewall status >/dev/null 2>&1; then
40 f_log "err" "error in nft based firewall/fw4"
41 fi
42 else
43 f_log "err" "no nft based firewall/fw4"
44 fi
45 fi
46
47 # init banIP nftables namespace
48 #
49 if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list set inet banIP allowlistv4MAC >/dev/null 2>&1; then
50 if f_nftinit "${ban_tmpfile}".init.nft; then
51 f_log "info" "initialize banIP nftables namespace"
52 else
53 f_log "err" "can't initialize banIP nftables namespace"
54 fi
55 fi
56
57 # handle downloads
58 #
59 f_log "info" "start banIP download processes"
60 if [ "${ban_allowlistonly}" = "1" ]; then
61 ban_feed=""
62 else
63 f_getfeed
64 fi
65 [ "${ban_deduplicate}" = "1" ] && printf "\n" >"${ban_tmpfile}.deduplicate"
66
67 cnt="1"
68 for feed in allowlist ${ban_feed} blocklist; do
69 # local feeds (sequential processing)
70 #
71 if [ "${feed}" = "allowlist" ] || [ "${feed}" = "blocklist" ]; then
72 for proto in 4MAC 6MAC 4 6; do
73 [ "${feed}" = "blocklist" ] && wait
74 f_down "${feed}" "${proto}"
75 done
76 continue
77 fi
78
79 # external feeds (parallel processing on multicore hardware)
80 #
81 if ! json_select "${feed}" >/dev/null 2>&1; then
82 f_log "info" "remove unknown feed '${feed}'"
83 uci_remove_list banip global ban_feed "${feed}"
84 uci_commit "banip"
85 continue
86 fi
87 json_objects="url_4 rule_4 url_6 rule_6 flag"
88 for object in ${json_objects}; do
89 eval json_get_var feed_"${object}" '${object}' >/dev/null 2>&1
90 done
91 json_select ..
92
93 # skip incomplete feeds
94 #
95 if { { [ -n "${feed_url_4}" ] && [ -z "${feed_rule_4}" ]; } || { [ -z "${feed_url_4}" ] && [ -n "${feed_rule_4}" ]; }; } ||
96 { { [ -n "${feed_url_6}" ] && [ -z "${feed_rule_6}" ]; } || { [ -z "${feed_url_6}" ] && [ -n "${feed_rule_6}" ]; }; } ||
97 { [ -z "${feed_url_4}" ] && [ -z "${feed_rule_4}" ] && [ -z "${feed_url_6}" ] && [ -z "${feed_rule_6}" ]; }; then
98 f_log "info" "skip incomplete feed '${feed}'"
99 continue
100 fi
101
102 # handle IPv4/IPv6 feeds with a single download URL
103 #
104 if [ "${feed_url_4}" = "${feed_url_6}" ]; then
105 if [ "${ban_protov4}" = "1" ] && [ -n "${feed_url_4}" ] && [ -n "${feed_rule_4}" ]; then
106 (f_down "${feed}" "4" "${feed_url_4}" "${feed_rule_4}" "${feed_flag}") &
107 feed_url_6="local"
108 wait
109 fi
110 if [ "${ban_protov6}" = "1" ] && [ -n "${feed_url_6}" ] && [ -n "${feed_rule_6}" ]; then
111 (f_down "${feed}" "6" "${feed_url_6}" "${feed_rule_6}" "${feed_flag}") &
112 hold="$((cnt % ban_cores))"
113 [ "${hold}" = "0" ] && wait
114 cnt="$((cnt + 1))"
115 fi
116 continue
117 fi
118
119 # handle IPv4/IPv6 feeds with separate download URLs
120 #
121 if [ "${ban_protov4}" = "1" ] && [ -n "${feed_url_4}" ] && [ -n "${feed_rule_4}" ]; then
122 (f_down "${feed}" "4" "${feed_url_4}" "${feed_rule_4}" "${feed_flag}") &
123 hold="$((cnt % ban_cores))"
124 [ "${hold}" = "0" ] && wait
125 cnt="$((cnt + 1))"
126 fi
127 if [ "${ban_protov6}" = "1" ] && [ -n "${feed_url_6}" ] && [ -n "${feed_rule_6}" ]; then
128 (f_down "${feed}" "6" "${feed_url_6}" "${feed_rule_6}" "${feed_flag}") &
129 hold="$((cnt % ban_cores))"
130 [ "${hold}" = "0" ] && wait
131 cnt="$((cnt + 1))"
132 fi
133 done
134 wait
135 f_rmset
136 f_rmdir "${ban_tmpdir}"
137 f_genstatus "active"
138
139 # start domain lookup
140 #
141 f_log "info" "start banIP domain lookup"
142 cnt="1"
143 for list in allowlist blocklist; do
144 (f_lookup "${list}") &
145 hold="$((cnt % ban_cores))"
146 [ "${hold}" = "0" ] && wait
147 cnt="$((cnt + 1))"
148 done
149 wait
150
151 # end processing
152 #
153 if [ "${ban_mailnotification}" = "1" ] && [ -n "${ban_mailreceiver}" ] && [ -x "${ban_mailcmd}" ]; then
154 (
155 sleep 5
156 f_mail
157 ) &
158 fi
159 json_cleanup
160 rm -rf "${ban_lock}"
161
162 # start detached log service (infinite loop)
163 #
164 f_monitor