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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to