diff --git a/net/banip/Makefile b/net/banip/Makefile index 065e12429c..a04eb3e86e 100644 --- a/net/banip/Makefile +++ b/net/banip/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=banip PKG_VERSION:=1.8.6 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken diff --git a/net/banip/files/banip-functions.sh b/net/banip/files/banip-functions.sh index 5775712b82..db641d7a66 100644 --- a/net/banip/files/banip-functions.sh +++ b/net/banip/files/banip-functions.sh @@ -203,20 +203,6 @@ f_rmdir() { fi } -# convert chars -# -f_char() { - local char="${1}" - - if [ "${char}" = "1" ]; then - printf '%s' "✔" - elif [ "${char}" = "0" ] || [ -z "${char}" ]; then - printf '%s' "✘" - else - printf '%s' "${char}" - fi -} - # trim strings # f_trim() { @@ -876,103 +862,87 @@ f_nftinit() { fi { - # nft header (tables, base and regular chains) + # nft header, optional table cleanup, base table, chains, counters and default rules # - printf '%s\n\n' "#!${ban_nftcmd} -f" - if "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1; then + printf '%s\n' "#!${ban_nftcmd} -f" "" + "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1 && printf '%s\n' "delete table inet banIP" - fi - printf '%s\n' "add table inet banIP" - - # base chains - # - printf '%s\n' "add chain inet banIP pre-routing { type filter hook prerouting priority -175; policy accept; }" - printf '%s\n' "add chain inet banIP wan-input { type filter hook input priority ${ban_nftpriority}; policy accept; }" - printf '%s\n' "add chain inet banIP wan-forward { type filter hook forward priority ${ban_nftpriority}; policy accept; }" - printf '%s\n' "add chain inet banIP lan-forward { type filter hook forward priority ${ban_nftpriority}; policy accept; }" - - # regular chains - # - printf '%s\n' "add chain inet banIP _inbound" - printf '%s\n' "add chain inet banIP _outbound" - printf '%s\n' "add chain inet banIP _reject" - - # named counter - # - printf '%s\n' "add counter inet banIP cnt_icmpflood" - printf '%s\n' "add counter inet banIP cnt_udpflood" - printf '%s\n' "add counter inet banIP cnt_synflood" - printf '%s\n' "add counter inet banIP cnt_tcpinvalid" - printf '%s\n' "add counter inet banIP cnt_ctinvalid" - printf '%s\n' "add counter inet banIP cnt_bcp38" - - # default reject chain rules - # - printf '%s\n' "add rule inet banIP _reject iifname != { ${wan_dev} } meta l4proto tcp reject with tcp reset" - printf '%s\n' "add rule inet banIP _reject reject with icmpx host-unreachable" - - # default pre-routing rules - # - printf '%s\n' "add rule inet banIP pre-routing iifname != { ${wan_dev} } counter accept" + printf '%s\n' \ + "add table inet banIP" \ + "add chain inet banIP pre-routing { type filter hook prerouting priority -175; policy accept; }" \ + "add chain inet banIP wan-input { type filter hook input priority ${ban_nftpriority}; policy accept; }" \ + "add chain inet banIP wan-forward { type filter hook forward priority ${ban_nftpriority}; policy accept; }" \ + "add chain inet banIP lan-forward { type filter hook forward priority ${ban_nftpriority}; policy accept; }" \ + "add chain inet banIP _inbound" \ + "add chain inet banIP _outbound" \ + "add chain inet banIP _reject" \ + "add counter inet banIP cnt_icmpflood" \ + "add counter inet banIP cnt_udpflood" \ + "add counter inet banIP cnt_synflood" \ + "add counter inet banIP cnt_tcpinvalid" \ + "add counter inet banIP cnt_ctinvalid" \ + "add counter inet banIP cnt_bcp38" \ + "add rule inet banIP _reject iifname != { ${wan_dev} } meta l4proto tcp reject with tcp reset" \ + "add rule inet banIP _reject reject with icmpx host-unreachable" \ + "add rule inet banIP pre-routing iifname != { ${wan_dev} } counter accept" # ct state invalid # - if [ "${ban_logprerouting}" = "1" ]; then + [ "${ban_logprerouting}" = "1" ] && printf '%s\n' "add rule inet banIP pre-routing ct state invalid ${log_ct}" - fi printf '%s\n' "add rule inet banIP pre-routing ct state invalid counter name cnt_ctinvalid drop" # ICMP Flood # if [ "${ban_icmplimit}" -gt "0" ]; then - if [ "${ban_logprerouting}" = "1" ]; then + [ "${ban_logprerouting}" = "1" ] && printf '%s\n' "add rule inet banIP pre-routing meta nfproto . meta l4proto { ipv4 . icmp , ipv6 . icmpv6 } limit rate over ${ban_icmplimit}/second ${log_icmp}" - fi printf '%s\n' "add rule inet banIP pre-routing meta nfproto . meta l4proto { ipv4 . icmp , ipv6 . icmpv6 } limit rate over ${ban_icmplimit}/second counter name cnt_icmpflood drop" fi # UDP Flood # if [ "${ban_udplimit}" -gt "0" ]; then - if [ "${ban_logprerouting}" = "1" ]; then + [ "${ban_logprerouting}" = "1" ] && printf '%s\n' "add rule inet banIP pre-routing meta l4proto udp ct state new limit rate over ${ban_udplimit}/second ${log_udp}" - fi printf '%s\n' "add rule inet banIP pre-routing meta l4proto udp ct state new limit rate over ${ban_udplimit}/second counter name cnt_udpflood drop" fi # SYN Flood # if [ "${ban_synlimit}" -gt "0" ]; then - if [ "${ban_logprerouting}" = "1" ]; then + [ "${ban_logprerouting}" = "1" ] && printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|ack) == syn limit rate over ${ban_synlimit}/second ${log_syn}" - fi printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|ack) == syn limit rate over ${ban_synlimit}/second counter name cnt_synflood drop" fi # TCP Invalid # if [ "${ban_logprerouting}" = "1" ]; then - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn) == (fin|syn) ${log_tcp}" - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (syn|rst) == (syn|rst) ${log_tcp}" - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) ${log_tcp}" - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) ${log_tcp}" + printf '%s\n' \ + "add rule inet banIP pre-routing tcp flags & (fin|syn) == (fin|syn) ${log_tcp}" \ + "add rule inet banIP pre-routing tcp flags & (syn|rst) == (syn|rst) ${log_tcp}" \ + "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) ${log_tcp}" \ + "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) ${log_tcp}" fi - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn) == (fin|syn) counter name cnt_tcpinvalid drop" - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (syn|rst) == (syn|rst) counter name cnt_tcpinvalid drop" - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) counter name cnt_tcpinvalid drop" - printf '%s\n' "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) counter name cnt_tcpinvalid drop" + printf '%s\n' \ + "add rule inet banIP pre-routing tcp flags & (fin|syn) == (fin|syn) counter name cnt_tcpinvalid drop" \ + "add rule inet banIP pre-routing tcp flags & (syn|rst) == (syn|rst) counter name cnt_tcpinvalid drop" \ + "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) counter name cnt_tcpinvalid drop" \ + "add rule inet banIP pre-routing tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) counter name cnt_tcpinvalid drop" # default wan-input rules # - printf '%s\n' "add rule inet banIP wan-input ct state established,related counter accept" - printf '%s\n' "add rule inet banIP wan-input iifname != { ${wan_dev} } counter accept" - printf '%s\n' "add rule inet banIP wan-input meta nfproto ipv4 udp sport 67-68 udp dport 67-68 counter accept" - printf '%s\n' "add rule inet banIP wan-input meta nfproto ipv6 udp sport 547 udp dport 546 counter accept" - printf '%s\n' "add rule inet banIP wan-input meta nfproto ipv6 icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert } ip6 hoplimit 255 counter accept" - [ -n "${allow_dport}" ] && printf '%s\n' "add rule inet banIP wan-input ${allow_dport} counter accept" - if [ "${ban_bcp38}" = "1" ]; then + printf '%s\n' \ + "add rule inet banIP wan-input ct state established,related counter accept" \ + "add rule inet banIP wan-input iifname != { ${wan_dev} } counter accept" \ + "add rule inet banIP wan-input meta nfproto ipv4 udp sport 67-68 udp dport 67-68 counter accept" \ + "add rule inet banIP wan-input meta nfproto ipv6 udp sport 547 udp dport 546 counter accept" \ + "add rule inet banIP wan-input meta nfproto ipv6 icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert } ip6 hoplimit 255 counter accept" + [ -n "${allow_dport}" ] && + printf '%s\n' "add rule inet banIP wan-input ${allow_dport} counter accept" + [ "${ban_bcp38}" = "1" ] && printf '%s\n' "add rule inet banIP wan-input fib saddr . iif oif missing counter name cnt_bcp38 drop" - fi if [ "${ban_loginbound}" = "1" ]; then printf '%s\n' "add rule inet banIP wan-input meta mark set 1 counter jump _inbound" else @@ -981,12 +951,13 @@ f_nftinit() { # default wan-forward rules # - printf '%s\n' "add rule inet banIP wan-forward ct state established,related counter accept" - printf '%s\n' "add rule inet banIP wan-forward iifname != { ${wan_dev} } counter accept" - [ -n "${allow_dport}" ] && printf '%s\n' "add rule inet banIP wan-forward ${allow_dport} counter accept" - if [ "${ban_bcp38}" = "1" ]; then + printf '%s\n' \ + "add rule inet banIP wan-forward ct state established,related counter accept" \ + "add rule inet banIP wan-forward iifname != { ${wan_dev} } counter accept" + [ -n "${allow_dport}" ] && + printf '%s\n' "add rule inet banIP wan-forward ${allow_dport} counter accept" + [ "${ban_bcp38}" = "1" ] && printf '%s\n' "add rule inet banIP wan-forward fib saddr . iif oif missing counter name cnt_bcp38 drop" - fi if [ "${ban_loginbound}" = "1" ]; then printf '%s\n' "add rule inet banIP wan-forward meta mark set 2 counter jump _inbound" else @@ -995,13 +966,15 @@ f_nftinit() { # default lan-forward rules # - printf '%s\n' "add rule inet banIP lan-forward ct state established,related counter accept" - printf '%s\n' "add rule inet banIP lan-forward oifname != { ${wan_dev} } counter accept" - [ -n "${vlan_allow}" ] && printf '%s\n' "add rule inet banIP lan-forward iifname { ${vlan_allow} } counter accept" - [ -n "${vlan_block}" ] && printf '%s\n' "add rule inet banIP lan-forward iifname { ${vlan_block} } counter goto _reject" - if [ "${ban_bcp38}" = "1" ]; then + printf '%s\n' \ + "add rule inet banIP lan-forward ct state established,related counter accept" \ + "add rule inet banIP lan-forward oifname != { ${wan_dev} } counter accept" + [ -n "${vlan_allow}" ] && + printf '%s\n' "add rule inet banIP lan-forward iifname { ${vlan_allow} } counter accept" + [ -n "${vlan_block}" ] && + printf '%s\n' "add rule inet banIP lan-forward iifname { ${vlan_block} } counter goto _reject" + [ "${ban_bcp38}" = "1" ] && printf '%s\n' "add rule inet banIP lan-forward fib saddr . iif oif missing counter name cnt_bcp38 drop" - fi printf '%s\n' "add rule inet banIP lan-forward counter jump _outbound" } >"${file}" @@ -1717,12 +1690,20 @@ f_rmset() { # generate status information # f_genstatus() { + local s_auto s_v4 s_v6 s_bcp s_lpre s_lin s_lout s_cnt s_dedup s_split s_cf s_allow s_dbg runtime local mem_free nft_ver chain_cnt set_cnt rule_cnt object end_time duration table table_sets element_cnt="0" custom_feed="0" split="0" status="${1}" + # memory and nftables version information + # mem_free="$("${ban_awkcmd}" '/^MemAvailable/{printf "%.2f", $2/1024}' "/proc/meminfo" 2>>"${ban_errorlog}")" nft_ver="$(printf '%s' "${ban_packages}" | "${ban_jsoncmd}" -ql1 -e '@.packages["nftables-json"]')" + # read config information if not already available + # [ -z "${ban_dev}" ] && f_conf + + # only gather detailed information if banIP is active + # if [ "${status}" = "active" ]; then table="$("${ban_nftcmd}" -tj list table inet banIP 2>>"${ban_errorlog}")" table_sets="$(printf '%s' "${table}" | "${ban_jsoncmd}" -qe '@.nftables[@.set.family="inet"].set.name')" @@ -1743,6 +1724,24 @@ f_genstatus() { [ -s "${ban_customfeedfile}" ] && custom_feed="1" [ "${ban_splitsize:-"0"}" -gt "0" ] && split="1" + # map flag values to status characters + # + case "${ban_autodetect}" in 1) s_auto="✔" ;; *) s_auto="✘" ;; esac + case "${ban_protov4}" in 1) s_v4="✔" ;; *) s_v4="✘" ;; esac + case "${ban_protov6}" in 1) s_v6="✔" ;; *) s_v6="✘" ;; esac + case "${ban_bcp38}" in 1) s_bcp="✔" ;; *) s_bcp="✘" ;; esac + case "${ban_logprerouting}" in 1) s_lpre="✔" ;; *) s_lpre="✘" ;; esac + case "${ban_loginbound}" in 1) s_lin="✔" ;; *) s_lin="✘" ;; esac + case "${ban_logoutbound}" in 1) s_lout="✔" ;; *) s_lout="✘" ;; esac + case "${ban_nftcount}" in 1) s_cnt="✔" ;; *) s_cnt="✘" ;; esac + case "${ban_deduplicate}" in 1) s_dedup="✔" ;; *) s_dedup="✘" ;; esac + case "${split}" in 1) s_split="✔" ;; *) s_split="✘" ;; esac + case "${custom_feed}" in 1) s_cf="✔" ;; *) s_cf="✘" ;; esac + case "${ban_allowlistonly}" in 1) s_allow="✔" ;; *) s_allow="✘" ;; esac + case "${ban_debug}" in 1) s_dbg="✔" ;; *) s_dbg="✘" ;; esac + + # generate JSON status file + # : >"${ban_rtfile}" json_init json_load_file "${ban_rtfile}" >/dev/null 2>&1 @@ -1782,7 +1781,7 @@ f_genstatus() { json_close_array json_add_string "nft_info" "ver: ${nft_ver:-"-"}, priority: ${ban_nftpriority}, policy: ${ban_nftpolicy}, loglevel: ${ban_nftloglevel}, expiry: ${ban_nftexpiry:-"-"}, limit (icmp/syn/udp): ${ban_icmplimit}/${ban_synlimit}/${ban_udplimit}" json_add_string "run_info" "base: ${ban_basedir}, backup: ${ban_backupdir}, report: ${ban_reportdir}, error: ${ban_errordir}" - json_add_string "run_flags" "auto: $(f_char ${ban_autodetect}), proto (4/6): $(f_char ${ban_protov4})/$(f_char ${ban_protov6}), bcp38: $(f_char ${ban_bcp38}), log (pre/in/out): $(f_char ${ban_logprerouting})/$(f_char ${ban_loginbound})/$(f_char ${ban_logoutbound}), count: $(f_char ${ban_nftcount}), dedup: $(f_char ${ban_deduplicate}), split: $(f_char ${split}), custom feed: $(f_char ${custom_feed}), allowed only: $(f_char ${ban_allowlistonly}), debug: $(f_char ${ban_debug})" + json_add_string "run_flags" "auto: ${s_auto}, proto (4/6): ${s_v4}/${s_v6}, bcp38: ${s_bcp}, log (pre/in/out): ${s_lpre}/${s_lin}/${s_lout}, count: ${s_cnt}, dedup: ${s_dedup}, split: ${s_split}, custom feed: ${s_cf}, allowed only: ${s_allow}, debug: ${s_dbg}" json_add_string "last_run" "${runtime:-"-"}" json_add_string "system_info" "cores: ${ban_cores}, log: ${ban_logreadcmd##*/}, fetch: ${ban_fetchcmd##*/}, ${ban_sysver}" json_dump >"${ban_rtfile}" @@ -1829,7 +1828,7 @@ f_getstatus() { # domain lookup # f_lookup() { - local cnt list domain lookup ip elementsv4 elementsv6 start_time end_time duration cnt_domain="0" cnt_ip="0" feed="${1}" + local cnt list timestamp domain lookup ip elementsv4 elementsv6 start_time end_time duration cnt_domain="0" cnt_ip="0" feed="${1}" read -r start_time _ <"/proc/uptime" start_time="${start_time%%.*}" @@ -1841,15 +1840,16 @@ f_lookup() { for domain in ${list}; do lookup="$("${ban_lookupcmd}" "${domain}" ${ban_resolver} 2>>"${ban_errorlog}" | "${ban_awkcmd}" '/^Address[ 0-9]*: /{if(!seen[$NF]++)printf "%s ",$NF}' 2>>"${ban_errorlog}")" + [ -n "${lookup}" ] && timestamp="$(date "+%Y-%m-%d %H:%M:%S")" for ip in ${lookup}; do if [ "${ip%%.*}" = "127" ] || [ "${ip%%.*}" = "0" ] || [ -z "${ip%%::*}" ]; then continue else [ "${ip##*:}" = "${ip}" ] && elementsv4="${elementsv4} ${ip}," || elementsv6="${elementsv6} ${ip}," if [ "${feed}" = "allowlist" ] && [ "${ban_autoallowlist}" = "1" ] && ! "${ban_grepcmd}" -q "^${ip}[[:space:]]*#" "${ban_allowlist}"; then - printf "%-45s%s\n" "${ip}" "# '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}" + printf "%-45s%s\n" "${ip}" "# '${domain}' added on ${timestamp}" >>"${ban_allowlist}" elif [ "${feed}" = "blocklist" ] && [ "${ban_autoblocklist}" = "1" ] && ! "${ban_grepcmd}" -q "^${ip}[[:space:]]*#" "${ban_blocklist}"; then - printf "%-45s%s\n" "${ip}" "# '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}" + printf "%-45s%s\n" "${ip}" "# '${domain}' added on ${timestamp}" >>"${ban_blocklist}" fi cnt_ip="$((cnt_ip + 1))" fi @@ -2684,8 +2684,8 @@ f_monitor() { if [ "${rdap_rc}" = "0" ] && [ -s "${ban_rdapfile}.${ip}" ]; then [ "${proto}" = ".v4" ] && rdap_idx="$("${ban_jsoncmd}" -i "${ban_rdapfile}.${ip}" -qe '@.cidr0_cidrs[@.v4prefix].*' | "${ban_awkcmd}" '{ORS=" "; print}')" [ "${proto}" = ".v6" ] && rdap_idx="$("${ban_jsoncmd}" -i "${ban_rdapfile}.${ip}" -qe '@.cidr0_cidrs[@.v6prefix].*' | "${ban_awkcmd}" '{ORS=" "; print}')" - rdap_info="$("${ban_jsoncmd}" -l1 -i "${ban_rdapfile}.${ip}" -qe '@.country' -qe '@.notices[@.title="Source"].description[1]' | "${ban_awkcmd}" 'BEGIN{RS="";FS="\n"}{printf "%s, %s",$1,$2}')" - [ -z "${rdap_info}" ] && rdap_info="$("${ban_jsoncmd}" -l1 -i "${ban_rdapfile}.${ip}" -qe '@.notices[0].links[0].value' | "${ban_awkcmd}" 'BEGIN{FS="[/.]"}{printf"%s, %s","n/a",toupper($4)}')" + rdap_info="$("${ban_jsoncmd}" -l1 -i "${ban_rdapfile}.${ip}" -qe '@.country' -qe '@.notices[@.title="Source"].description[1]' | "${ban_awkcmd}" 'BEGIN{RS="";FS="\n"}{c=($1!=""?$1:"-"); s=($2!=""?$2:"-"); printf "%s, %s", c, s}')" + [ -z "${rdap_info}" ] || [ "${rdap_info}" = "-, -" ] && rdap_info="$("${ban_jsoncmd}" -l1 -i "${ban_rdapfile}.${ip}" -qe '@.notices[0].links[0].value' | "${ban_awkcmd}" 'BEGIN{FS="[/.]"}{printf"%s, %s","n/a",toupper($4)}')" # if RDAP response contains (multiple) valid CIDR info, # attempt to add entire range to blocklist set with same expiry as individual IP