top of page
  • Youtube
  • X
  • TikTok
  • Facebook
  • Instagram
Search

How To Secure Coolify Server with Fail2Ban

  • Writer: Mustafa Ramadan
    Mustafa Ramadan
  • 6 days ago
  • 5 min read

Self-hosting Coolify on a VPS is awesome — it gives you full control and zero limits compared to Vercel or Netlify. But that control comes with responsibility. One of the biggest risks is leaving your server exposed to brute-force, port scans, and bots hammering /wp-login.php or similar paths and admin panels.


In this guide, I’ll show you exactly how I secured my Coolify server using Fail2Ban, even when Traefik is handling all the reverse proxy traffic.


Why Fail2Ban?

Fail2Ban monitors logs for suspicious patterns (e.g. 404s, failed SSH logins) and blocks offending IPs by injecting firewall rules — using iptables or nftables.


Step-by-Step Setup (Tested on Coolify + Ubuntu)


Install Fail2Ban

sudo apt update
sudo apt install fail2ban -y

to confirm your fail2ban is now ready and running on your coolify check it by this:

sudo systemctl status fail2ban

You should see: Active: active (running)


Lets Configure Fail2Ban

Create a local configuration file to customize settings:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

In the [DEFAULT] section, you can adjust parameters like:

• bantime = 1d
• findtime = 10m
• maxretry = 5  

These settings control how long an IP is banned, the time window for counting failures, and the number of retries allowed


Enable SSH Protection

Still in jail.local, ensure the [sshd] section is enabled, by default is already enabled like this:

