The moment a homelab exposes anything to the internet, the logs fill with strangers: bots trying passwords on SSH, scanners probing for admin pages, automated tools hammering login forms of every self-hosted app they recognise. Most of it fails harmlessly, but it is noise, it wastes resources, and occasionally it finds a weak password. Blocking repeat offenders automatically is one of the standard layers of defence.
Fail2ban has done that job for two decades. CrowdSec is the newer alternative that adds shared threat intelligence and a different architecture. For a homelab sitting behind a reverse proxy, the choice is less about which is “better” and more about where the blocking can actually happen, because a reverse proxy changes what the blocking tool sees.
Two ways to ban a bad actor
Fail2ban watches log files on a machine. Each “jail” pairs a filter, a set of patterns that recognise failures such as wrong SSH passwords or failed web logins, with an action, typically adding a firewall rule that bans the offending IP address for a period. It is simple, mature, packaged in every Linux distribution, and works one machine at a time.
CrowdSec separates detection from blocking. An agent reads logs, parses them, and matches “scenarios” such as brute force attempts, scans or known exploit patterns, many available from its public hub. When a scenario triggers, CrowdSec makes a “decision” to ban an address. Separate components called bouncers enforce decisions wherever you put them: in the host firewall, in a reverse proxy such as Nginx, Traefik or Caddy, or at a cloud edge. Participating installations share anonymised signals about attackers and in return receive a community blocklist of addresses already attacking others.
| CrowdSec | Fail2ban | |
|---|---|---|
| Detection | Parsers and scenarios from a shared hub | Regex filters per jail |
| Blocking | Bouncers in firewall, reverse proxy or cloud edge | Actions, usually local firewall rules |
| Shared threat data | Community blocklist | None by default |
| Multiple machines | One central API, many agents and bouncers | Each machine on its own |
| Resource use | Light, a little more than Fail2ban | Very light |
| Learning curve | Moderate: agents, collections, bouncers | Low for common jails |
The reverse proxy problem
In a typical homelab, every web app sits behind a reverse proxy such as Caddy, Traefik or Nginx Proxy Manager. That has two consequences for blocking.
First, the apps see the proxy’s address, not the attacker’s, unless they are configured to trust forwarded headers. A Fail2ban jail watching an app’s own log may only ever see the proxy’s IP, and banning that would block everyone.
Second, banning at the app server’s firewall does nothing if the traffic arrives through the proxy on another machine. The ban has to happen where connections enter: on the proxy host’s firewall, or inside the proxy itself.
Fail2ban can handle this by watching the reverse proxy’s access logs, which contain real client addresses, and banning on the proxy host. That works well when the proxy and Fail2ban are on the same machine and logs are in a format your filters understand.
CrowdSec was designed for this layout. Its agent can read the proxy’s logs, and a bouncer installed in the proxy or on the proxy host blocks requests from banned addresses before they reach any app. With several machines, one central CrowdSec instance can collect detections from agents everywhere and push decisions to every bouncer. Choosing the proxy itself is covered in Caddy vs Nginx Proxy Manager.

Cloudflare Tunnel and other front doors
Many homelabs avoid opening ports entirely by using Cloudflare Tunnel or a similar service. Traffic then arrives at your proxy from the tunnel, not from the attacker directly, so host firewall bans are useless: every request appears to come from the tunnel connector. Blocking must happen either at the proxy, using the real client address passed in headers, or at the edge service itself.
CrowdSec has bouncers that work with Cloudflare’s firewall rules, pushing bans to the edge so blocked traffic never reaches your network. Fail2ban can do something similar with custom actions that call Cloudflare’s API, but it requires more scripting.
Shared blocklists: help or hype?
CrowdSec’s community blocklist is its distinctive feature. Addresses that many installations report for aggressive behaviour are added to a list your bouncers can block before the address ever touches your services. In practice, this cuts a large share of the background noise from scanners and brute-force bots on day one.
There are trade-offs. Your installation shares signals about attacks it sees, in anonymised form, which you should be comfortable with. The free community list is a curated subset; larger lists are part of paid offerings. And blocklists cannot stop targeted attacks from fresh addresses, so they reduce noise rather than replace good passwords, updates and two-factor authentication.
Fail2ban has no shared intelligence by default. It only bans addresses after they fail on your own services.
SSH: still the classic case
The most common Fail2ban jail protects SSH, and it remains effective. CrowdSec covers SSH equally well with its standard collection. But for a homelab, the better answer to SSH brute force is often to stop exposing SSH at all: put it behind a VPN or mesh network, and use key authentication only. That approach is explained in Tailscale SSH vs opening port 22. If SSH is only reachable over a private network, banning becomes unnecessary for it.

