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.

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