[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

This configuration helps protect against brute-force SSH attacks.


Restart Fail2Ban

Apply your changes:

sudo systemctl restart fail2ban

Check if sshd jail is active:

sudo fail2ban-client status

You should see something.

Status
|- Number of jail: 1
`- Jail list: sshd

to get more details like "Currently banned IPs: 0 , Log path ,Max retry, find time, etc." run:

sudo fail2ban-client status sshd

Great! At this point, your Coolify server is already protected from brute-force SSH attacks. Fail2Ban is installed, active, and monitoring login attempts in real time. Now let’s take things a step further — it’s time to secure your web layer too. To do that, we need to enable HTTP access logging in Traefik so Fail2Ban can watch and act on suspicious traffic hitting your websites.


Lets Protect Our Websites, Enable Logging in Traefik

Edit your traefik config (command) to enable the access logs:

      - '--accesslog=true'
      - '--accesslog.filepath=/traefik/access.log'
      - '--accesslog.format=json'

Restart Traefik to apply.

This will log access logs in structured JSON to /data/coolify/proxy/access.log (inside the container: /traefik/access.log).


To confirm is working:

tail -f /data/coolify/proxy/access.log

Create Fail2Ban Filter for Traefik

Create /etc/fail2ban/filter.d/traefik-http.conf:

[Definition]
failregex = .*"ClientHost":"<HOST>".*"(404|403|401|429|502|503|504)"
ignoreregex =

Create Jail Config

Edit or create /etc/fail2ban/jail.d/traefik-http.conf:

[traefik-http]
enabled = true
backend = auto
filter = traefik-http
logpath = /data/coolify/proxy/access.log
maxretry = 5
findtime = 60
bantime = 3600
banaction = nftables

Restart Fail2Ban and Check status:

sudo systemctl restart fail2ban
sudo fail2ban-client status traefik-http

to check fail2ban logs run:

sudo cat /var/log/fail2ban.log

Then Fail2Ban uses the default nftables action, which:


  • creates a set in inet f2b-table

  • injects rules into inet filter INPUT

  • drops IPs matching the set


To check the blocked rules in the firewall:

sudo nft list ruleset | grep reject

Or check the actual nftables sets:

sudo nft list set inet f2b-table addr-set-traefik-http
sudo nft list set inet f2b-table addr6-set-traefik-http

Now your Coolify server is protected with real-time IP banning for HTTP/s threats using Fail2Ban and nftables. This setup actively blocks bots and attackers trying to brute-force or probe your apps through Traefik. But why stop there? Let’s level up and extend those bans — so if someone hits your SSH, they also get blocked from all your websites.


Merge Fail2Ban SSH Bans into Traefik Middleware


Fail2Ban is great at blocking brute-force attacks on services like SSH. But what if you want to propagate those bans to your web layer too — for example, block the same IPs at the Traefik level?


Yes, it’s possible — and here’s how we did it in our Coolify setup.


Use the fail2ban Traefik Plugin (Built-in Middleware)

We will use the official Traefik plugin github.com/tomMoulard/fail2ban — this allows us to block IPs directly from within Traefik using a middleware. For more info about the Traefik Plugin:


To install the plugin here’s what we will add to the Coolify-managed docker-compose command for Traefik:

- '--experimental.plugins.fail2ban.modulename=github.com/tomMoulard/fail2ban'
- '--experimental.plugins.fail2ban.version=v0.8.3'

We also enable this middleware on both HTTP and HTTPS routes add them inside the Traefik configuration file:

labels:
 - traefik.http.routers.traefik.middlewares=fail2ban@file
 - traefik.https.routers.traefik.middlewares=fail2ban@file

So even if attackers try hitting /admin or /wp-login.php on HTTPS — they’ll still get blocked.

This enables the plugin. Then, we created a middleware using the plugin that reads denied IPs from a file or config name it : fail2ban.yml

http:
	middlewares:
	fail2ban:
  plugin:
        fail2ban:
          logPath: /traefik/access.log
          maxretry: 5
          findtime: 60
          bantime: 600
          statuscodes:
            - 401
            - 403
            - 404
            - 429
            - 500
            - 502
            - 503
            - 504
	 denylist:
            files:
          - "/traefik/denylist.txt"

Sync Fail2Ban Bans to Traefik

We write a small cronjob or script to export current Fail2Ban bans (e.g. from the sshd jail):

fail2ban-client status sshd | grep 'Banned IP list' | cut -d ':' -f2 | tr ',' '\n' > /data/coolify/proxy/denylist.txt

Then Traefik plugin will automatically pick up new IPs from that file — and apply them instantly.


And we Done... One source of truth (Fail2Ban), multiple layers of protection (SSH + Traefik). Super flexible, and easy to maintain.


Using Cloudflare or Tunnels?

If you’re using Cloudflare or Cloudflared Tunnels, make sure your Traefik setup trusts forwarded headers like X-Forwarded-For — so you can log the real IP address behind the tunnel or proxy. Otherwise, Fail2Ban or Traefik plugins might end up banning 127.0.0.1 or your tunnel instead of the attacker 🚫


If yes then include, the following in Traefik configuration file:

- '--entrypoints.http.forwardedHeaders.trustedIPs=10.0.0.0/8'
- '--entrypoints.https.forwardedHeaders.trustedIPs=10.0.0.0/8'
- '--entrypoints.http.forwardedHeaders.insecure=true'
- '--entrypoints.https.forwardedHeaders.insecure=true'

This lets Traefik read the real client IP even when traffic comes from a reverse proxy.


If you don’t use Cloudflare or any proxy in front of your server — you can safely remove those flags for extra security.


Final Thoughts:

Fail2Ban Works on Coolify, But CrowdSec Works Smarter

While the old school Fail2Ban can secure both SSH and HTTP on your Coolify + Traefik setup, it needs extra scripting to fully protect Docker traffic. It works — but it’s not built for modern stacks like Coolify.


CrowdSec, on the other hand, is designed for today’s web:


  • Native Traefik Bouncer — no hacks, no custom scripts

  • Real-time ban propagation across services

  • Works even behind Cloudflare or Cloudflared tunnels

  • Maintains a global threat intelligence network


Fail2Ban is local, old-school, IP-based and needs work to be cloudflare compatible .

CrowdSec is cloud-native, collaborative, and modern.


So while this guide helps you harden your Coolify server with Fail2Ban, if you want a cleaner, more powerful security layer, go with CrowdSec — it just fits better. Check this guide: Secure Your Coolify Server & Websites with CrowdSec and Traefik



Need Help Securing Your Coolify Server?


I offer hands-on consulting & setup for a rock-solid production server:


  • CrowdSec Firewall + Traefik Bouncer on self-hosting

  • Traefik tuning & performance tweaks

  • SSH hardening & system lockdown

  • Monitoring, alerts & auto-bans

  • Full Coolify install & app deployment


👉 Reach out below — I’ll help you secure your stack the right way.

 
 
 

Comments


Let’s Work Together

Need an experienced IT Professional to help out? Send me an email to discuss in more detail. Alternatively connect with me elsewhere on the web →

  • X
  • Instagram
  • Facebook
  • LinkedIn
  • YouTube
  • TikTok

Handcrafted by me © twentytwentythree. Powered and secured by Wix

bottom of page