Protecting self-hosted app logins
Web apps are the more interesting target. Password managers, photo servers, file sync and dashboards all have login pages, and some have had vulnerabilities. Both tools can watch login failures, as long as the app logs them with the client’s real address.
CrowdSec’s hub includes collections for many popular self-hosted apps and reverse proxies, with parsers that understand their log formats and scenarios for brute force and probing. Fail2ban has filters for common services and a community of user-contributed filters for others, though you may need to write or adapt a regex for newer apps.
In both cases, check that bans actually work: trigger a few failed logins from a phone on mobile data, and confirm the address is blocked and then released.
Running it across several machines
With one exposed machine, the difference is small. With several, such as a reverse proxy host, a mail server and a VPS, CrowdSec’s central model helps: one place to see all detections, and a ban decided on one machine is enforced on all of them. Its free web console adds a dashboard of alerts across installations if you want it.
Fail2ban runs independently on each machine. You can share bans with custom actions or scripts, but it is not built for it.
Running costs and upkeep
Fail2ban is very light and needs almost no maintenance once jails are configured; the main task is checking that log paths still match after software updates.
CrowdSec is also light, written in Go, with modest memory use. It has more parts to update: the agent, collections from the hub, and bouncers. Updating hub collections regularly keeps detection current. Both need you to whitelist your own addresses, so you do not lock yourself out after mistyping a password a few times.
A first afternoon with CrowdSec behind Caddy or Traefik
For readers leaning towards CrowdSec, a typical first setup looks like this:
- Install the CrowdSec agent on the reverse proxy host, or as a container that can read the proxy’s access logs.
- Install the collections for your proxy and for the apps you expose, plus the base Linux and SSH collections.
- Add a bouncer: the firewall bouncer on the proxy host, or a bouncer plugin inside the proxy itself.
- Whitelist your home network and VPN ranges.
- Run the metrics and decisions commands to confirm logs are being parsed and that decisions appear when you trigger failures.
Within an hour or two, the dashboard shows which scenarios fire most and how much of the community blocklist is already stopping connections.
Mistakes that make either useless
- Banning the proxy. Watching app logs that only see the proxy’s address, then banning it. Watch the proxy’s logs or configure trusted forwarding headers.
- Banning in the wrong place. Blocking on an app server when traffic enters through a proxy or tunnel elsewhere.
- Containers bypassing the host firewall. Docker publishes ports with its own firewall rules, which can bypass bans added in some chains. Use bouncers or actions that target the right chain, or block at the proxy.
- No whitelist. Locking out your own home or mobile address.
- Treating it as the only defence. Strong passwords, two-factor authentication, updates and a VPN for admin interfaces matter more.
Which to use
Choose Fail2ban if you have one or two exposed machines, mainly want to stop brute force on SSH or a few services, and like a simple tool that has worked the same way for years. Make sure it watches logs that contain real client addresses and bans where traffic actually enters.
Choose CrowdSec if your homelab sits behind a reverse proxy or a tunnel, you expose several apps or machines, and you want the community blocklist to cut background noise from day one. Its bouncers solve the “where do I block?” problem that trips up Fail2ban in modern setups.
And before either, ask whether the service needs to be public at all. The best ban is a port that was never open.