giovedì 1 settembre 2011

How to integrate autofwd with Nagios

The autofwd tool is a very simple, portable and effective solution to protect a server (or a PC) from brute force password attacks, mainly attempting to break into the computer via sshd, but generally speaking to protect any local service from that type of attack.

Basically autofwd, when detecting an attack, does (1) ban the offending IP (either v4 or v6) and then (2) notifies the administrator with a mail message.
This is normally enough but, if you have already in place a Nagios monitoring service, you may want to notify the Nagios console about every ban and unban action carried by autofwd, in order to centralize to the unified console these kind of alarms, too. In this post I will explain how to do this.

As a requirement, I assume that you already have a working installation of autofwd in place and that there is on the network a Nagios version 3 server, where a nsca process is listening for passive commands.

Step 1: install the nsca client part on the host where autofwd is running.
You can download the source and compile it or, on a debian-derived linux distribution, you just enter: apt-get install nsca and the work is done.
Now you have the send_nsca executable installed somewhere in your file system and that's all we need from the nsca package.

Step 2: configure autofwd.
If you haven't introduced any enhancement, the operational part your actual autofwd.conf should look something like this:

--- CUT HERE ---

# NOTE: All of the external commands need to include the __IP__ token in
# order for autofwd to substitute the IP address in the correct
# location.
# Ban IPv4 Cmd: Command to execute to ban an IP
Ban IPv4 Cmd: /sbin/iptables -I INPUT -s __IP__ -j DROP

# Unban IPv4 Cmd: Command to execute to unban an IP
Unban IPv4 Cmd: /sbin/iptables -D INPUT -s __IP__ -j DROP

--- CUT HERE ---

The same applies for IPv6 so I wont copy it again.

In order to let Nagios know that a banning/unbanning action has been performed, we have to operate in the Ban Cmd sections, which can be modified as follows (pay attention to the absolute path of ban_check):

--- CUT HERE ---

# NOTE: All of the external commands need to include the __IP__ token in
# order for autofwd to substitute the IP address in the correct
# location.
# Ban IPv4 Cmd: Command to execute to ban an IP
Ban IPv4 Cmd: /etc/nagios/ban_check ban4 __IP__

# Unban IPv4 Cmd: Command to execute to unban an IP
Unban IPv4 Cmd: /etc/nagios/ban_check unban4 __IP__

--- CUT HERE ---

The ban_check command that I introduced here is a wrapper, that includes the iptables directive as well as other actions.

Step 3: deploy the ban_check wrapper on the monitored host.
The wrapper listing follows:

--- CUT HERE ---

# ban_check: wrapper to extend autofwd actions, alerting Nagios
# To be run on the same host where autofwd is
# Requires: nsca package (for send_nsca) and a working Nagios server
# Author: Niccolo Avico (
# Usage: ban_check { ban4 | ban6 | unban4 | unban6 }
# ban4 (bans as an IPv4 address)
# ban6 (bans as an IPv6 address)
# unban4 (unbans as an IPv4 address)
# unban6 (unbans as an IPv6 address)


USAGE="Usage: `basename $0` { ban4 | ban6 | unban4 | unban6 } "

# LOCAL_HOSTNAME corresponds to the name by which this host is known to Nagios

# NAGIOS_SERVER is where the Nagios console is running in your network

# NAGIOS_SERVICE is the name by which Nagios knows autofwd

if [ $# -ne 2 ]; then
echo "${USAGE}" >&2
exit 1

# Exit if send_nsca package is not installed
if [ -x /sbin/send_nsca ]; then
echo "Missing package send_nsca." >&2
exit 4

case "$1" in
iptables -I INPUT -s $TAG_IP -j DROP
action="IPv4 ${TAG_IP} banned."
ip6tables -I INPUT -s $TAG_IP -j DROP
action="IPv6 ${TAG_IP} banned."
iptables -D INPUT -s $TAG_IP -j DROP
action="IPv4 ${TAG_IP} unbanned."
ip6tables -D INPUT -s $TAG_IP -j DROP
action="IPv6 ${TAG_IP} unbanned."
echo "${USAGE}" >&2
exit 3

# Now inform Nagios about this action:
# pipe the service check info into the send_nsca program, which
# in turn transmits the data to the nsca daemon on the central
# monitoring server

/usr/bin/printf "%s\t%s\t%s\t%s\n" "$LOCAL_HOSTNAME" "$NAGIOS_SERVICE" "$return_code" "$action" | /usr/sbin/send_nsca -H $NAGIOS_SERVER -c $NSCA_CONFIG

--- CUT HERE ---

Please note that we want to send Nagios a CRITICAL (return_code=2) alarm when autofwd will ban an attacker and a WARNING (return_code=1) alarm when autofwd will unban it (if autofwd.conf allows to do so).

Let's put the wrapper in a file called /etc/nagios/ban_check and make it executable.

You must also customize the wrapper with the IP address of your Nagios server ($NAGIOS_SERVER) and put the Nagios short name for the host ($LOCAL_HOSTNAME), as is defined in your Nagios console.

Step 4: configure Nagios for the autofwd service.
In order for Nagios to process autofwd actions and display them as alarms for you host, we now define a new service, called autofwd (as it is named in the wrapper); you can put the following definitions in a new autofwd.cfg file, accessible by your Nagios installation.

--- CUT HERE ---

define hostgroup {
hostgroup_name autofwd-servers
alias Server equipped with autofwd

define service {
hostgroup_name autofwd-servers
service_description autofwd
check_command return-ok ; always return OK
use generic-service
max_check_attempts 1 ; immediately put in HARD state
active_checks_enabled 0 ; only passive checks
passive_checks_enabled 1
is_volatile 1 ; EVERY check is an alarm
check_freshness 0 ; don't check for stale state
flap_detection_enabled 0 ; by definition it will flap CRITICAL/WARNING
notification_options c,r
notifications_enabled 1
notification_interval 0

--- CUT HERE ---

For a further exaplanation of the parameters, please follow the Nagios reference.

Step 5: on the Nagios server, include the new service in your host definition.
In the define host section of your Nagios configuration regarding the monitored host, add autofwd-servers to the list of hostgroups to which the host belongs.

--- CUT HERE ---

define host{
host_name HS-Rustica1
alias POP gestito da Niccolo'
hostgroups openwrt-servers, http-servers, ssh-servers, autofwd-servers
active_checks_enabled 0
use generic-host
contacts gilgamesh
register 1

--- CUT HERE ---

Step 6: test.
Restart the Nagios service and, if everything went ok, you should see, in the web Nagios console, a new service called autofwd, listed with the other services checked for your host.

You can now monitor the nagios log file for autofwd notifications; just issue on a terminal:

nagios-server:$ tail -f /var/log/nagios3/nagios.log | grep autofwd

Open another terminal and log into the monitored host. Issue a ban_check fake:

host:$ ban_check ban4 fake-ip

You should see immediately a diagnostic from send_nsca, confirming that the command has been sent to the nagios server.
The first terminal should now display a PASSIVE CHECK notification about you host and the banning action just performed; at the same time the Nagios console shall put in a CRITICAL state the autofwd service for that host.

Due to the behaviour of no volatile services in Nagios, this CRITICAL state will never be reset automatically by the system (and this is what we want, indeed): if nobody takes care of the alarm, the autofwd eventually will unban the IP (if instructed to do so) and the service state will move from CRITICAL to WARNING.

The only way to reset to OK that state is to issue a manual command to Nagios, submitting a passive service check from the web console.

This policy should grant that no attack attempt to your host shall be underestimated or misnotified.