Hi Yaroslav, I've prepared an updated patch. Most changes are in comments. The iptables rule which I previously proposed was unnecessarily complicated. Just one line is enough. I've added it as an 'actionstart' rule in the action file. It can be used directly if fail2ban runs as root. If fail2ban runs as non-root, then it won't be able to execute the rule, but anyway it serves as documentation. Also the special rsyslog setup is not necessary -- /var/log/auth.log is owned by group 'adm' by default, so it is enough to add the fail2ban user to this group. OTOH, some more setup for logrotate is necessary.
As you suggested, the fail2ban user is not created automatically, but it is now documented how to add one in the action file comments. An updated introductory blurb and changes to files follow: ------------------------------------------------------------------- Fail2ban currently requires root priviledges to insert iptables rules through calls to /sbin/iptables and also to read the logfiles. Fail2ban can run as an unpriviledged user provided that those two capabilites are preserved. The idea is to run fail2ban as a normal user (e.g. fail2ban) who belongs to a group which is allowed to read logfiles. The user should also be allowed to write to /proc/net/xt_recent/fail2ban-whatever (the name of the file depends on the iptables rules used to create it). /proc/net/xt_recent/* is created by the xt_recent kernel module when an iptables rule with '-m limit' is inserted. This file contains a dynamic list of IP addresses which can than be used in iptables rules. Addresses can be matched against this list, with an optional timeout. One way to use xt_recent is to insert IPs into this list from an iptables rule, e.g. after connecting to the SSH port three times in a minute. This is the standard usage described in iptables(3). Another way to use xt_recent is by inserting the rules by writing to /proc/net/xt_recent/whatever. This can be performed by a fail2ban action. Files in /proc/net/xt_recent/ are protected by normal filesystem rules, so can be chown'ed and chmod'ed to be writable by a certain user. After the necessary iptables rules are inserted (which requires root priviledges), blacklisting can be perfomed by an unpriviledged user. Using fail2ban with xt_recent allows smarter filtering than normal iptables rules with the xt_recent module can provide. The disadvantage is that fail2ban cannot perform the setup by itself, which would require the priviledge to call /sbin/iptables, and it must be done through other means. The primary advantage is obvious: it's generally better to run services not as root. This setup is more robust, because xt_recent has it's own memory management and should behave smartly in case a very large amount of IPs is blocked. Also in case the fail2ban process dies the rules expire automatically. In case of a large amount of blocked IPs, traversing rules linearly for each SYN packet as fail2ban normally inserts them will be slow, but xt_recent with the same number of IPs would be much faster. (Didn't test this, so this is pure handwaving, but it should really be this way ;)) From the administrators point of view, a setup with xt_recent might also be easier, because it's very simple to modify the permissions on /proc/net/xt_recent/fail2ban-whatever to be readable or writable by some user and thus allow delisting IPs by helper administrators without the ability to mess up other iptables rules. The setup is simple: - add user fail2ban who can read /var/log/auth.log and other necessary log files. Log files are owned by group 'adm', so it is enough if this user belongs to this group. - put a rule to check the xt_recent list in the static firewall initialization script, with a name like fail2ban-ssh. The necessary invocation is documented in the action file. - set FAIL2BAN_USER in /etc/default/fail2ban. - make sure that logfiles of fail2ban itself are writable by the fail2ban user. /etc/init.d/fail2ban will change the ownership at startup, but it is also necessary to modify /etc/logrotate.d/fail2ban. Necessary changes are documented in that file. --- fail2ban-0.8.4/debian/fail2ban.default 2011-03-23 11:06:35.000000000 +0100 +++ /etc/default/fail2ban 2011-03-23 12:53:41.000000000 +0100 @@ -21,3 +21,19 @@ # Command line options for Fail2Ban. Refer to "fail2ban-client -h" for # valid options. FAIL2BAN_OPTS="" + +# Run fail2ban as a different user. If not set, fail2ban +# will run as root. +# +# The user is not created automatically. +# The user can be created e.g. with +# useradd --system --no-create-home --home-dir / --groups adm fail2ban +# Log files are readable by group adm by default. Adding the fail2ban +# user to this group allows it to read the logfiles. +# +# Another manual step that needs to be taken is to allow write access +# for fail2ban user to fail2ban log files. The /etc/init.d/fail2ban +# script will change the ownership when starting fail2ban. Logrotate +# needs to be configured seperately, see /etc/logrotate.d/fail2ban. + +FAIL2BAN_USER="fail2ban" --- fail2ban-0.8.4/debian/fail2ban.init 2011-03-23 11:06:35.000000000 +0100 +++ /etc/init.d/fail2ban 2011-03-23 12:52:19.000000000 +0100 @@ -33,6 +33,9 @@ # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 +# Run as root by default. +FAIL2BAN_USER=root + # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME DAEMON_ARGS="$FAIL2BAN_OPTS" @@ -103,7 +106,17 @@ # Assure that /var/run/fail2ban exists [ -d /var/run/fail2ban ] || mkdir -p /var/run/fail2ban - start-stop-daemon --start --quiet --chuid root --exec $DAEMON -- \ + if [ "$FAIL2BAN_USER" != "root" ]; then + # Make the socket directory, IP lists and fail2ban log + # files writable by fail2ban + chown "$FAIL2BAN_USER" /var/run/fail2ban + # Create the logfile if it doesn't exist + touch /var/log/fail2ban.log + chown "$FAIL2BAN_USER" /var/log/fail2ban.log + find /proc/net/xt_recent -name 'fail2ban-*' -exec chown "$FAIL2BAN_USER" {} \; + fi + + start-stop-daemon --start --quiet --chuid "$FAIL2BAN_USER" --exec $DAEMON -- \ $DAEMON_ARGS start > /dev/null\ || return 2 --- /dev/null 2011-03-01 12:22:44.452629464 +0100 +++ /etc/fail2ban/action.d/iptables-xt_recent-echo.conf 2011-03-23 11:35:29.000000000 +0100 @@ -0,0 +1,77 @@ +# Fail2Ban configuration file +# +# Author: Zbigniew Jędrzejewski-Szmek <zbys...@in.waw.pl> +# +# $Revision: 1 $ +# + +[Definition] + +# Option: actionstart +# Notes.: command executed once at the start of Fail2Ban. +# Values: CMD +# +# Changing iptables rules requires root priviledges. If fail2ban is +# configured to run as root, firewall setup can be performed by +# fail2ban automatically. However, if fail2ban is configured to run as +# a normal user, the configuration must be done by some other means +# (e.g. using static firewall configuration with the +# iptables-persistent package). +# +# Explanation of the rule below: +# Check if any packets coming from an IP on the fail2ban-<name> +# list have been seen in the last 3600 seconds. If yes, update the +# timestamp for this IP and drop the packet. If not, let the packet +# through. +# +# Fail2ban inserts blacklisted hosts into the fail2ban-<name> list +# and removes them from the list after some time, according to its +# own rules. The 3600 second timeout is independent and acts as a +# safeguard in case the fail2ban process dies unexpectedly. The +# shorter of the two timeouts actually matters. +# actionstart = iptables -I INPUT -m recent --update --seconds 3600 --name fail2ban-<name> -j DROP +actionstart = + +# Option: actionstop +# Notes.: command executed once at the end of Fail2Ban +# Values: CMD +# +actionstop = echo / > /proc/net/xt_recent/fail2ban-<name> + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = test -e /proc/net/xt_recent/fail2ban-<name> + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: <ip> IP address +# <failures> number of failures +# <time> unix timestamp of the ban time +# Values: CMD +# +actionban = echo +<ip> > /proc/net/xt_recent/fail2ban-<name> + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: <ip> IP address +# <failures> number of failures +# <time> unix timestamp of the ban time +# Values: CMD +# +actionunban = echo -<ip> > /proc/net/xt_recent/fail2ban-<name> + +[Init] + +# Defaut name of the chain +# +name = default + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp | icmp | all ] Default: tcp +# +protocol = tcp --- fail2ban-0.8.4/debian/fail2ban.logrotate 2011-03-23 11:06:35.000000000 +0100 +++ /etc/logrotate.d/fail2ban 2011-03-23 12:55:56.000000000 +0100 @@ -9,5 +9,8 @@ postrotate fail2ban-client set logtarget /var/log/fail2ban.log >/dev/null endscript + + # If fail2ban runs as non-root it still needs to have write access + # to logfiles. + # create 640 fail2ban adm create 640 root adm } -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org