caddy_fail2ban

package module
v0.0.0-...-33d62c0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2025 License: AGPL-3.0 Imports: 12 Imported by: 0

README

caddy-fail2ban

A simple package to add fail2ban support to caddy. This simple module adds a fail2ban HTTP matcher based on a text file of IP addresses. Forked from Javex/caddy-fail2ban

Problem using fail2ban

when running a double proxy architecture fail2ban would either:

  • ban the upstream proxy, thus cutting every user off from the service (bad) (also just bad header assignment),
  • ban the client, which is meaningless as the client is connected through the proxy and never directly connects to the server (bad)

fail2ban is blocking using firewall rules in iptables or nftables

Solution

Block connections based off of the X-Real-IP or X-Forwarded-For headers in the http (application) layer, but only when the connecting ip is the trusted proxy.

iptables/nftables arnt made to do this sort of behavior, but caddy should

Reason for Fork

The original repo was comparing the connection ip(remote_ip) to the banned ip, this connection ip is the ip directly connecting to the server, rather than the client connecting through a chain of proxies.

So I had the same issue as described above, banning a client that wasnt directly connecting to the server, so banning nothing.

Changes

  1. if trusted proxy, grab ip from X-Real-IP or X-Forwarded-For and do the ban compare with that ip

Not a huge change, but now it works (also until I can figure out how to grab trusted proxy from caddy config, its just hard coded)

This also means a malicious user cant run their own proxy set fake headers and avoid bans

Getting Started

First, make sure to build your caddy with support for this module:

 xcaddy build \
    --with github.com/lukeg32/caddy-fail2ban@main

Then insert this into your Caddyfile:

@banned {
	fail2ban ./banned-ips
}
handle @banned {
	abort
}

The right place for it depends on your setup, but you can find more complete examples in the examples/ directory.

Next, you will need to create the fail2ban action. You can copy the suggested one if you like:

$ cp fail2ban/caddy-banfile.conf /etc/fail2ban/actions.d/caddy-banfile.conf

Now in any of your jails if you want to block requests at the HTTP layer, you can use the action:

action = caddy-banfile[banfile_path="/etc/caddy/banned-ips"]

The above path is the default so you can omit the banfile_path parameter if you like.

Making Changes

If you would like to make your own changes, (ie set the trusted proxy to your own)

  1. clone the repo some where
  2. make your changes to the go files
  3. build xcaddy with local repo
git clone https://github.com/lukeg32/caddy-fail2ban.git

# make your changes to the go files... nvim fail2ban.go

xcadddy build --with github.com/lukeg32/caddy-fail2ban@main=./caddy-fail2ban/

if all is successful it should build caddy with your changes

Running tests

First run the go unit tests, then spin up a docker container to test the integration with fail2ban

go build -v ./...
go test -v ./...

sudo docker build . -t caddy-fail2ban
sudo docker run --rm --name caddy-fail2ban --detach -v $PWD/test/Caddyfile:/etc/caddy/Caddyfile caddy-fail2ban
sudo docker exec -it caddy-fail2ban /usr/local/bin/caddy-fail2ban-test.sh
sudo docker logs caddy-fail2ban
sudo docker stop caddy-fail2ban

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Banlist

type Banlist struct {
	// contains filtered or unexported fields
}

func NewBanlist

func NewBanlist(ctx caddy.Context, logger *zap.Logger, banfile *string) Banlist

func (*Banlist) IsBanned

func (b *Banlist) IsBanned(remote_ip string) bool

func (*Banlist) Reload

func (b *Banlist) Reload()

func (*Banlist) Start

func (b *Banlist) Start()

type Fail2Ban

type Fail2Ban struct {
	Banfile string `json:"banfile"`
	// contains filtered or unexported fields
}

Fail2Ban implements an HTTP handler that checks a specified file for banned IPs and matches if they are found

func (Fail2Ban) CaddyModule

func (Fail2Ban) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*Fail2Ban) Match

func (m *Fail2Ban) Match(req *http.Request) bool

func (*Fail2Ban) Provision

func (m *Fail2Ban) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

func (*Fail2Ban) UnmarshalCaddyfile

func (m *Fail2Ban) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile implements caddyfile.Unmarshaler.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL