Creates iptables rules based on syslog message
C Makefile Shell
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

What is “cfailban”?

cfailban reads input from various sources (typically syslog output), checks it against user-defined regular expressions and adds iptables entries for matches.

It can be used to block brute-force attacks which are trying e.g. to login via SSH.

It features:

  • IPv4 and IPv6 netfilter support
  • customizable expiration of netfilter entries which are blocking IPs
  • customizable trigger rates
  • integrated tests to verify regular expressions
  • reading input from multiple sources (FIFOs and sockets)
  • a customizable whitelist



  • iniparser
  • GNU gengetopt (only build time dependency)
  • a recent Linux system (e.g. RHEL6 is supported, RHEL5 not)

Compilation + Installation

$ make
$ make install [DESTDIR=<dir>]

You might want to set prefix, sbindir or sysconfdir makefile variables too. For older compilers which do not understand -flto flags, you can override them by

$ make C_FLTO= LD_FLTO=

Configuration file

Look into the source tarbal for a sample configuration file cfailban.conf and adapt it to your needs. For future steps, we assume a file like

rate = 1/min
burst = 10
duration = 300

ip4tables_prog = /usr/sbin/iptables
ip6tables_prog = /usr/sbin/ip6tables
chain = chk-BANNED
target = BANNED
manage = true

local0 =
local1 =

type = socket
stype = udp
host =
port = 530

pattern4 = "ip=@HOST@"
resolve4 = true
ban4 = 1

netfilter setup

You have to create both the filter:chain (“chk-BANNED”) and filter:target (“BANNED”) chains in your local netfilter setup. The filter:chain should be called very early and for existing connections too, so top of INPUT would be a suitable place.

The filter:target rule is for rejecting the packets and you might want to do some logging there too.

iptables -N chk-BANNED
iptables -I INPUT 1 -j chk-BANNED
iptables -N BANNED
iptables -A BANNED -j LOG
iptables -A BANNED -j DROP

While testing, you might want to omit the -I INPUT setup to avoid locking out yourself.

syslog setup


destination d_cfailban {
  udp("" port(530));

filter f_cfailban {
  (program("sshd") and 
   message("(authentication failure)|([iI]nvalid user)"));

log { source(localhost); filter(f_cfailban);  destination(d_cfailban); };


$template cfailbanfmt,"%msg%\n"
:programname, isequal, "sshd"	@;cfailbanfmt

testing it

Start program as root by

# cfailban -c failban.conf --debug


$ printf '\n' | nc -u 530

multiple times.

The configuration file

The defaults section

The parser section

The filter section

This section defines various parameters of the netfilter code:

  • the paths of the iptables program (filter:ip4tables and filter:ip6tables)
  • the iptables chain (filter:chain -> “chk-BANNED”) where rules will be created
  • the iptables target (filter:target -> “BANNED”) which must be another chain
  • whether the chain will be managed by us; when it is managed, it will be flushed both on starting and leaving the program

Blocking an ip address means to execute

/usr/sbin/iptables -A chk-BANNED -s <ip> -g BANNED \
  -m comment --coment <rule-name>

The whitelist section

The source sections

FIFO sources

Socket sources

The rule sections

There can be multiple sections having the format rule/<name>. The <name> part specifies an unique name for the rule which is e.g. used as the comment in the netfilter rule later.

The following options are supported:

an extended regular expression which must contain a match group specifying the ip address; this option tries to autodetect the ip family (IPv4 or IPv6)
same like pattern but assumes IPv4
same like pattern but assumes IPv6
the match group index in pattern which specifies the ip address
the match group index in pattern4 which specifies the ip address
the match group index in pattern6 which specifies the ip address
a boolean flag; when set, it is tried to resolve the result from pattern by DNS when it is non-numeric; see warning below…
like resolve, but applies to pattern4 and ban4
like resolve, but applies to pattern6 and ban6
a string of the format <number>/<time-unit>; this setting means, that an internal counter will be incremented by <number> every <time-unit>. On the other site, this counter will be decremented when seeing a corresponding syslog entry and the ip will be blocked when the counter reaches zero.
an absolute integer value which specifies the initial and maximal value of the internal counter
number of seconds which must pass to unblock an ip address

NOTE: you can specify all three pattern types (auto, IPv4 and IPv6) in one rule

WARNING: enabling resolve can slow down parsing of log entries significantly and might be used to attack the failban solution. It is recommended to use numeric ip addresses wherever possible.


This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see