Package: fail2ban Version: 0.8.3-2sid1 Severity: important Hi.
I've marked this as important, as it can make fail2ban unusable.
Perhaps the following should also be forwarded upstream.
I've also CC'ed this to the Debian iptables maintainer:
Laurence, please read this,... it might be a good reason why we need
some Debian-standard-iptables-loading-way again (perhaps, but not sure
about this, via an /etc/init.d/iptables script; anyway: using pre-up or
so in the interfaces-file has some drawbacks IMHO).
The default way (especially when one doesn't have own iptables rules)
how fail2ban works is quite fine:
It's started somewhere in /etc/init.d has only its ssh-stuff enabled,
uses iptables-multiport as action, which adds about the following when
starting:
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I INPUT -p <protocol> --dport <port> -j fail2ban-<name>
and removes about the following when stopping:
actionstop = iptables -D INPUT -p <protocol> --dport <port> -j fail2ban-<name>
iptables -F fail2ban-<name>
iptables -X fail2ban-<name>
In this configuration, the actionstop, should never be a problem (even
at complex iptables configurations, there should be no other rule with a
fail2ban-<name> target,.. I think we can assume this).
But the action start is very problematic: It simply appends the fail2ban
rule to the chain.
Now consider a system where I'm using iptables rules like this:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT --destination hilbert.scientia.net --protocol tcp -m tcp
--destination-port ssh --syn -j ACCEPT
COMMIT
These rules might be loaded at any point (e.g. via the pre-up
of /etc/network/interfaces or some selfmade /etc/init.d/iptables
script).
When loading it via pre-up in /etc/network/interfaces these rules are
loaded before fail2ban is startet (which is good, as otherwise
iptables-restore would simply wipe out all fail2ban rules)
1st problem:
Depending on when the iptables rules are loaded, they might overwrite
fail2ban's rules.
Of course we can never fully prevent this, but it should be secured that
in the normal startup this never happens
But right now, fail2bans init.d script has:
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $time $network $syslog iptables firehol shorewall
ipmasq
# Should-Stop: $network $syslog iptables firehol shorewall ipmasq
As far as I understand, this means that neither network
(/etc/init.d/networking) nor the other iptalbes things (btw: what is
iptables? do we have an /etc/init.d/iptables script?!) are certainly
loaded before fail2ban,... they only _should_ be loaded, right?
The same applies for the stopping of fail2ban (more about that later).
2nd problem:
In my scenario above, where I lock anything incomming except ssh,
fail2ban won't work as the rules will look like this:
rule 1: --destination hilbert.scientia.net --protocol tcp -m tcp
--destination-port ssh --syn -j ACCEPT
rule 2: -p tcp --dport ssh -j fail2ban-ssh
Of course the first rule allows already any ssh access and makes
fail2ban useless.
The same scenario can very easily happen in lots of other cases:
- when start/stopping fail2ban manually (vi its init-scripts)
- when the package is upgraded
- perhaps even more
Some solutions to the 1st problem:
This is difficult to solve, as Debian has no default "Debian-way" of
loading iptables-rules, has it?
So one step could be: re-intruduce an /etc/init.d/iptables script, or
make some other default-debian-way, in order that we definitely (ok, at
least when the user goes the debian-way) know when the rules are loaded
during booting.
Once we know this, modify fail2ban's start script accordingly, to
guarantee that iptables is loaded after the iptables rules (and not just
"should").
Some solutions to the 2nd problem:
This is by far more difficult thant the 1st one. I did it the following
way:
1) A usesless hook-rule must be present in the iptables-rules for ANY
(!!!!) protocol used with fail2ban, e.g. with ssh:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT --in-interface lo -j ACCEPT
-A INPUT --in-interface lo -m comment --comment "fail2ban-ssh-hook"
-A INPUT --destination hilbert.scientia.net --protocol tcp -m tcp
--destination-port ssh --syn -j ACCEPT
COMMIT
Of course one MUST use one without a target, and one SHOULD use one that
even then never matches (in order to don't mess up with the counters).
My rule here never matches, as I already have an "-A INPUT
--in-interface lo -j ACCEPT" rule before,.. that matches the same.
2) The action.d-configs for fail2ban must be modified in order to
replace that rule when fail2ban is started, e.g. in
iptables-multiport.conf:
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
rulenum=$( iptables -L INPUT --line-numbers | grep "/\*
fail2ban-<name>-hook \*/" | cut -d " " -f 1 )
iptables -R INPUT ${rulenum} -p <protocol> -m multiport --dports
<port> -j fail2ban-<name>
This replaces the hook rule with the fail2ban rule (and here you see why
we must add hook rules for ANY protocol used with fail2ban, because of
the -<name> thingy).
Of course now we must also replace the actionstop, in order to recreate
our hook-rule (actually ANY hook-rule), e.g. via:
actionstop = rulenum=$( iptables -L INPUT --line-numbers | grep
"fail2ban-<name>" | cut -d " " -f 1 )
iptables -R INPUT ${rulenum} --in-interface lo -m comment
--comment "fail2ban-<name>-hook"
iptables -F fail2ban-<name>
iptables -X fail2ban-<name>
3) As the whole procedure definitely requires user interaction (at least
adding the hook rules, but perhaps adaption of all this to the local
setup), a NEWS file should be written that reflect the changens, and at
every new installation, that process should be user-visibly (e.g. via
debconf) described, or at least pointed to some docs.
4) Possible improvements:
My modifications are still not perfect:
- What happens when the grep gives more results than just one line?
=> the whole thing should fail! (perhaps?!)
- What if the users manually uses iptables-restore before stopping
fail2ban? Will the current actionstop still work (at least not messing
everything up)? Probably not, as the replace will already fail!
=> tighten it against these things
Thanks for your ideas,
Chris.
-- System Information:
Debian Release: 5.0
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.26-1-686 (SMP w/1 CPU core)
Locale: LANG=en_DE.UTF-8, LC_CTYPE=en_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages fail2ban depends on:
ii lsb-base 3.2-20 Linux Standard Base 3.2 init scrip
ii python 2.5.2-3 An interactive high-level object-o
ii python-central 0.6.8 register and build utility for Pyt
Versions of packages fail2ban recommends:
ii iptables 1.4.2-6 administration tools for packet fi
ii whois 4.7.30 an intelligent whois client
Versions of packages fail2ban suggests:
ii bsd-mailx [mailx] 8.1.2-0.20081101cvs-2 A simple mail user agent
pn python-gamin <none> (no description available)
-- no debconf information
smime.p7s
Description: S/MIME cryptographic signature

