Simple python script that can block and unblock IPv4 and IPv6
  • Python 85.2%
  • Shell 14.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-06-16 01:14:29 -03:00
config/nftables Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
docs Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
packaging/systemd Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
scripts Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
src Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
.gitattributes Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
.gitignore Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00
agmh.txt Mirroring with AGMH v0.4.1 2026-06-16 01:14:29 -03:00
LICENSE Initial commit 2026-05-27 06:29:48 -03:00
README.md Initial implementation of nftables REST API with features for banning and unbanning IPv4 and IPv6 addresses, including documentation and systemd service setup. 2026-05-27 09:12:32 -03:00

nftables REST API

Small local REST API for adding and removing IPv4, IPv6, and CIDR entries from nftables block sets.

The project is intentionally minimal: a Python HTTP server bound to 127.0.0.1:9099, a systemd unit, helper scripts, and an example nftables ruleset. It was tested on Debian 13 Trixie on OVH and is intended for local host perimeter control.

Features

  • Blocks and unblocks IPv4 addresses, IPv6 addresses, and CIDR ranges.
  • Uses nftables sets named banned_ipv4 and banned_ipv6.
  • Applies blocks to input, output, and forwarded traffic.
  • Exposes a local HTTP API with optional bearer-token authentication.
  • Includes optional banip and unbanip shell wrappers.

Repository Layout

.
|-- config/
|   `-- nftables/
|       `-- killlist.nft
|-- docs/
|   |-- api.md
|   |-- nftables.md
|   `-- shell-wrappers.md
|-- packaging/
|   `-- systemd/
|       `-- nftables-rest-api.service
|-- scripts/
|   |-- banip
|   `-- unbanip
|-- src/
|   `-- nftables_rest_api.py
|-- LICENSE
`-- README.md

Requirements

  • Linux with nftables support.
  • Python 3.
  • Root privileges, because the API calls /usr/sbin/nft.
  • systemd, if you want to run the API as a service.

Security Notes

  • Keep the API bound to 127.0.0.1 unless you add proper transport security and access controls.
  • The bearer token is sent over plain HTTP. This is acceptable for local-only usage, but it should not be exposed directly on a public interface.
  • If NFT_API_TOKEN is empty, authentication is disabled by the Python script.
  • The sample nftables file starts with flush ruleset, which removes the current nftables ruleset before loading the new one. If the host already has firewall rules, merge the killlist table manually instead of copying the sample file as-is.
  • Bans added through the API are runtime nftables entries. Reloading a ruleset that defines empty sets will remove those runtime entries.

Quick Start

Install dependencies:

sudo apt update
sudo apt install -y nftables python3

Install the example nftables ruleset:

sudo cp config/nftables/killlist.nft /etc/nftables.conf
sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo systemctl enable --now nftables

Install the API script:

sudo install -d -o root -g root -m 755 /opt/nftables-rest-api
sudo install -o root -g root -m 700 src/nftables_rest_api.py /opt/nftables-rest-api/nftables_rest_api.py

Install and configure the systemd service:

sudo install -o root -g root -m 644 packaging/systemd/nftables-rest-api.service /etc/systemd/system/nftables-rest-api.service
sudo nano /etc/systemd/system/nftables-rest-api.service

Replace the placeholder token before starting the service:

Environment=NFT_API_TOKEN=your-long-random-token

Start the API:

sudo systemctl daemon-reload
sudo systemctl enable --now nftables-rest-api

Confirm the API is listening locally:

sudo ss -lntp | grep 9099

Expected result:

LISTEN 0 128 127.0.0.1:9099 0.0.0.0:* users:(("python3",pid=...,fd=...))

API Example

curl -sS \
  -H 'Authorization: Bearer your-long-random-token' \
  --get \
  --data-urlencode 'target=203.0.113.10' \
  'http://127.0.0.1:9099/ban'
{
  "ok": true,
  "target": "203.0.113.10/32",
  "set": "banned_ipv4",
  "action": "ban"
}

Documentation

Troubleshooting

Check the service:

sudo systemctl status nftables-rest-api
sudo journalctl -u nftables-rest-api -f

Check whether nftables accepted the ruleset:

sudo nft -c -f /etc/nftables.conf

List the active sets directly:

sudo nft list set inet killlist banned_ipv4
sudo nft list set inet killlist banned_ipv6

If a request returns 500, read the JSON stderr field. It contains the error reported by nftables, such as attempting to delete an element that is not in the set.

Contributing

Issues and pull requests are welcome. Keep changes small, document behavior that affects operators, and test nftables behavior on a real Linux host before changing the API or ruleset examples.

License

This project is released into the public domain under the Unlicense.