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.

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