banip: new package to block incoming & outgoing ip addresseslilik-openwrt-22.03
@ -0,0 +1,64 @@ | |||
# | |||
# Copyright (c) 2018 Dirk Brenken (dev@brenken.org) | |||
# This is free software, licensed under the GNU General Public License v3. | |||
# | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=banip | |||
PKG_VERSION:=0.0.5 | |||
PKG_RELEASE:=1 | |||
PKG_LICENSE:=GPL-3.0+ | |||
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org> | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/banip | |||
SECTION:=net | |||
CATEGORY:=Network | |||
TITLE:=Ban incoming and/or outgoing ip adresses via ipsets | |||
DEPENDS:=+jshn +jsonfilter +ipset +iptables | |||
PKGARCH:=all | |||
endef | |||
define Package/banip/description | |||
Powerful banIP script to block ip addresses via ipsets. | |||
The script supports many ip blacklist sites plus manual black- and whitelist overrides. | |||
Please see https://github.com/openwrt/packages/blob/master/net/banip/files/README.md for further information. | |||
endef | |||
define Package/banip/conffiles | |||
/etc/config/banip | |||
/etc/banip/banip.whitelist | |||
/etc/banip/banip.blacklist | |||
endef | |||
define Build/Prepare | |||
endef | |||
define Build/Configure | |||
endef | |||
define Build/Compile | |||
endef | |||
define Package/banip/install | |||
$(INSTALL_DIR) $(1)/usr/bin | |||
$(INSTALL_BIN) ./files/banip.sh $(1)/usr/bin/ | |||
$(INSTALL_DIR) $(1)/etc/init.d | |||
$(INSTALL_BIN) ./files/banip.init $(1)/etc/init.d/banip | |||
$(INSTALL_DIR) $(1)/etc/config | |||
$(INSTALL_CONF) ./files/banip.conf $(1)/etc/config/banip | |||
$(INSTALL_DIR) $(1)/etc/banip | |||
$(INSTALL_CONF) ./files/banip.blacklist $(1)/etc/banip/ | |||
$(INSTALL_CONF) ./files/banip.whitelist $(1)/etc/banip/ | |||
$(INSTALL_DIR) $(1)/etc/hotplug.d/firewall | |||
$(INSTALL_DATA) ./files/banip.hotplug $(1)/etc/hotplug.d/firewall/30-banip | |||
endef | |||
$(eval $(call BuildPackage,banip)) |
@ -0,0 +1,75 @@ | |||
# banIP - ban incoming and/or outgoing ip adresses via ipsets | |||
## Description | |||
IP address blocking is commonly used to protect against brute force attacks, prevent disruptive or unautherized address(es) from access or it can be used to restrict access to or from a particular geographic area — for example. | |||
## Main Features | |||
* support many IP blocklist sources (free for private usage, for commercial use please check their individual licenses): | |||
* zero-conf like automatic installation & setup, usually no manual changes needed | |||
* supports six different download utilities: uclient-fetch, wget, curl, aria2c, wget-nossl, busybox-wget | |||
* Really fast downloads & list processing as they are handled in parallel as background jobs in a configurable 'Download Queue' | |||
* provides 'http only' mode without installed ssl library for all non-SSL blocklist sources | |||
* full IPv4 and IPv6 support | |||
* ipsets (one per source) are used to ban a large number of IP addresses | |||
* supports blocking by ASN numbers | |||
* supports blocking by iso country codes | |||
* supports local white & blacklist (IPv4, IPv6 & CIDR notation), located by default in /etc/banip/banip.whitelist and /etc/banip/banip.blacklist | |||
* auto-add unsuccessful ssh login attempts to local blacklist | |||
* auto-add the uplink subnet to local whitelist | |||
* per source configuration of SRC (incoming) and DST (outgoing) | |||
* integrated IPSet-Lookup | |||
* integrated RIPE-Lookup | |||
* blocklist source parsing by fast & flexible regex rulesets | |||
* minimal status & error logging to syslog, enable debug logging to receive more output | |||
* procd based init system support (start/stop/restart/reload/status) | |||
* procd network interface trigger support | |||
* output comprehensive runtime information via LuCI or via 'status' init command | |||
* strong LuCI support | |||
* optional: add new banIP sources on your own | |||
## Prerequisites | |||
* [OpenWrt](https://openwrt.org), tested with the stable release series (18.06) and with the latest snapshot | |||
* a download utility: | |||
* to support all blocklist sources a full version (with ssl support) of 'wget', 'uclient-fetch' with one of the 'libustream-*' ssl libraries, 'aria2c' or 'curl' is required | |||
* for limited devices with real memory constraints, banIP provides also a 'http only' option and supports wget-nossl and uclient-fetch (without libustream-ssl) as well | |||
## Installation & Usage | |||
* install 'banip' (_opkg install banip_) | |||
* at minimum configure the needed IP blocklist sources, the download utility and enable the banIP service in _/etc/config/banip_ | |||
* control the banip service manually with _/etc/init.d/banip_ start/stop/restart/reload/status or use the LuCI frontend | |||
## LuCI banIP companion package | |||
* it's recommended to use the provided LuCI frontend to control all aspects of banIP | |||
* install 'luci-app-banip' (_opkg install luci-app-banip_) | |||
* the application is located in LuCI under 'Services' menu | |||
## Examples | |||
**receive banIP runtime information:** | |||
<pre><code> | |||
/etc/init.d/banip status | |||
::: banIP runtime information | |||
+ status : enabled | |||
+ version : 0.0.5 | |||
+ fetch_info : /bin/uclient-fetch (libustream-ssl) | |||
+ ipset_info : 3 IPSets with overall 29510 IPs/Prefixes | |||
+ last_run : 08.11.2018 15:03:50 | |||
+ system : GL-AR750S, OpenWrt SNAPSHOT r8419-860de2e1aa | |||
</code></pre> | |||
**cronjob for a regular block list update (/etc/crontabs/root):** | |||
<pre><code> | |||
0 06 * * * /etc/init.d/banip reload | |||
</code></pre> | |||
## Support | |||
Please join the banIP discussion in this [forum thread](https://forum.openwrt.org/t/banip-new-project-needs-testers-feedback/16985) or contact me by mail <dev@brenken.org> | |||
## Removal | |||
* stop all banIP related services with _/etc/init.d/banip stop_ | |||
* optional: remove the banip package (_opkg remove banip_) | |||
Have fun! | |||
Dirk |
@ -0,0 +1,223 @@ | |||
# banIP configuration, for further information | |||
# see 'https://github.com/openwrt/packages/blob/master/net/banip/files/README.md' | |||
config banip 'global' | |||
option ban_enabled '0' | |||
option ban_automatic '1' | |||
option ban_fetchutil 'uclient-fetch' | |||
option ban_iface 'wan' | |||
config banip 'extra' | |||
option ban_debug '0' | |||
option ban_maxqueue '8' | |||
config source 'whitelist' | |||
option ban_src '/etc/banip/banip.whitelist' | |||
option ban_src_6 '/etc/banip/banip.whitelist' | |||
option ban_src_desc 'Always allow these IPs (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add whitelist \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add whitelist_6 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src+dst' | |||
option ban_src_on '1' | |||
option ban_src_on_6 '0' | |||
config source 'blacklist' | |||
option ban_src '/etc/banip/banip.blacklist' | |||
option ban_src_6 '/etc/banip/banip.blacklist' | |||
option ban_src_desc 'Always deny these IPs (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add blacklist \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add blacklist_6 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src+dst' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'bogon' | |||
option ban_src 'https://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt' | |||
option ban_src_6 'https://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt' | |||
option ban_src_desc 'Bogon prefixes, plus prefixes that have been allocated to RIRs but not yet assigned to ISPs (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add bogon \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add bogon_6 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src+dst' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'tor' | |||
option ban_src 'https://check.torproject.org/exit-addresses' | |||
option ban_src_desc 'List of Tor Exit Nodes (IPv4)' | |||
option ban_src_rset '/^(ExitAddress ([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add tor \"\$2}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'threat' | |||
option ban_src 'https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt' | |||
option ban_src_desc 'Emerging Threats (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add threat \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'debl' | |||
option ban_src 'https://www.blocklist.de/downloads/export-ips_all.txt' | |||
option ban_src_6 'https://www.blocklist.de/downloads/export-ips_all.txt' | |||
option ban_src_desc 'Fail2ban reporting service (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add debl \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add debl_6 \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'myip' | |||
option ban_src 'https://www.myip.ms/files/blacklist/general/latest_blacklist.txt' | |||
option ban_src_6 'https://www.myip.ms/files/blacklist/general/latest_blacklist.txt' | |||
option ban_src_desc 'IP blacklist provided by myip.ms (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add myip \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add myip_6 \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'yoyo' | |||
option ban_src 'http://pgl.yoyo.org/adservers/iplist.php?ipformat=plain&showintro=0&mimetype=plaintext' | |||
option ban_src_desc 'IP blocklist provided by Peter Lowe (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add yoyo \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'zeus' | |||
option ban_src 'https://zeustracker.abuse.ch/blocklist.php?download=ipblocklist' | |||
option ban_src_desc 'Zeus Tracker by abuse.ch (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add zeus \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'sslbl' | |||
option ban_src 'https://sslbl.abuse.ch/blacklist/sslipblacklist.csv' | |||
option ban_src_desc 'SSL Blacklist by abuse.ch (IPv4)' | |||
option ban_src_rset 'BEGIN{FS=\",\"}/^(([0-9]{1,3}\.){3}[0-9]{1,3},).*/{print \"add sslbl \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'ransomware' | |||
option ban_src 'https://ransomwaretracker.abuse.ch/downloads/RW_IPBL.txt' | |||
option ban_src_desc 'Ransomware Tracker by abuse.ch (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add ransomware \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'feodo' | |||
option ban_src 'https://feodotracker.abuse.ch/blocklist/?download=ipblocklist' | |||
option ban_src_desc 'Feodo Tracker by abuse.ch (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add feodo \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'dshield' | |||
option ban_src 'http://feeds.dshield.org/block.txt' | |||
option ban_src_desc 'Dshield recommended IP blocklist. Contains top 20 attacking class C subnets (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add dshield \"\$1 \"/\"\$3}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'proxy' | |||
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/proxylists.ipset' | |||
option ban_src_desc 'List of Open Proxies (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add proxy \"\$1}' | |||
option ban_src_settype 'ip' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'iblocklist' | |||
option ban_src 'http://list.iblocklist.com/?list=dgxtneitpuvgqqcpfulq&fileformat=cidr&archiveformat=gz' | |||
option ban_src_desc 'Contains advertising trackers and a short list of bad/intrusive porn sites (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add iblocklist \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'drop' | |||
option ban_src 'https://www.spamhaus.org/drop/drop.txt' | |||
option ban_src_6 'https://www.spamhaus.org/drop/dropv6.txt' | |||
option ban_src_desc 'Spamhaus drop compilation (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add drop \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add drop_6 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'edrop' | |||
option ban_src 'https://www.spamhaus.org/drop/edrop.txt' | |||
option ban_src_desc 'Spamhaus edrop compilation (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add edrop \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'firehol1' | |||
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset' | |||
option ban_src_desc 'Firehol Level 1 compilation. Contains bogons, spamhaus drop and edrop, dshield and malware lists (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol1 \"\$1}' | |||
option ban_src_settype 'net_inet' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'firehol2' | |||
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level2.netset' | |||
option ban_src_desc 'Firehol Level 2 compilation. Contains blocklists that track attacks, during the last 48 hours (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol2 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'firehol3' | |||
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level3.netset' | |||
option ban_src_desc 'Firehol Level 3 compilation. Contains blocklists that track attacks, spyware and viruses (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol3 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'firehol4' | |||
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level4.netset' | |||
option ban_src_desc 'Firehol Level 4 compilation. May include a large number of false positives (IPv4)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol4 \"\$1}' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
config source 'country' | |||
option ban_src 'https://stat.ripe.net/data/country-resource-list/data.json?resource=' | |||
option ban_src_6 'https://stat.ripe.net/data/country-resource-list/data.json?resource=' | |||
option ban_src_desc 'Build a dynamic IPSet by country iso codes based on RIPE data (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add country \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add country_6 \"\$1}' | |||
list ban_src_cat 'de' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' | |||
config source 'asn' | |||
option ban_src 'https://stat.ripe.net/data/announced-prefixes/data.json?resource=' | |||
option ban_src_6 'https://stat.ripe.net/data/announced-prefixes/data.json?resource=' | |||
option ban_src_desc 'Build a dynamic IPSet by ASN numbers based on RIPE data (IPv4/IPv6)' | |||
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add asn \"\$1}' | |||
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add asn_6 \"\$1}' | |||
list ban_src_cat '32934' | |||
option ban_src_settype 'net' | |||
option ban_src_ruletype 'src' | |||
option ban_src_on '0' | |||
option ban_src_on_6 '0' |
@ -0,0 +1,12 @@ | |||
#!/bin/sh | |||
# | |||
ban_pidfile="/var/run/banip.pid" | |||
ban_enabled="$(/etc/init.d/banip enabled; printf "%u" ${?})" | |||
if [ "${ban_enabled}" = "1" ] || [ ! -f "${ban_pidfile}" ] || [ -s "${ban_pidfile}" ] || [ "${ACTION}" != "add" ] | |||
then | |||
exit 0 | |||
fi | |||
/etc/init.d/banip start |
@ -0,0 +1,74 @@ | |||
#!/bin/sh /etc/rc.common | |||
# | |||
START=30 | |||
USE_PROCD=1 | |||
EXTRA_COMMANDS="status" | |||
EXTRA_HELP=" status Print runtime information" | |||
ban_init="/etc/init.d/banip" | |||
ban_script="/usr/bin/banip.sh" | |||
ban_pidfile="/var/run/banip.pid" | |||
boot() | |||
{ | |||
ban_boot="1" | |||
rc_procd start_service | |||
} | |||
start_service() | |||
{ | |||
if [ $("${ban_init}" enabled; printf "%u" ${?}) -eq 0 ] | |||
then | |||
if [ "${ban_boot}" = "1" ] | |||
then | |||
return 0 | |||
fi | |||
local nice="$(uci_get banip extra ban_nice)" | |||
procd_open_instance "banip" | |||
procd_set_param command "${ban_script}" "${@}" | |||
procd_set_param pidfile "${ban_pidfile}" | |||
procd_set_param nice ${nice:-0} | |||
procd_set_param stdout 1 | |||
procd_set_param stderr 1 | |||
procd_close_instance | |||
fi | |||
} | |||
stop_service() | |||
{ | |||
rc_procd "${ban_script}" stop | |||
rc_procd start_service | |||
} | |||
status() | |||
{ | |||
local key keylist value rtfile="$(uci_get banip global ban_rtfile)" | |||
rtfile="${rtfile:-"/tmp/ban_runtime.json"}" | |||
json_load_file "${rtfile}" >/dev/null 2>&1 | |||
json_select data >/dev/null 2>&1 | |||
if [ ${?} -eq 0 ] | |||
then | |||
printf "%s\n" "::: banIP runtime information" | |||
json_get_keys keylist | |||
for key in ${keylist} | |||
do | |||
json_get_var value "${key}" | |||
printf " + %-10s : %s\n" "${key}" "${value}" | |||
done | |||
else | |||
printf "%s\n" "::: no banIP runtime information available" | |||
fi | |||
} | |||
service_triggers() | |||
{ | |||
local iface="$(uci_get banip global ban_iface)" | |||
local delay="$(uci_get banip extra ban_triggerdelay)" | |||
PROCD_RELOAD_DELAY=$((${delay:-2} * 1000)) | |||
procd_add_interface_trigger "interface.*.up" "${iface:-"wan"}" "${ban_init}" start | |||
procd_add_reload_trigger "banip" "firewall" | |||
} |
@ -0,0 +1,671 @@ | |||
#!/bin/sh | |||
# banIP - ban incoming and outgoing ip adresses/subnets via ipset | |||
# written by Dirk Brenken (dev@brenken.org) | |||
# This is free software, licensed under the GNU General Public License v3. | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
# set initial defaults | |||
# | |||
LC_ALL=C | |||
PATH="/usr/sbin:/usr/bin:/sbin:/bin" | |||
ban_ver="0.0.5" | |||
ban_sysver="unknown" | |||
ban_enabled=0 | |||
ban_automatic="1" | |||
ban_iface="" | |||
ban_debug=0 | |||
ban_maxqueue=8 | |||
ban_fetchutil="uclient-fetch" | |||
ban_ipt="$(command -v iptables)" | |||
ban_ipt_save="$(command -v iptables-save)" | |||
ban_ipt_restore="$(command -v iptables-restore)" | |||
ban_ipt6="$(command -v ip6tables)" | |||
ban_ipt6_save="$(command -v ip6tables-save)" | |||
ban_ipt6_restore="$(command -v ip6tables-restore)" | |||
ban_ipset="$(command -v ipset)" | |||
ban_chain="banIP" | |||
ban_action="${1:-"start"}" | |||
ban_pidfile="/var/run/banip.pid" | |||
ban_rtfile="/tmp/ban_runtime.json" | |||
ban_setcnt=0 | |||
ban_cnt=0 | |||
ban_rc=0 | |||
# load environment | |||
# | |||
f_envload() | |||
{ | |||
local sys_call sys_desc sys_model | |||
# get system information | |||
# | |||
sys_call="$(ubus -S call system board 2>/dev/null)" | |||
if [ -n "${sys_call}" ] | |||
then | |||
sys_desc="$(printf '%s' "${sys_call}" | jsonfilter -e '@.release.description')" | |||
sys_model="$(printf '%s' "${sys_call}" | jsonfilter -e '@.model')" | |||
ban_sysver="${sys_model}, ${sys_desc}" | |||
fi | |||
# parse 'global' and 'extra' section by callback | |||
# | |||
config_cb() | |||
{ | |||
local type="${1}" | |||
if [ "${type}" = "banip" ] | |||
then | |||
option_cb() | |||
{ | |||
local option="${1}" | |||
local value="${2}" | |||
eval "${option}=\"${value}\"" | |||
} | |||
else | |||
reset_cb | |||
fi | |||
} | |||
# parse 'source' typed sections | |||
# | |||
parse_config() | |||
{ | |||
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" | |||
for opt in ${options} | |||
do | |||
config_get value "${section}" "${opt}" | |||
if [ -n "${value}" ] | |||
then | |||
eval "${opt}_${section}=\"${value}\"" | |||
if [ "${opt}" = "ban_src" ] | |||
then | |||
eval "ban_sources=\"${ban_sources} ${section}\"" | |||
elif [ "${opt}" = "ban_src_6" ] | |||
then | |||
eval "ban_sources=\"${ban_sources} ${section}_6\"" | |||
fi | |||
fi | |||
done | |||
} | |||
# load config | |||
# | |||
config_load banip | |||
config_foreach parse_config source | |||
# create temp directory & files | |||
# | |||
f_temp | |||
# check status | |||
# | |||
if [ ${ban_enabled} -eq 0 ] | |||
then | |||
f_jsnup disabled | |||
f_ipset destroy | |||
f_rmtemp | |||
f_log "info" "banIP is currently disabled, please set ban_enabled to '1' to use this service" | |||
exit 0 | |||
fi | |||
} | |||
# check environment | |||
# | |||
f_envcheck() | |||
{ | |||
local ssl_lib | |||
# check fetch utility | |||
# | |||
case "${ban_fetchutil}" in | |||
uclient-fetch) | |||
if [ -f "/lib/libustream-ssl.so" ] | |||
then | |||
ban_fetchparm="${ban_fetchparm:-"--timeout=20 --no-check-certificate -O"}" | |||
ssl_lib="libustream-ssl" | |||
else | |||
ban_fetchparm="${ban_fetchparm:-"--timeout=20 -O"}" | |||
fi | |||
;; | |||
wget) | |||
ban_fetchparm="${ban_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=20 --no-check-certificate -O"}" | |||
ssl_lib="built-in" | |||
;; | |||
wget-nossl) | |||
ban_fetchparm="${ban_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=20 -O"}" | |||
;; | |||
busybox) | |||
ban_fetchparm="${ban_fetchparm:-"-O"}" | |||
;; | |||
curl) | |||
ban_fetchparm="${ban_fetchparm:-"--connect-timeout 20 --insecure -o"}" | |||
ssl_lib="built-in" | |||
;; | |||
aria2c) | |||
ban_fetchparm="${ban_fetchparm:-"--timeout=20 --allow-overwrite=true --auto-file-renaming=false --check-certificate=false -o"}" | |||
ssl_lib="built-in" | |||
;; | |||
esac | |||
ban_fetchutil="$(command -v "${ban_fetchutil}")" | |||
ban_fetchinfo="${ban_fetchutil:-"-"} (${ssl_lib:-"-"})" | |||
if [ ! -x "${ban_fetchutil}" ] || [ -z "${ban_fetchutil}" ] || [ -z "${ban_fetchparm}" ] | |||
then | |||
f_log "err" "download utility not found, please install 'uclient-fetch' with 'libustream-mbedtls' or the full 'wget' package" | |||
fi | |||
# get wan device and wan subnets | |||
# | |||
if [ "${ban_automatic}" = "1" ] | |||
then | |||
network_find_wan ban_iface | |||
if [ -z "${ban_iface}" ] | |||
then | |||
network_find_wan6 ban_iface | |||
fi | |||
fi | |||
network_get_device ban_dev "${ban_iface}" | |||
network_get_subnets ban_subnets "${ban_iface}" | |||
network_get_subnets6 ban_subnets6 "${ban_iface}" | |||
if [ -z "${ban_iface}" ] || [ -z "${ban_dev}" ] | |||
then | |||
f_log "err" "wan interface/device (${ban_iface:-"-"}/${ban_dev:-"-"}) not found, please please check your configuration" | |||
fi | |||
uci_set banip global ban_iface "${ban_iface}" | |||
uci_commit banip | |||
f_jsnup "running" | |||
f_log "info" "start banIP processing (${ban_action})" | |||
} | |||
# create temporary files and directories | |||
# | |||
f_temp() | |||
{ | |||
if [ -z "${ban_tmpdir}" ] | |||
then | |||
ban_tmpdir="$(mktemp -p /tmp -d)" | |||
ban_tmpload="$(mktemp -p ${ban_tmpdir} -tu)" | |||
ban_tmpfile="$(mktemp -p ${ban_tmpdir} -tu)" | |||
fi | |||
if [ ! -s "${ban_pidfile}" ] | |||
then | |||
printf '%s' "${$}" > "${ban_pidfile}" | |||
fi | |||
} | |||
# remove temporary files and directories | |||
# | |||
f_rmtemp() | |||
{ | |||
if [ -d "${ban_tmpdir}" ] | |||
then | |||
rm -rf "${ban_tmpdir}" | |||
fi | |||
> "${ban_pidfile}" | |||
} | |||
# iptables rules engine | |||
# | |||
f_iptrule() | |||
{ | |||
local rc timeout="-w 5" action="${1}" rule="${2}" | |||
if [ "${src_name##*_}" = "6" ] | |||
then | |||
rc="$("${ban_ipt6}" "${timeout}" -C ${rule} 2>/dev/null; printf '%u' ${?})" | |||
if ([ ${rc} -ne 0 ] && ([ "${action}" = "-A" ] || [ "${action}" = "-I" ])) \ | |||
|| ([ ${rc} -eq 0 ] && [ "${action}" = "-D" ]) | |||
then | |||
"${ban_ipt6}" "${timeout}" "${action}" ${rule} | |||
fi | |||
else | |||
rc="$("${ban_ipt}" "${timeout}" -C ${rule} 2>/dev/null; printf '%u' ${?})" | |||
if ([ ${rc} -ne 0 ] && ([ "${action}" = "-A" ] || [ "${action}" = "-I" ])) \ | |||
|| ([ ${rc} -eq 0 ] && [ "${action}" = "-D" ]) | |||
then | |||
"${ban_ipt}" "${timeout}" "${action}" ${rule} | |||
fi | |||
fi | |||
} | |||
# remove/add iptables rules | |||
# | |||
f_iptadd() | |||
{ | |||
local rm="${1}" | |||
f_iptrule "-D" "${ban_chain} -i ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}" | |||
f_iptrule "-D" "${ban_chain} -o ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}" | |||
if [ -z "${rm}" ] && [ ${cnt} -gt 0 ] | |||
then | |||
if [ "${src_ruletype}" != "dst" ] | |||
then | |||
if [ "${src_name##*_}" = "6" ] | |||
then | |||
# dummy, special IPv6 rules | |||
/bin/true | |||
else | |||
f_iptrule "-I" "${wan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN" | |||
fi | |||
f_iptrule "-A" "${wan_input} -j ${ban_chain}" | |||
f_iptrule "-A" "${wan_forward} -j ${ban_chain}" | |||
f_iptrule "${action:-"-A"}" "${ban_chain} -i ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}" | |||
fi | |||
if [ "${src_ruletype}" != "src" ] | |||
then | |||
if [ "${src_name##*_}" = "6" ] | |||
then | |||
# dummy, special IPv6 rules | |||
/bin/true | |||
else | |||
f_iptrule "-I" "${lan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN" | |||
fi | |||
f_iptrule "-A" "${lan_input} -j ${ban_chain}" | |||
f_iptrule "-A" "${lan_forward} -j ${ban_chain}" | |||
f_iptrule "${action:-"-A"}" "${ban_chain} -o ${ban_dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}" | |||
fi | |||
else | |||
if [ -n "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipset}" destroy "${src_name}" | |||
fi | |||
fi | |||
} | |||
# ipset/iptables actions | |||
# | |||
f_ipset() | |||
{ | |||
local rc cnt cnt_ip cnt_cidr size source action ruleset ruleset_6 rule timeout="-w 5" mode="${1}" | |||
if [ "${src_name%_6*}" = "whitelist" ] | |||
then | |||
target_src="ACCEPT" | |||
target_dst="ACCEPT" | |||
action="-I" | |||
fi | |||
case "${mode}" in | |||
initial) | |||
if [ -z "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipt}" "${timeout}" -N "${ban_chain}" | |||
fi | |||
if [ -z "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipt6}" "${timeout}" -N "${ban_chain}" | |||
fi | |||
src_name="ruleset" | |||
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"}" | |||
for rule in ${ruleset} | |||
do | |||
f_iptrule "-D" "${rule} -j ${ban_chain}" | |||
done | |||
src_name="ruleset_6" | |||
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"}" | |||
for rule in ${ruleset_6} | |||
do | |||
f_iptrule "-D" "${rule} -j ${ban_chain}" | |||
done | |||
f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_chain:-"-"}, ruleset: ${ruleset}, ruleset_6: ${ruleset_6}" | |||
;; | |||
create) | |||
cnt="$(wc -l 2>/dev/null < "${tmp_file}")" | |||
cnt_cidr="$(grep -F "/" "${tmp_file}" | wc -l)" | |||
cnt_ip="$(( cnt - cnt_cidr ))" | |||
size="$(( cnt / 4 ))" | |||
if [ ${cnt} -gt 0 ] | |||
then | |||
if [ -z "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipset}" create "${src_name}" hash:"${src_settype}" hashsize "${size}" maxelem 262144 family "${src_setipv}" counters | |||
else | |||
"${ban_ipset}" flush "${src_name}" | |||
fi | |||
"${ban_ipset}" -! restore < "${tmp_file}" | |||
printf "%s\n" "1" > "${tmp_set}" | |||
printf "%s\n" "${cnt}" > "${tmp_cnt}" | |||
fi | |||
f_iptadd | |||
end_ts="$(date +%s)" | |||
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 ))" | |||
;; | |||
refresh) | |||
if [ -n "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipset}" save "${src_name}" > "${tmp_file}" | |||
if [ -s "${tmp_file}" ] | |||
then | |||
cnt="$(( $(wc -l 2>/dev/null < "${tmp_file}") - 1 ))" | |||
cnt_cidr="$(grep -F "/" "${tmp_file}" | wc -l)" | |||
cnt_ip="$(( cnt - cnt_cidr ))" | |||
printf "%s\n" "1" > "${tmp_set}" | |||
printf "%s\n" "${cnt}" > "${tmp_cnt}" | |||
fi | |||
f_iptadd | |||
fi | |||
end_ts="$(date +%s)" | |||
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 ))" | |||
;; | |||
flush) | |||
f_iptadd "remove" | |||
if [ -n "$("${ban_ipset}" -n list "${src_name}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipset}" flush "${src_name}" | |||
"${ban_ipset}" destroy "${src_name}" | |||
fi | |||
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}" | |||
;; | |||
destroy) | |||
if [ -n "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipt_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt_restore}" | |||
"${ban_ipt}" "${timeout}" -F "${ban_chain}" | |||
"${ban_ipt}" "${timeout}" -X "${ban_chain}" | |||
fi | |||
if [ -n "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipt6_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt6_restore}" | |||
"${ban_ipt6}" "${timeout}" -F "${ban_chain}" | |||
"${ban_ipt6}" "${timeout}" -X "${ban_chain}" | |||
fi | |||
for source in ${ban_sources} | |||
do | |||
if [ -n "$("${ban_ipset}" -n list "${source}" 2>/dev/null)" ] | |||
then | |||
"${ban_ipset}" destroy "${source}" | |||
fi | |||
done | |||
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}" | |||
;; | |||
esac | |||
} | |||
# write to syslog | |||
# | |||
f_log() | |||
{ | |||
local class="${1}" log_msg="${2}" | |||
if [ -n "${log_msg}" ] && ([ "${class}" != "debug" ] || [ ${ban_debug} -eq 1 ]) | |||
then | |||
logger -p "${class}" -t "banIP-[${ban_ver}]" "${log_msg}" | |||
if [ "${class}" = "err" ] | |||
then | |||
f_jsnup error | |||
f_ipset destroy | |||
f_rmtemp | |||
logger -p "${class}" -t "banIP-[${ban_ver}]" "Please also check 'https://github.com/openwrt/packages/blob/master/net/banip/files/README.md'" | |||
exit 1 | |||
fi | |||
fi | |||
} | |||
# main function for banIP processing | |||
# | |||
f_main() | |||
{ | |||
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 | |||
local src_name src_on src_url src_rset src_setipv src_settype src_ruletype src_cat src_log src_addon | |||
local pid pid_list log_content="$(logread -e "dropbear")" | |||
local wan_input wan_forward lan_input lan_forward target_src target_dst | |||
mem_total="$(awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)" | |||
mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)" | |||
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}" | |||
f_ipset initial | |||
# main loop | |||
# | |||
for src_name in ${ban_sources} | |||
do | |||
if [ "${src_name##*_}" = "6" ] | |||
then | |||
src_on="$(eval printf '%s' \"\${ban_src_on_6_${src_name%_6*}\}\")" | |||
src_url="$(eval printf '%s' \"\${ban_src_6_${src_name%_6*}\}\")" | |||
src_rset="$(eval printf '%s' \"\${ban_src_rset_6_${src_name%_6*}\}\")" | |||
src_setipv="inet6" | |||
wan_input="${ban_wan_input_chain_6:-"input_wan_rule"}" | |||
wan_forward="${ban_wan_forward_chain_6:-"forwarding_wan_rule"}" | |||
lan_input="${ban_lan_input_chain_6:-"input_lan_rule"}" | |||
lan_forward="${ban_lan_forward_chain_6:-"forwarding_lan_rule"}" | |||
target_src="${ban_target_src_6:-"DROP"}" | |||
target_dst="${ban_target_dst_6:-"REJECT"}" | |||
else | |||
src_on="$(eval printf '%s' \"\${ban_src_on_${src_name}\}\")" | |||
src_url="$(eval printf '%s' \"\${ban_src_${src_name}\}\")" | |||
src_rset="$(eval printf '%s' \"\${ban_src_rset_${src_name}\}\")" | |||
src_setipv="inet" | |||
wan_input="${ban_wan_input_chain:-"input_wan_rule"}" | |||
wan_forward="${ban_wan_forward_chain:-"forwarding_wan_rule"}" | |||
lan_input="${ban_lan_input_chain:-"input_lan_rule"}" | |||
lan_forward="${ban_lan_forward_chain:-"forwarding_lan_rule"}" | |||
target_src="${ban_target_src:-"DROP"}" | |||
target_dst="${ban_target_dst:-"REJECT"}" | |||
fi | |||
src_settype="$(eval printf '%s' \"\${ban_src_settype_${src_name%_6*}\}\")" | |||
src_ruletype="$(eval printf '%s' \"\${ban_src_ruletype_${src_name%_6*}\}\")" | |||
src_cat="$(eval printf '%s' \"\${ban_src_cat_${src_name%_6*}\}\")" | |||
src_addon="" | |||
tmp_load="${ban_tmpload}.${src_name}" | |||
tmp_file="${ban_tmpfile}.${src_name}" | |||
tmp_raw="${tmp_load}.raw" | |||
tmp_cnt="${tmp_file}.cnt" | |||
tmp_set="${tmp_file}.setcnt" | |||
# basic pre-checks | |||
# | |||
f_log "debug" "f_main ::: name: ${src_name}, src_on: ${src_on:-"-"}" | |||
if [ "${src_on}" != "1" ] || [ -z "${src_url}" ] || [ -z "${src_rset}" ] ||\ | |||
[ -z "${src_settype}" ] || [ -z "${src_ruletype}" ] | |||
then | |||
f_ipset flush | |||
continue | |||
fi | |||
# download queue processing | |||
# | |||
( | |||
start_ts="$(date +%s)" | |||
if [ -f "${src_url}" ] | |||
then | |||
src_log="$(cat "${src_url}" 2>/dev/null > "${tmp_load}")" | |||
ban_rc=${?} | |||
case "${src_name}" in | |||
whitelist) | |||
src_addon="${ban_subnets}" | |||
;; | |||
whitelist_6) | |||
src_addon="${ban_subnets6}" | |||
;; | |||
blacklist) | |||
pid_list="$(printf "%s\n" "${log_content}" | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}')" | |||
for pid in ${pid_list} | |||
do | |||
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)}')" | |||
done | |||
;; | |||
blacklist_6) | |||
pid_list="$(printf "%s\n" "${log_content}" | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}')" | |||
for pid in ${pid_list} | |||
do | |||
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)}')" | |||
done | |||
;; | |||
esac | |||
for ip in ${src_addon} | |||
do | |||
if [ -z "$(grep -F "${ip}" "${src_url}")" ] | |||
then | |||
printf '\n%s\n' "${ip}" >> "${tmp_load}" | |||
printf '\n%s\n' "${ip}" >> "${src_url}" | |||
fi | |||
done | |||
elif [ -n "${src_cat}" ] | |||
then | |||
if [ "${src_cat//[0-9]/}" != "${src_cat}" ] | |||
then | |||
for as in ${src_cat} | |||
do | |||
src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}AS${as}" 2>&1)" | |||
ban_rc=${?} | |||
if [ ${ban_rc} -eq 0 ] | |||
then | |||
jsonfilter -i "${tmp_raw}" -e '@.data.prefixes.*.prefix' 2>/dev/null >> "${tmp_load}" | |||
else | |||
break | |||
fi | |||
done | |||
else | |||
for co in ${src_cat} | |||
do | |||
src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}${co}&v4_format=prefix" 2>&1)" | |||
ban_rc=${?} | |||
if [ ${ban_rc} -eq 0 ] | |||
then | |||
if [ "${src_name##*_}" = "6" ] | |||
then | |||
jsonfilter -i "${tmp_raw}" -e '@.data.resources.ipv6.*' 2>/dev/null >> "${tmp_load}" | |||
else | |||
jsonfilter -i "${tmp_raw}" -e '@.data.resources.ipv4.*' 2>/dev/null >> "${tmp_load}" | |||
fi | |||
else | |||
break | |||
fi | |||
done | |||
fi | |||
else | |||
src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}" 2>&1)" | |||
ban_rc=${?} | |||
if [ ${ban_rc} -eq 0 ] | |||
then | |||
zcat "${tmp_raw}" 2>/dev/null > "${tmp_load}" | |||
ban_rc=${?} | |||
if [ ${ban_rc} -ne 0 ] | |||
then | |||
mv -f "${tmp_raw}" "${tmp_load}" | |||
ban_rc=${?} | |||
fi | |||
fi | |||
fi | |||
if [ ${ban_rc} -eq 0 ] | |||
then | |||
awk "${src_rset}" "${tmp_load}" 2>/dev/null | sort -u > "${tmp_file}" | |||
ban_rc=${?} | |||
if [ ${ban_rc} -eq 0 ] | |||
then | |||
f_ipset create | |||
else | |||
f_ipset refresh | |||
fi | |||
else | |||
src_log="$(printf '%s' "${src_log}" | awk '{ORS=" ";print $0}')" | |||
f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${ban_rc}, log: ${src_log:-"-"}" | |||
f_ipset refresh | |||
fi | |||
) & | |||
hold=$(( cnt % ban_maxqueue )) | |||
if [ ${hold} -eq 0 ] | |||
then | |||
wait | |||
fi | |||
cnt=$(( cnt + 1 )) | |||
done | |||
wait | |||
if [ ${ban_rc} -eq 0 ] | |||
then | |||
for cnt in $(cat ${ban_tmpfile}.*.setcnt 2>/dev/null) | |||
do | |||
ban_setcnt=$(( ban_setcnt + cnt )) | |||
done | |||
for cnt in $(cat ${ban_tmpfile}.*.cnt 2>/dev/null) | |||
do | |||
ban_cnt=$(( ban_cnt + cnt )) | |||
done | |||
f_log "info" "${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes loaded successfully (${ban_sysver})" | |||
fi | |||
f_jsnup | |||
f_rmtemp | |||
exit ${ban_rc} | |||
} | |||
# update runtime information | |||
# | |||
f_jsnup() | |||
{ | |||
local rundate="$(/bin/date "+%d.%m.%Y %H:%M:%S")" status="${1:-"enabled"}" | |||
ban_cntinfo="${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes" | |||
json_add_string "status" "${status}" | |||
json_add_string "version" "${ban_ver}" | |||
json_add_string "fetch_info" "${ban_fetchinfo:-"-"}" | |||
json_add_string "ipset_info" "${ban_cntinfo:-"-"}" | |||
json_add_string "last_run" "${rundate:-"-"}" | |||
json_add_string "system" "${ban_sysver}" | |||
json_dump > "${ban_rtfile}" | |||
f_log "debug" "f_jsnup ::: status: ${status}, setcnt: ${ban_setcnt}, cnt: ${ban_cnt}" | |||
} | |||
# source required system libraries | |||
# | |||
if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ] | |||
then | |||
. "/lib/functions.sh" | |||
. "/lib/functions/network.sh" | |||
. "/usr/share/libubox/jshn.sh" | |||
else | |||
f_log "err" "system libraries not found" | |||
fi | |||
# initialize json runtime file | |||
# | |||
json_load_file "${ban_rtfile}" >/dev/null 2>&1 | |||
json_select data >/dev/null 2>&1 | |||
if [ ${?} -ne 0 ] | |||
then | |||
> "${ban_rtfile}" | |||
json_init | |||
json_add_object "data" | |||
fi | |||
# handle different banIP actions | |||
# | |||
f_envload | |||
case "${ban_action}" in | |||
stop) | |||
f_jsnup stopped | |||
f_ipset destroy | |||
f_rmtemp | |||
;; | |||
start|restart|reload) | |||
f_envcheck | |||
f_main | |||
;; | |||
esac |