banip: update 1.8.9-2 master
authorDirk Brenken <redacted>
Sun, 21 Jun 2026 16:43:35 +0000 (18:43 +0200)
committerDirk Brenken <redacted>
Sun, 21 Jun 2026 16:46:38 +0000 (18:46 +0200)
default feed updates:
- urlhaus, urlvir, webclient: switched from in to out
  and added a tcp udp 80 443 port limit (destination feeds for LAN-initiated traffic)
- feodo, spamhaus, threat, threatview, proxy, tor, vpn, vpndc: switched from in to inout
- threatview: added url_6, as the source ships IPv4 and IPv6 in a single file
- country / asn: intentionally left on in; documented how to switch them to outbound/both
  for the recurring "block connections to country X" case
- readme update:
  - corrected the feed table to match the above,
  - removed the stale drop row (replaced by spamhaus),
  - and reworked the chain explanation to clarify the inbound-vs-outbound (source-IP vs destination-IP) model
  - significantly expanded the custom-feeds section (all JSON fields, rule parameters, etc.

Signed-off-by: Dirk Brenken <redacted>
net/banip/Makefile
net/banip/files/README.md
net/banip/files/banip.feeds

index 6a042837e8f53570d0b47dfc3c9b96fc149d5fb0..a35d88e9f61009de770c5658eacd0e917c1f5c37 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=banip
 PKG_VERSION:=1.8.9
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
 
index 8e32c7389e425c398b2a445fa2068d6f06033739..7a838eef5f4cdebe815e0097de06a4e627088cc4 100644 (file)
@@ -39,11 +39,14 @@ For a typical setup these few steps are enough to get banIP up and running — s
 <a id="main-features"></a>
 ## Main Features
 * banIP supports the following fully pre-configured IP blocklist feeds (free for private usage, for commercial use please check their individual licenses).
-**Please note:** By default, each feed blocks the packet flow in the chain shown in the table below. _Inbound_ combines the chains WAN-Input and WAN-Forward, _Outbound_ represents the LAN-FWD chain:
+**Please note:** By default, each feed blocks the packet flow in the chain(s) shown in the table below. _Inbound_ combines the chains WAN-Input and WAN-Forward, _Outbound_ represents the LAN-FWD chain:
   * WAN-INP chain applies to packets from internet to your router
   * WAN-FWD chain applies to packets from internet to other local devices (not your router)
   * LAN-FWD chain applies to local packets going out to the internet (not your router)
-  The listed standard assignments can be changed to your needs under the `Feed/Set Settings` config tab.
+
+  How to read the default direction: most reputation feeds list the **source** IPs of attackers, scanners and spammers — those are blocked _inbound_, because the unwanted connection is initiated **from the internet towards you**. A second group of feeds lists IPs that your **own clients should never talk to** (malware hosting, command-and-control servers, threat/DoH/DNS endpoints); those are blocked _outbound_ in the LAN-FWD chain, because the connection is initiated **from your LAN**. Feeds where both risks apply (e.g. spamhaus, emerging threats, tor, proxy, vpn) default to **both** directions. This distinction matters: a feed of malware-download or C2 IPs in the _inbound_ chain alone provides little protection, because your LAN client is the one initiating the connection — see the `country`/`asn` note in the [Best practise](#best-practise-and-tweaks) section for the common "block a country" case.
+
+  The listed standard assignments can be changed to your needs under the `Feed/Set Settings` config tab (options `ban_feedin`, `ban_feedout`, `ban_feedinout` and `ban_feedreset`).
 
 | Feed                | Focus                          | Inbound | Outbound | Proto/Port        | Information                                                  |
 | :------------------ | :----------------------------- | :-----: | :------: | :---------------: | :----------------------------------------------------------- |
@@ -58,10 +61,9 @@ For a typical setup these few steps are enough to get banIP up and running — s
 | debl                | fail2ban IP blacklist          |    x    |          |                   | [Link](https://www.blocklist.de)                             |
 | dns                 | public DNS-Server              |         |    x     | tcp, udp: 53, 853 | [Link](https://public-dns.info)                              |
 | doh                 | public DoH-Server              |         |    x     | tcp, udp: 80, 443 | [Link](https://github.com/dibdot/DoH-IP-blocklists)          |
-| drop                | spamhaus drop compilation      |    x    |          |                   | [Link](https://www.spamhaus.org)                             |
 | dshield             | dshield IP blocklist           |    x    |          |                   | [Link](https://www.dshield.org)                              |
 | etcompromised       | ET compromised hosts           |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=et_compromised)    |
-| feodo               | feodo tracker                  |    x    |          |                   | [Link](https://feodotracker.abuse.ch)                        |
+| feodo               | feodo tracker                  |    x    |    x     |                   | [Link](https://feodotracker.abuse.ch)                        |
 | firehol1            | firehol level 1 compilation    |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=firehol_level1)    |
 | firehol2            | firehol level 2 compilation    |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=firehol_level2)    |
 | firehol3            | firehol level 3 compilation    |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=firehol_level3)    |
@@ -73,21 +75,21 @@ For a typical setup these few steps are enough to get banIP up and running — s
 | ipsum               | malicious IPs                  |    x    |          |                   | [Link](https://github.com/stamparm/ipsum)                    |
 | ipthreat            | hacker and botnet IPs          |    x    |          |                   | [Link](https://ipthreat.net)                                 |
 | myip                | real-time IP blocklist         |    x    |          |                   | [Link](https://myip.ms)                                      |
-| proxy               | open proxies                   |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=proxylists)        |
-| spamhaus            | Spamhaus DROP                  |    x    |          |                   | [Link](https://www.spamhaus.org/blocklists/)                 |
-| threat              | emerging threats               |    x    |          |                   | [Link](https://rules.emergingthreats.net)                    |
-| threatview          | malicious IPs                  |    x    |          |                   | [Link](https://threatview.io)                                |
-| tor                 | tor exit nodes                 |    x    |          |                   | [Link](https://www.dan.me.uk)                                |
+| proxy               | open proxies                   |    x    |    x     |                   | [Link](https://iplists.firehol.org/?ipset=proxylists)        |
+| spamhaus            | Spamhaus DROP                  |    x    |    x     |                   | [Link](https://www.spamhaus.org/blocklists/)                 |
+| threat              | emerging threats               |    x    |    x     |                   | [Link](https://rules.emergingthreats.net)                    |
+| threatview          | malicious IPs                  |    x    |    x     |                   | [Link](https://threatview.io)                                |
+| tor                 | tor exit nodes                 |    x    |    x     |                   | [Link](https://www.dan.me.uk)                                |
 | turris              | turris sentinel blocklist      |    x    |          |                   | [Link](https://view.sentinel.turris.cz)                      |
 | uceprotect1         | spam protection level 1        |    x    |          |                   | [Link](https://www.uceprotect.net/en/index.php)              |
 | uceprotect2         | spam protection level 2        |    x    |          |                   | [Link](https://www.uceprotect.net/en/index.php)              |
 | uceprotect3         | spam protection level 3        |    x    |          |                   | [Link](https://www.uceprotect.net/en/index.php)              |
-| urlhaus             | urlhaus IDS IPs                |    x    |          |                   | [Link](https://urlhaus.abuse.ch)                             |
-| urlvir              | malware related IPs            |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=urlvir)            |
-| webclient           | malware related IPs            |    x    |          |                   | [Link](https://iplists.firehol.org/?ipset=firehol_webclient) |
+| urlhaus             | urlhaus IDS IPs                |         |    x     | tcp, udp: 80, 443 | [Link](https://urlhaus.abuse.ch)                             |
+| urlvir              | malware related IPs            |         |    x     | tcp, udp: 80, 443 | [Link](https://iplists.firehol.org/?ipset=urlvir)            |
+| webclient           | malware related IPs            |         |    x     | tcp, udp: 80, 443 | [Link](https://iplists.firehol.org/?ipset=firehol_webclient) |
 | voip                | VoIP fraud blocklist           |    x    |          |                   | [Link](https://voipbl.org)                                   |
-| vpn                 | vpn IPs                        |    x    |          |                   | [Link](https://github.com/X4BNet/lists_vpn)                  |
-| vpndc               | vpn datacenter IPs             |    x    |          |                   | [Link](https://github.com/X4BNet/lists_vpn)                  |
+| vpn                 | vpn IPs                        |    x    |    x     |                   | [Link](https://github.com/X4BNet/lists_vpn)                  |
+| vpndc               | vpn datacenter IPs             |    x    |    x     |                   | [Link](https://github.com/X4BNet/lists_vpn)                  |
 
 * Zero-conf like automatic installation & setup, usually no manual changes needed
 * All Sets are handled in a separate nft table/namespace `banIP`
@@ -390,6 +392,32 @@ The following feeds are just my personal recommendation as an initial setup:
 In total, this feed selection blocks about 20K IP addresses. It may also be useful to include some countries to the country feed.
 Please note: don't just blindly activate (too) many feeds at once, sooner or later this will lead to OOM conditions.
 
+**Feed direction (inbound vs. outbound) — and the country/ASN case**  
+This is the single most common source of confusion, so it's worth understanding the model before you pick feeds.
+
+banIP filters on the **connection level** (source/destination IP), not on content. The default chain of a feed therefore has to match **who initiates the unwanted connection**:
+
+* **Inbound** (WAN-Input + WAN-Forward): blocks connections that come **from the internet towards you**. This is the right direction for the large majority of reputation feeds, which list the **source** IPs of attackers, scanners, brute-forcers and spam senders (`cinsscore`, `debl`, `dshield`, `firehol*`, `bruteforceblock`, `uceprotect*`, …). A fail2ban-style feed only makes sense inbound.
+* **Outbound** (LAN-Forward): blocks connections your **own LAN clients initiate towards** a listed IP. This is the right direction for feeds that list destinations your devices should never reach: malware-download hosts, command-and-control servers, DoH/DNS bypass endpoints and threat IPs (`doh`, `dns`, `hagezi`, `feodo`, `urlhaus`, `urlvir`, `webclient`).
+* **Both**: feeds where the risk genuinely exists in both directions default to `inout` (`spamhaus`, `threat`, `threatview`, `tor`, `proxy`, `vpn`, `vpndc`).
+
+The classic mistake: enabling a malware-URL / C2 feed like `urlhaus` in the **inbound** chain and expecting it to stop a LAN client from downloading malware. It won't — the client is the one opening the connection, so only the **outbound** chain can intercept it. These feeds ship with sensible defaults (outbound or both), but if you maintain your own custom feeds, keep this rule of thumb in mind.
+
+**The country/ASN case:** the `country` and `asn` feeds default to the **inbound** chain. This blocks traffic *from* the selected country/ASN towards you — the typical "keep attackers from region X out" use case. If your goal is instead to stop your **own clients from reaching** a country or ASN (the recurring "block all connections *to* country X" request), inbound alone does nothing for you. Switch the feed to the outbound or both chain:
+
+* via LuCI: `Feed/Set Settings` → move the feed into `Outbound` or `Inbound + Outbound`
+* via CLI in `/etc/config/banip`:
+
+```
+# block outbound connections to the selected countries as well as inbound
+list ban_feedinout 'country'
+
+# or restrict the country feed exclusively to the outbound (LAN-FWD) chain
+list ban_feedout 'country'
+```
+
+Be aware that bidirectional country blocking on large countries quickly inflates element counts and memory usage; consider `ban_countrysplit`/`ban_asnsplit` and the low-memory tweaks above.
+
 **Log Terms for logfile parsing**  
 Like fail2ban and crowdsec, banIP supports logfile scanning and automatic blocking of suspicious attacker IPs.
 In the default config only the log terms to detect failed login attempts via dropbear and LuCI are in place. The following search pattern has been tested as well:
@@ -550,8 +578,9 @@ For a regular, automatic update of the used feeds or other regular banIP tasks (
 By default banIP scans the logfile via logread, so to monitor attacks on asterisk, its security log must be available via logread. To do this, edit `/etc/asterisk/logger.conf` and add the line `syslog.local0 = security`, then run `asterisk -rx reload logger` to update the running asterisk configuration.
 
 **Change/add banIP feeds and set optional feed flags**  
-The banIP default blocklist feeds are stored in an external JSON file `/etc/banip/banip.feeds`. All custom changes should be stored in an external JSON file `/etc/banip/banip.custom.feeds` (empty by default). It's recommended to use the LuCI based Custom Feed Editor to make changes to this file.
-A valid JSON source object contains the following information, e.g.:
+The banIP default blocklist feeds are stored in an external JSON file `/etc/banip/banip.feeds`. This file is shipped with the package and is **overwritten on every package update**, so never edit it directly. All of your custom changes belong in the separate JSON file `/etc/banip/banip.custom.feeds` (empty by default), which is preserved across updates. It's recommended to use the LuCI based Custom Feed Editor (`Custom Feed Editor`tab), which validates the JSON for you.  
+
+A feed is a single JSON object, keyed by a unique feed name (no spaces, no special characters). Example:
 
 ```json
        [...]
@@ -566,14 +595,52 @@ A valid JSON source object contains the following information, e.g.:
        [...]
 ```
 
-Add an unique feed name (no spaces, no special chars) and make the required changes: adapt at least the URL, check/change the rule, the size and the description for a new feed.
-The rule consist of max. 4 individual, space separated parameters:
-1. type: `feed` or `suricata` (required)
-2. prefix: an optional search term (a string literal, no regex) to identify valid IP list entries
-3. column: the IP column within the feed file, e.g. `1` (required)
-4. separator: an optional field separator, default is the character class `[[:space:]]`
-
-Please note: the flag field is optional, it's a space separated list of options: supported are `gz` as an archive format and protocols `tcp` or `udp` with port numbers/port ranges for destination port limitations.
+The object supports the following fields:
+
+| Field   | Required | Description                                                                                                              |
+| :------ | :------: | :--------------------------------------------------------------------------------------------------------------------- |
+| url_4   | yes\*    | download URL of the IPv4 list. \*at least one of `url_4`/`url_6` must be present                                         |
+| url_6   | yes\*    | download URL of the IPv6 list. May point to the **same** URL as `url_4` if the source mixes IPv4 and IPv6 in one file   |
+| rule    | yes      | the parsing ruleset, max. 4 space separated parameters (see below)                                                      |
+| chain   | yes      | the default chain/direction: `in`, `out` or `inout` (see below)                                                         |
+| descr   | yes      | a short human-readable description shown in LuCI and the feed table                                                     |
+| flag    | no       | optional, space separated list of extra options: archive format and/or protocol/port limitations (see below)           |
+
+**The `url_4` / `url_6` fields**  
+Each address family is fetched and processed independently. Three cases:
+* IPv4-only source: set `url_4` only, omit `url_6`
+* separate IPv4 and IPv6 files: set both to their respective URLs (e.g. `doh`, `spamhaus`)
+* a single dual-stack file that mixes v4 and v6 entries: point both `url_4` and `url_6` at that same URL. banIP fetches it only once and process it for each family and the per-family regex extracts the matching addresses; the non-matching lines are simply ignored. (e.g. `threatview`, which ships v4 and v6 in one file).
+
+**The `rule` field**  
+The rule consists of max. 4 individual, space separated parameters:
+1. **type**: `feed` or `suricata` (required)
+   * `feed`: a plain IP/CIDR list, one entry per line (the common case)
+   * `suricata`: a Suricata/Snort-style ruleset; banIP extracts the IPs out of the rule lines
+2. **prefix**: an optional search term (a literal string, not a regex) that a line must contain to be considered a valid entry. Use it to skip comment/header lines or to pick only the relevant rows. Omit it if every data line is a bare IP.
+3. **column**: the 1-based column that holds the IP within a matching line, e.g. `1` for a bare list or `13` for the dshield block file (required)
+4. **separator**: an optional field separator; default is the whitespace character class `[[:space:]]`. Pass a literal character such as `,` for comma-separated sources (e.g. turris).
+
+**The `chain` field**  
+Defines the default blocking direction. See the [Best practise feed-direction note](#best-practise-and-tweaks) for the reasoning behind each value:
+* `in`: inbound only (WAN-Input + WAN-Forward). Use for source-IP reputation feeds (attackers, scanners, spam senders).
+* `out`: outbound only (LAN-Forward). Use for destination feeds your own clients should never reach (malware hosts, C2, DoH/DNS endpoints).
+* `inout`: both directions. Use when the risk genuinely exists on both sides (e.g. spamhaus, tor, proxy, vpn).
+
+This is only the **default**; a user can always override it at runtime per feed via `ban_feedin` / `ban_feedout` / `ban_feedinout`, or strip a feed's port/protocol limitation via `ban_feedreset` — without touching the feed JSON.
+
+**The `flag` field (optional)**  
+A space separated list of extra options:
+* `gz`: the source is gzip-compressed and will be decompressed before parsing (e.g. `backscatterer`, `ipthreat`, `uceprotect*`)
+* protocol/port limitation — one or both of `tcp` / `udp` followed by one or more destination ports or port ranges. This restricts the feed's rules to those destination ports, which is mainly useful for outbound feeds to cut false positives.  
+Examples:  
+  * `tcp udp 80 443`: limit to HTTP/HTTPS (e.g. `doh`, `hagezi`, `feodo`, `urlhaus`, `urlvir`, `webclient`)
+  * `tcp udp 53 853`: limit to plain DNS and DNS-over-TLS (e.g. `dns`)
+  * `tcp 22`: limit to SSH
+  * `tcp 5060-5061 udp 5060`: mix of single ports and ranges
+  * `gz` and a port limitation can be combined, e.g. `gz tcp udp 80 443`
+
+After editing `/etc/banip/banip.custom.feeds`, reload banIP (`/etc/init.d/banip reload`) and check the `Processing Log` tab — a malformed JSON object or a wrong column/separator typically shows up there as a feed that loads zero elements.
 
 <a id="troubleshooting-and-debug-options"></a>
 ## Troubleshooting & debug options
index f91cf87dc7cbbc618c64f686c53e8a9251a04036..eb324e7a40b097a144e421c438b463c4de5ea751 100644 (file)
@@ -89,7 +89,7 @@
        "feodo":{
                "url_4": "https://feodotracker.abuse.ch/downloads/ipblocklist.txt",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "feodo tracker"
        },
        "firehol1":{
        "proxy":{
                "url_4": "https://iplists.firehol.org/files/proxylists.ipset",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "open proxies"
        },
        "spamhaus":{
                "url_4": "https://www.spamhaus.org/drop/drop_v4.json",
                "url_6": "https://www.spamhaus.org/drop/drop_v6.json",
                "rule": "feed 4 \"",
-               "chain": "in",
+               "chain": "inout",
                "descr": "Spamhaus DROP"
        },
        "threat":{
                "url_4": "https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "emerging threats"
        },
        "threatview":{
                "url_4": "https://threatview.io/Downloads/IP-High-Confidence-Feed.txt",
+               "url_6": "https://threatview.io/Downloads/IP-High-Confidence-Feed.txt",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "malicious IPs"
        },
        "tor":{
                "url_4": "https://www.dan.me.uk/torlist/?exit",
                "url_6": "https://www.dan.me.uk/torlist/?exit",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "tor exit nodes"
        },
        "turris":{
        "urlhaus":{
                "url_4": "https://urlhaus.abuse.ch/downloads/ids/",
                "rule": "suricata 1",
-               "chain": "in",
-               "descr": "urlhaus IDS IPs"
+               "chain": "out",
+               "descr": "urlhaus IDS IPs",
+               "flag": "tcp udp 80 443"
        },
        "urlvir":{
                "url_4": "https://iplists.firehol.org/files/urlvir.ipset",
                "rule": "feed 1",
-               "chain": "in",
-               "descr": "malware related IPs"
+               "chain": "out",
+               "descr": "malware related IPs",
+               "flag": "tcp udp 80 443"
        },
        "voip":{
                "url_4": "https://voipbl.org/update/",
        "vpn":{
                "url_4": "https://raw.githubusercontent.com/X4BNet/lists_vpn/refs/heads/main/output/vpn/ipv4.txt",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "vpn IPs"
        },
        "vpndc":{
                "url_4": "https://raw.githubusercontent.com/X4BNet/lists_vpn/refs/heads/main/output/datacenter/ipv4.txt",
                "rule": "feed 1",
-               "chain": "in",
+               "chain": "inout",
                "descr": "vpn datacenter IPs"
        },
        "webclient":{
                "url_4": "https://iplists.firehol.org/files/firehol_webclient.netset",
                "rule": "feed 1",
-               "chain": "in",
-               "descr": "malware related IPs"
+               "chain": "out",
+               "descr": "malware related IPs",
+               "flag": "tcp udp 80 443"
        }
 }
git clone https://git.99rst.org/PROJECT