You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

671 lines
18 KiB

  1. #!/bin/sh
  2. # banIP - ban incoming and outgoing ip adresses/subnets via ipset
  3. # written by Dirk Brenken (dev@brenken.org)
  4. # This is free software, licensed under the GNU General Public License v3.
  5. # You should have received a copy of the GNU General Public License
  6. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  7. # set initial defaults
  8. #
  9. LC_ALL=C
  10. PATH="/usr/sbin:/usr/bin:/sbin:/bin"
  11. ban_ver="0.0.5"
  12. ban_sysver="unknown"
  13. ban_enabled=0
  14. ban_automatic="1"
  15. ban_iface=""
  16. ban_debug=0
  17. ban_maxqueue=8
  18. ban_fetchutil="uclient-fetch"
  19. ban_ipt="$(command -v iptables)"
  20. ban_ipt_save="$(command -v iptables-save)"
  21. ban_ipt_restore="$(command -v iptables-restore)"
  22. ban_ipt6="$(command -v ip6tables)"
  23. ban_ipt6_save="$(command -v ip6tables-save)"
  24. ban_ipt6_restore="$(command -v ip6tables-restore)"
  25. ban_ipset="$(command -v ipset)"
  26. ban_chain="banIP"
  27. ban_action="${1:-"start"}"
  28. ban_pidfile="/var/run/banip.pid"
  29. ban_rtfile="/tmp/ban_runtime.json"
  30. ban_setcnt=0
  31. ban_cnt=0
  32. ban_rc=0
  33. # load environment
  34. #
  35. f_envload()
  36. {
  37. local sys_call sys_desc sys_model
  38. # get system information
  39. #
  40. sys_call="$(ubus -S call system board 2>/dev/null)"
  41. if [ -n "${sys_call}" ]
  42. then
  43. sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')"
  44. sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')"
  45. ban_sysver="${sys_model}, ${sys_desc}"
  46. fi
  47. # parse 'global' and 'extra' section by callback
  48. #
  49. config_cb()
  50. {
  51. local type="${1}"
  52. if [ "${type}" = "banip" ]
  53. then
  54. option_cb()
  55. {
  56. local option="${1}"
  57. local value="${2}"
  58. eval "${option}=\"${value}\""
  59. }
  60. else
  61. reset_cb
  62. fi
  63. }
  64. # parse 'source' typed sections
  65. #
  66. parse_config()
  67. {
  68. local value opt section="${1}" options="ban_src ban_src_6 ban_src_rset ban_src_rset_6 ban_src_settype ban_src_ruletype ban_src_on ban_src_on_6 ban_src_cat"
  69. for opt in ${options}
  70. do
  71. config_get value "${section}" "${opt}"
  72. if [ -n "${value}" ]
  73. then
  74. eval "${opt}_${section}=\"${value}\""
  75. if [ "${opt}" = "ban_src" ]
  76. then
  77. eval "ban_sources=\"${ban_sources} ${section}\""
  78. elif [ "${opt}" = "ban_src_6" ]
  79. then
  80. eval "ban_sources=\"${ban_sources} ${section}_6\""
  81. fi
  82. fi
  83. done
  84. }
  85. # load config
  86. #
  87. config_load banip
  88. config_foreach parse_config source
  89. # create temp directory & files
  90. #
  91. f_temp
  92. # check status
  93. #
  94. if [ ${ban_enabled} -eq 0 ]
  95. then
  96. f_jsnup disabled
  97. f_ipset destroy
  98. f_rmtemp
  99. f_log "info" "banIP is currently disabled, please set ban_enabled to '1' to use this service"
  100. exit 0
  101. fi
  102. }
  103. # check environment
  104. #
  105. f_envcheck()
  106. {
  107. local ssl_lib
  108. # check fetch utility
  109. #
  110. case "${ban_fetchutil}" in
  111. uclient-fetch)
  112. if [ -f "/lib/libustream-ssl.so" ]
  113. then
  114. ban_fetchparm="${ban_fetchparm:-"--timeout=20 --no-check-certificate -O"}"
  115. ssl_lib="libustream-ssl"
  116. else
  117. ban_fetchparm="${ban_fetchparm:-"--timeout=20 -O"}"
  118. fi
  119. ;;
  120. wget)
  121. ban_fetchparm="${ban_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=20 --no-check-certificate -O"}"
  122. ssl_lib="built-in"
  123. ;;
  124. wget-nossl)
  125. ban_fetchparm="${ban_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=20 -O"}"
  126. ;;
  127. busybox)
  128. ban_fetchparm="${ban_fetchparm:-"-O"}"
  129. ;;
  130. curl)
  131. ban_fetchparm="${ban_fetchparm:-"--connect-timeout 20 --insecure -o"}"
  132. ssl_lib="built-in"
  133. ;;
  134. aria2c)
  135. ban_fetchparm="${ban_fetchparm:-"--timeout=20 --allow-overwrite=true --auto-file-renaming=false --check-certificate=false -o"}"
  136. ssl_lib="built-in"
  137. ;;
  138. esac
  139. ban_fetchutil="$(command -v "${ban_fetchutil}")"
  140. ban_fetchinfo="${ban_fetchutil:-"-"} (${ssl_lib:-"-"})"
  141. if [ ! -x "${ban_fetchutil}" ] || [ -z "${ban_fetchutil}" ] || [ -z "${ban_fetchparm}" ]
  142. then
  143. f_log "err" "download utility not found, please install 'uclient-fetch' with 'libustream-mbedtls' or the full 'wget' package"
  144. fi
  145. # get wan device and wan subnets
  146. #
  147. if [ "${ban_automatic}" = "1" ]
  148. then
  149. network_find_wan ban_iface
  150. if [ -z "${ban_iface}" ]
  151. then
  152. network_find_wan6 ban_iface
  153. fi
  154. fi
  155. network_get_device ban_dev "${ban_iface}"
  156. network_get_subnets ban_subnets "${ban_iface}"
  157. network_get_subnets6 ban_subnets6 "${ban_iface}"
  158. if [ -z "${ban_iface}" ] || [ -z "${ban_dev}" ]
  159. then
  160. f_log "err" "wan interface/device (${ban_iface:-"-"}/${ban_dev:-"-"}) not found, please please check your configuration"
  161. fi
  162. uci_set banip global ban_iface "${ban_iface}"
  163. uci_commit banip
  164. f_jsnup "running"
  165. f_log "info" "start banIP processing (${ban_action})"
  166. }
  167. # create temporary files and directories
  168. #
  169. f_temp()
  170. {
  171. if [ -z "${ban_tmpdir}" ]
  172. then
  173. ban_tmpdir="$(mktemp -p /tmp -d)"
  174. ban_tmpload="$(mktemp -p ${ban_tmpdir} -tu)"
  175. ban_tmpfile="$(mktemp -p ${ban_tmpdir} -tu)"
  176. fi
  177. if [ ! -s "${ban_pidfile}" ]
  178. then
  179. printf '%s' "${$}" > "${ban_pidfile}"
  180. fi
  181. }
  182. # remove temporary files and directories
  183. #
  184. f_rmtemp()
  185. {
  186. if [ -d "${ban_tmpdir}" ]
  187. then
  188. rm -rf "${ban_tmpdir}"
  189. fi
  190. > "${ban_pidfile}"
  191. }
  192. # iptables rules engine
  193. #
  194. f_iptrule()
  195. {
  196. local rc timeout="-w 5" action="${1}" rule="${2}"
  197. if [ "${src_name##*_}" = "6" ]
  198. then
  199. rc="$("${ban_ipt6}" "${timeout}" -C ${rule} 2>/dev/null; printf '%u' ${?})"
  200. if ([ ${rc} -ne 0 ] && ([ "${action}" = "-A" ] || [ "${action}" = "-I" ])) \
  201. || ([ ${rc} -eq 0 ] && [ "${action}" = "-D" ])
  202. then
  203. "${ban_ipt6}" "${timeout}" "${action}" ${rule}
  204. fi
  205. else
  206. rc="$("${ban_ipt}" "${timeout}" -C ${rule} 2>/dev/null; printf '%u' ${?})"
  207. if ([ ${rc} -ne 0 ] && ([ "${action}" = "-A" ] || [ "${action}" = "-I" ])) \
  208. || ([ ${rc} -eq 0 ] && [ "${action}" = "-D" ])
  209. then
  210. "${ban_ipt}" "${timeout}" "${action}" ${rule}
  211. fi
  212. fi
  213. }
  214. # remove/add iptables rules
  215. #
  216. f_iptadd()
  217. {
  218. local rm="${1}"
  219. f_iptrule "-D" "${ban_chain} -i ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}"
  220. f_iptrule "-D" "${ban_chain} -o ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}"
  221. if [ -z "${rm}" ] && [ ${cnt} -gt 0 ]
  222. then
  223. if [ "${src_ruletype}" != "dst" ]
  224. then
  225. if [ "${src_name##*_}" = "6" ]
  226. then
  227. # dummy, special IPv6 rules
  228. /bin/true
  229. else
  230. f_iptrule "-I" "${wan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN"
  231. fi
  232. f_iptrule "-A" "${wan_input} -j ${ban_chain}"
  233. f_iptrule "-A" "${wan_forward} -j ${ban_chain}"
  234. f_iptrule "${action:-"-A"}" "${ban_chain} -i ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}"
  235. fi
  236. if [ "${src_ruletype}" != "src" ]
  237. then
  238. if [ "${src_name##*_}" = "6" ]
  239. then
  240. # dummy, special IPv6 rules
  241. /bin/true
  242. else
  243. f_iptrule "-I" "${lan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN"
  244. fi
  245. f_iptrule "-A" "${lan_input} -j ${ban_chain}"
  246. f_iptrule "-A" "${lan_forward} -j ${ban_chain}"
  247. f_iptrule "${action:-"-A"}" "${ban_chain} -o ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}"
  248. fi
  249. else
  250. if [ -n "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ]
  251. then
  252. "${ban_ipset}" destroy "${src_name}"
  253. fi
  254. fi
  255. }
  256. # ipset/iptables actions
  257. #
  258. f_ipset()
  259. {
  260. local rc cnt cnt_ip cnt_cidr size source action ruleset ruleset_6 rule timeout="-w 5" mode="${1}"
  261. if [ "${src_name%_6*}" = "whitelist" ]
  262. then
  263. target_src="ACCEPT"
  264. target_dst="ACCEPT"
  265. action="-I"
  266. fi
  267. case "${mode}" in
  268. initial)
  269. if [ -z "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
  270. then
  271. "${ban_ipt}" "${timeout}" -N "${ban_chain}"
  272. fi
  273. if [ -z "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
  274. then
  275. "${ban_ipt6}" "${timeout}" -N "${ban_chain}"
  276. fi
  277. src_name="ruleset"
  278. ruleset="${ban_wan_input_chain:-"input_wan_rule"} ${ban_wan_forward_chain:-"forwarding_wan_rule"} ${ban_lan_input_chain:-"input_lan_rule"} ${ban_lan_forward_chain:-"forwarding_lan_rule"}"
  279. for rule in ${ruleset}
  280. do
  281. f_iptrule "-D" "${rule} -j ${ban_chain}"
  282. done
  283. src_name="ruleset_6"
  284. ruleset_6="${ban_wan_input_chain_6:-"input_wan_rule"} ${ban_wan_forward_chain_6:-"forwarding_wan_rule"} ${ban_lan_input_chain_6:-"input_lan_rule"} ${ban_lan_forward_chain_6:-"forwarding_lan_rule"}"
  285. for rule in ${ruleset_6}
  286. do
  287. f_iptrule "-D" "${rule} -j ${ban_chain}"
  288. done
  289. f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_chain:-"-"}, ruleset: ${ruleset}, ruleset_6: ${ruleset_6}"
  290. ;;
  291. create)
  292. cnt="$(wc -l 2>/dev/null < "${tmp_file}")"
  293. cnt_cidr="$(grep -F "/" "${tmp_file}" | wc -l)"
  294. cnt_ip="$(( cnt - cnt_cidr ))"
  295. size="$(( cnt / 4 ))"
  296. if [ ${cnt} -gt 0 ]
  297. then
  298. if [ -z "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ]
  299. then
  300. "${ban_ipset}" create "${src_name}" hash:"${src_settype}" hashsize "${size}" maxelem 262144 family "${src_setipv}" counters
  301. else
  302. "${ban_ipset}" flush "${src_name}"
  303. fi
  304. "${ban_ipset}" -! restore < "${tmp_file}"
  305. printf "%s\n" "1" > "${tmp_set}"
  306. printf "%s\n" "${cnt}" > "${tmp_cnt}"
  307. fi
  308. f_iptadd
  309. end_ts="$(date +%s)"
  310. f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, settype: ${src_settype:-"-"}, setipv: "${src_setipv}", ruletype: ${src_ruletype:-"-"}, count(sum/ip/cidr): ${cnt:-0}/${cnt_ip:-0}/${cnt_cidr:-0}, time(s): $(( end_ts - start_ts ))"
  311. ;;
  312. refresh)
  313. if [ -n "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ]
  314. then
  315. "${ban_ipset}" save "${src_name}" > "${tmp_file}"
  316. if [ -s "${tmp_file}" ]
  317. then
  318. cnt="$(( $(wc -l 2>/dev/null < "${tmp_file}") - 1 ))"
  319. cnt_cidr="$(grep -F "/" "${tmp_file}" | wc -l)"
  320. cnt_ip="$(( cnt - cnt_cidr ))"
  321. printf "%s\n" "1" > "${tmp_set}"
  322. printf "%s\n" "${cnt}" > "${tmp_cnt}"
  323. fi
  324. f_iptadd
  325. fi
  326. end_ts="$(date +%s)"
  327. f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, count: ${cnt:-0}/${cnt_ip:-0}/${cnt_cidr:-0}, time(s): $(( end_ts - start_ts ))"
  328. ;;
  329. flush)
  330. f_iptadd "remove"
  331. if [ -n "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ]
  332. then
  333. "${ban_ipset}" flush "${src_name}"
  334. "${ban_ipset}" destroy "${src_name}"
  335. fi
  336. f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}"
  337. ;;
  338. destroy)
  339. if [ -n "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
  340. then
  341. "${ban_ipt_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt_restore}"
  342. "${ban_ipt}" "${timeout}" -F "${ban_chain}"
  343. "${ban_ipt}" "${timeout}" -X "${ban_chain}"
  344. fi
  345. if [ -n "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
  346. then
  347. "${ban_ipt6_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt6_restore}"
  348. "${ban_ipt6}" "${timeout}" -F "${ban_chain}"
  349. "${ban_ipt6}" "${timeout}" -X "${ban_chain}"
  350. fi
  351. for source in ${ban_sources}
  352. do
  353. if [ -n "$("${ban_ipset}" -n list "${source}" 2>/dev/null)" ]
  354. then
  355. "${ban_ipset}" destroy "${source}"
  356. fi
  357. done
  358. f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}"
  359. ;;
  360. esac
  361. }
  362. # write to syslog
  363. #
  364. f_log()
  365. {
  366. local class="${1}" log_msg="${2}"
  367. if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${ban_debug} -eq 1 ])
  368. then
  369. logger -p "${class}" -t "banIP-[${ban_ver}]" "${log_msg}"
  370. if [ "${class}" = "err" ]
  371. then
  372. f_jsnup error
  373. f_ipset destroy
  374. f_rmtemp
  375. logger -p "${class}" -t "banIP-[${ban_ver}]" "Please also check 'https://github.com/openwrt/packages/blob/master/net/banip/files/README.md'"
  376. exit 1
  377. fi
  378. fi
  379. }
  380. # main function for banIP processing
  381. #
  382. f_main()
  383. {
  384. local start_ts end_ts ip tmp_raw tmp_cnt tmp_setcnt tmp_load tmp_file entry list suffix mem_total mem_free cnt=1
  385. local src_name src_on src_url src_rset src_setipv src_settype src_ruletype src_cat src_log src_addon
  386. local pid pid_list log_content="$(logread -e "dropbear")"
  387. local wan_input wan_forward lan_input lan_forward target_src target_dst
  388. mem_total="$(awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
  389. mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
  390. f_log "debug" "f_main ::: fetch_util: ${ban_fetchinfo:-"-"}, fetch_parm: ${ban_fetchparm:-"-"}, iface: ${ban_iface:-"-"}, dev: ${ban_dev:-"-"}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${ban_maxqueue}"
  391. f_ipset initial
  392. # main loop
  393. #
  394. for src_name in ${ban_sources}
  395. do
  396. if [ "${src_name##*_}" = "6" ]
  397. then
  398. src_on="$(eval printf '%s' \"\${ban_src_on_6_${src_name%_6*}\}\")"
  399. src_url="$(eval printf '%s' \"\${ban_src_6_${src_name%_6*}\}\")"
  400. src_rset="$(eval printf '%s' \"\${ban_src_rset_6_${src_name%_6*}\}\")"
  401. src_setipv="inet6"
  402. wan_input="${ban_wan_input_chain_6:-"input_wan_rule"}"
  403. wan_forward="${ban_wan_forward_chain_6:-"forwarding_wan_rule"}"
  404. lan_input="${ban_lan_input_chain_6:-"input_lan_rule"}"
  405. lan_forward="${ban_lan_forward_chain_6:-"forwarding_lan_rule"}"
  406. target_src="${ban_target_src_6:-"DROP"}"
  407. target_dst="${ban_target_dst_6:-"REJECT"}"
  408. else
  409. src_on="$(eval printf '%s' \"\${ban_src_on_${src_name}\}\")"
  410. src_url="$(eval printf '%s' \"\${ban_src_${src_name}\}\")"
  411. src_rset="$(eval printf '%s' \"\${ban_src_rset_${src_name}\}\")"
  412. src_setipv="inet"
  413. wan_input="${ban_wan_input_chain:-"input_wan_rule"}"
  414. wan_forward="${ban_wan_forward_chain:-"forwarding_wan_rule"}"
  415. lan_input="${ban_lan_input_chain:-"input_lan_rule"}"
  416. lan_forward="${ban_lan_forward_chain:-"forwarding_lan_rule"}"
  417. target_src="${ban_target_src:-"DROP"}"
  418. target_dst="${ban_target_dst:-"REJECT"}"
  419. fi
  420. src_settype="$(eval printf '%s' \"\${ban_src_settype_${src_name%_6*}\}\")"
  421. src_ruletype="$(eval printf '%s' \"\${ban_src_ruletype_${src_name%_6*}\}\")"
  422. src_cat="$(eval printf '%s' \"\${ban_src_cat_${src_name%_6*}\}\")"
  423. src_addon=""
  424. tmp_load="${ban_tmpload}.${src_name}"
  425. tmp_file="${ban_tmpfile}.${src_name}"
  426. tmp_raw="${tmp_load}.raw"
  427. tmp_cnt="${tmp_file}.cnt"
  428. tmp_set="${tmp_file}.setcnt"
  429. # basic pre-checks
  430. #
  431. f_log "debug" "f_main ::: name: ${src_name}, src_on: ${src_on:-"-"}"
  432. if [ "${src_on}" != "1" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ] ||\
  433. [ -z "${src_settype}" ] || [ -z "${src_ruletype}" ]
  434. then
  435. f_ipset flush
  436. continue
  437. fi
  438. # download queue processing
  439. #
  440. (
  441. start_ts="$(date +%s)"
  442. if [ -f "${src_url}" ]
  443. then
  444. src_log="$(cat "${src_url}" 2>/dev/null > "${tmp_load}")"
  445. ban_rc=${?}
  446. case "${src_name}" in
  447. whitelist)
  448. src_addon="${ban_subnets}"
  449. ;;
  450. whitelist_6)
  451. src_addon="${ban_subnets6}"
  452. ;;
  453. blacklist)
  454. pid_list="$(printf "%s\n" "${log_content}" | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
  455. for pid in ${pid_list}
  456. do
  457. src_addon="${src_addon} $(printf "%s\n" "${log_content}" | grep -F "${pid}" | awk 'match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
  458. done
  459. ;;
  460. blacklist_6)
  461. pid_list="$(printf "%s\n" "${log_content}" | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
  462. for pid in ${pid_list}
  463. do
  464. src_addon="${src_addon} $(printf "%s\n" "${log_content}" | grep -F "${pid}" | awk 'match($0,/([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
  465. done
  466. ;;
  467. esac
  468. for ip in ${src_addon}
  469. do
  470. if [ -z "$(grep -F "${ip}" "${src_url}")" ]
  471. then
  472. printf '\n%s\n' "${ip}" >> "${tmp_load}"
  473. printf '\n%s\n' "${ip}" >> "${src_url}"
  474. fi
  475. done
  476. elif [ -n "${src_cat}" ]
  477. then
  478. if [ "${src_cat//[0-9]/}" != "${src_cat}" ]
  479. then
  480. for as in ${src_cat}
  481. do
  482. src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}AS${as}" 2>&1)"
  483. ban_rc=${?}
  484. if [ ${ban_rc} -eq 0 ]
  485. then
  486. jsonfilter -i "${tmp_raw}" -e '@.data.prefixes.*.prefix' 2>/dev/null >> "${tmp_load}"
  487. else
  488. break
  489. fi
  490. done
  491. else
  492. for co in ${src_cat}
  493. do
  494. src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}${co}&v4_format=prefix" 2>&1)"
  495. ban_rc=${?}
  496. if [ ${ban_rc} -eq 0 ]
  497. then
  498. if [ "${src_name##*_}" = "6" ]
  499. then
  500. jsonfilter -i "${tmp_raw}" -e '@.data.resources.ipv6.*' 2>/dev/null >> "${tmp_load}"
  501. else
  502. jsonfilter -i "${tmp_raw}" -e '@.data.resources.ipv4.*' 2>/dev/null >> "${tmp_load}"
  503. fi
  504. else
  505. break
  506. fi
  507. done
  508. fi
  509. else
  510. src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}" 2>&1)"
  511. ban_rc=${?}
  512. if [ ${ban_rc} -eq 0 ]
  513. then
  514. zcat "${tmp_raw}" 2>/dev/null > "${tmp_load}"
  515. ban_rc=${?}
  516. if [ ${ban_rc} -ne 0 ]
  517. then
  518. mv -f "${tmp_raw}" "${tmp_load}"
  519. ban_rc=${?}
  520. fi
  521. fi
  522. fi
  523. if [ ${ban_rc} -eq 0 ]
  524. then
  525. awk "${src_rset}" "${tmp_load}" 2>/dev/null | sort -u > "${tmp_file}"
  526. ban_rc=${?}
  527. if [ ${ban_rc} -eq 0 ]
  528. then
  529. f_ipset create
  530. else
  531. f_ipset refresh
  532. fi
  533. else
  534. src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')"
  535. f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${ban_rc}, log: ${src_log:-"-"}"
  536. f_ipset refresh
  537. fi
  538. ) &
  539. hold=$(( cnt % ban_maxqueue ))
  540. if [ ${hold} -eq 0 ]
  541. then
  542. wait
  543. fi
  544. cnt=$(( cnt + 1 ))
  545. done
  546. wait
  547. if [ ${ban_rc} -eq 0 ]
  548. then
  549. for cnt in $(cat ${ban_tmpfile}.*.setcnt 2>/dev/null)
  550. do
  551. ban_setcnt=$(( ban_setcnt + cnt ))
  552. done
  553. for cnt in $(cat ${ban_tmpfile}.*.cnt 2>/dev/null)
  554. do
  555. ban_cnt=$(( ban_cnt + cnt ))
  556. done
  557. f_log "info" "${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes loaded successfully (${ban_sysver})"
  558. fi
  559. f_jsnup
  560. f_rmtemp
  561. exit ${ban_rc}
  562. }
  563. # update runtime information
  564. #
  565. f_jsnup()
  566. {
  567. local rundate="$(/bin/date "+%d.%m.%Y %H:%M:%S")" status="${1:-"enabled"}"
  568. ban_cntinfo="${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes"
  569. json_add_string "status" "${status}"
  570. json_add_string "version" "${ban_ver}"
  571. json_add_string "fetch_info" "${ban_fetchinfo:-"-"}"
  572. json_add_string "ipset_info" "${ban_cntinfo:-"-"}"
  573. json_add_string "last_run" "${rundate:-"-"}"
  574. json_add_string "system" "${ban_sysver}"
  575. json_dump > "${ban_rtfile}"
  576. f_log "debug" "f_jsnup ::: status: ${status}, setcnt: ${ban_setcnt}, cnt: ${ban_cnt}"
  577. }
  578. # source required system libraries
  579. #
  580. if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
  581. then
  582. . "/lib/functions.sh"
  583. . "/lib/functions/network.sh"
  584. . "/usr/share/libubox/jshn.sh"
  585. else
  586. f_log "err" "system libraries not found"
  587. fi
  588. # initialize json runtime file
  589. #
  590. json_load_file "${ban_rtfile}" >/dev/null 2>&1
  591. json_select data >/dev/null 2>&1
  592. if [ ${?} -ne 0 ]
  593. then
  594. > "${ban_rtfile}"
  595. json_init
  596. json_add_object "data"
  597. fi
  598. # handle different banIP actions
  599. #
  600. f_envload
  601. case "${ban_action}" in
  602. stop)
  603. f_jsnup stopped
  604. f_ipset destroy
  605. f_rmtemp
  606. ;;
  607. start|restart|reload)
  608. f_envcheck
  609. f_main
  610. ;;
  611. esac