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.

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