
easywall v2.7.0
Web interface for the nftables firewall on Linux, written in Go. The apply undoes itself after 120 seconds unless you confirm it — you cannot lock yourself out. Debian & Docker install.
easywall
Your firewall. Your rules. No surprises.
Live demo · Documentation · Changelog
nftables through a web interface that cannot lock you out: every apply reverts itself unless you confirm it.
The idea
Editing a rule changes nothing. Applying it changes everything — for 120 seconds. If the new rules cut your connection you cannot click Confirm, and not confirming is what brings the old rules back.
Architecture
Two processes. The one exposed to the network holds no privilege worth stealing.
A complete rewrite of the original easywall — Python, Flask, iptables via
subprocess — which was archived in 2022 after a CVE. Both root causes are gone:
the privileges live in a different process, and the apply path builds Go structs
instead of a command line. How it works →
Install
# Debian / Ubuntu — amd64 and arm64
ARCH=$(dpkg --print-architecture)
wget https://github.com/jp1337/easywall/releases/latest/download/easywall_$ARCH.deb
sudo dpkg -i easywall_$ARCH.deb && sudo apt-get install -f
# Docker
git clone https://github.com/jp1337/easywall.git && cd easywall && docker compose up -d
# From source — Go 1.26+, nftables
git clone https://github.com/jp1337/easywall.git && cd easywall
make build && sudo make install
sudo systemctl enable --now easywall-core easywall-web
Then open https://localhost:12227. The first visit
sets up the account and stages the first rules.
What you get
| Ports | TCP and UDP, single or range, with per-rule SSH brute-force routing |
| Blacklist & whitelist | IPv4, IPv6 and CIDR, evaluated before any port rule |
| Protection modules | Twelve, five on by default — floods, scans, bogons, fragments, broadcast/multicast/anycast |
| Port forwarding | NAT redirects with protocol selection |
| Custom rules | Raw nftables, syntax-checked before it is applied |
| Export / import | The whole rule set as JSON |
| Audit log | What changed and when, one JSON object per line |
| Docker coexistence | Owns table inet easywall, touches nothing else |
| English & German | Switchable in the interface, including before sign-in |
| Light & dark | Follows the OS, with a manual toggle; both contrast-checked |
Built with
| Go 1.26, single binary | go-chi/chi · html/template |
nftables via google/nftables | direct netlink, no nft subprocess |
| Argon2id | golang.org/x/crypto, 16-byte salt per password |
| CSRF | net/http.CrossOriginProtection, Go 1.25 native |
| Design system | DESIGN.md + Tailwind v4 — no third-party UI library |
| Fonts | Inter + JetBrains Mono, self-hosted, ~145 KB — works air-gapped |
| CI | govulncheck, gosec, CodeQL, -race, and an integration suite against a real kernel |
Roadmap
Correctness first: a firewall that quietly does less than it says is worse than one that does less and says so.
| 2.6 | Integration tests that assert meaning, not rule counts |
| 2.7 | Identity — a user in the socket protocol, then login events, then multiple accounts, then 2FA |
| 2.8 | A REST API with token auth, ACME as an option, opt-in trusted reverse proxy |
| 2.9 | An opt-in count of installations |
Why each comes when it does, and what the count would send: Roadmap →
Getting help
| A question, or something not behaving | Discord |
| A bug, or a feature you want | GitHub issues |
| A security vulnerability | Security advisory — not Discord, and not a public issue |
Contributing
Setup, commit conventions and the review checklist: CONTRIBUTING.md.
Anything visual goes through DESIGN.md first.
Security issues: not as a public issue — use GitHub Security Advisories.
License
GPL-3.0 — see LICENSE.