Skip to content

Latest commit

 

History

38 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RegBan

RegBan is a small fail2ban-style tool that reads command output, extracts IP addresses with regular expressions, scores repeated matches, and adds offenders to nftables sets for a configurable amount of time.

It is intentionally narrow. RegBan does not watch files itself, does not manage firewall rules, and does not wake up later to unban addresses. It expects other Unix tools to stream logs into it, and it relies on nftables set timeouts to expire bans.

This project is still a proof of concept. It is useful for experiments and for people comfortable reading the code, but it is not packaged as a polished daemon yet.

How it works

RegBan starts one or more configured commands, usually something like journalctl -f or tail -F. Each line is matched against the configured regular expressions. Patterns use {{ip}} as the capture point for the source address.

When a pattern matches, RegBan:

  1. Parses the IP address.
  2. Adds the pattern score to that address.
  3. Applies score decay over time.
  4. Looks up any extra score from configured IP range tables.
  5. Adds the IP to the configured nftables set when it reaches a ban threshold.

IPv4 and IPv6 are both supported, as long as matching nftables sets are configured.

Building

RegBan uses CMake and depends on libmnl, libnftnl, and yaml-cpp. The repository can build yaml-cpp internally by default.

cmake -S . -B build
cmake --build build --target regban

To use the system yaml-cpp instead:

cmake -S . -B build -DINTERNAL_YAML_CPP=OFF
cmake --build build --target regban

Tests are available through the custom test target:

cmake --build build --target test

nftables setup

Create the sets before starting RegBan. For an inet table named default, a minimal setup looks like this:

sudo nft add table inet default
sudo nft add set inet default blacklistv4 '{ type ipv4_addr; flags timeout; }'
sudo nft add set inet default blacklistv6 '{ type ipv6_addr; flags timeout, interval; }'
sudo nft add rule inet default input ip saddr @blacklistv4 drop
sudo nft add rule inet default input ip6 saddr @blacklistv6 drop

The IPv6 set needs interval because RegBan stores IPv6 bans as small ranges.

Configuration

Start from examples/settings.yml. A typical SSH setup looks like this:

log:
  level: info

cleanupinterval: 3600

nft:
  table: default
  type: inet
  ipv4set: blacklistv4
  ipv6set: blacklistv6

processes:
  - name: sshd
    command: "journalctl -t sshd -f -n 0 -q"
    patterns:
      - pattern: ".* Invalid user .* from {{ip}}.*"
        score: 100
      - pattern: ".* Failed password for .* from {{ip}} .*"
        score: 50
      - pattern: ".* Failed password for root from {{ip}} .*"
        score: 200

rangetables: []

scores:
  decay:
    amount: 10
    per: 3600
  table:
    100:
      bantime: 86400
      score: 0

Score entries are keyed by the lower bound at which they apply. In the example above, an address is banned for one day once its score reaches 100.

Set statefile if you want RegBan to persist current scores between restarts:

statefile: /var/lib/regban/state.yml

Running

Dry-run mode reads logs and prints what it would do without changing nftables:

./build/regban --dry-run examples/settings.yml

Live mode needs permission to talk to netfilter, so it usually runs as root:

sudo ./build/regban /etc/regban/settings.yml

You can also pass configuration on stdin:

cat examples/settings.yml | ./build/regban -

Range tables

Range tables add or subtract score based on CIDR ranges. A range with a score of 0 or less acts as an allow-list entry for matching IPs.

CSV range tables use three columns:

192.0.2.0,24,50
fd00:11::,64,0

IPv4 ranges must be at least /8. IPv6 ranges must be at least /18, because the in-memory index uses the leading address bits.

Current limitations

  • RegBan assumes log streaming is handled by another command.
  • It depends on nftables timeouts for unbanning.
  • IPv6 handling stores and matches the first 64 bits internally.
  • Configuration errors are generally fatal.
  • There is no service unit, package, or install target yet.

The upside is that the moving parts are few: one process reads lines, scores matches, and writes directly to nftables.

About

Lightweight alternative to fail2ban using nftables (banning IPs with failed login attempts)

Topics

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages