Internet RFCs
Usenet FAQs
Other FAQs
Documents
| |
Introduction.
Automatic firewall hardening
is a technique used by many commercial firewalls to prevent
invalid packets from reaching protected networks. The objective
of this document is to demonstrate how to harden iptables in real-time.
By default, iptables can log
messages via the Linux syslogd daemon. Logs by themselves are
fine for basic security but do not address advanced security
issues. For advanced security a system needs to run custom
scripts as soon as illegal operations are logged by the
firewall. Depending on the severity of the violations, you can
program these scripts to perform various actions such as blocking
offending IP addresses. The techniques outlined in this document
are not limited to iptables, and can also be modified to process
output from any application which logs via syslog e.g. intrusion
detection scanners such as SNORT.
The content in this document
has been tested against Red Hat 7.2/7.3 only, but then, I live on
the island of Mauritius which is a hell of a journey from civilisation, and all of us here are scantily clad Zulu warriors
:-) For more info about Mauritius and scuba diving try www.islandsoft.net
An excellent document on the
Linux firewall capabilites is the Iptables Tutorial by Oskar
Andreasson which you can find at http://iptables-tutorial.haringstad.com/
Linux Reference
Books.
Here are some Linux books
which you may find interesting. Please open each link in a new
window.
Advanced
Linux Networking
Hack
Attacks Revealed: A Complete Reference
Hacking
Linux Exposed
Linux
Firewalls (2nd Edition)
Linux
Routers
Network
Intrusion Detection (An Analysts Handbook, 2nd Edition)
PHP
and PostgreSQL Advanced Web Programming
Real
World Linux Security: Intrusion Prevention, Detection and
Recovery
Red
Hat Linux 7.3 Bible
The Theory.
Linux syslogd incorporates
an interesting feature which allows it to redirect its output to
user defined pipes instead of log files. I will use a Perl script
to process messages coming from syslogd and dynamically
reconfigure iptables.
What You Will Need.
The examples in this
document use a postgresql server. Most people are familiar with
MySQL ,so porting should not be a problem. I prefer Postgres
because it has many features present in commercial databases. For
more information about PostgreSQL visit http://www.postgresql.org/. You will also need the postgresql-perl,
Perl and iptables packages installed on the firewall machine.
On the postgreSQL server
create a database called "adaptive" and a table called
"iptables". Add the folowing fields.
- ipaddress as char 16
- severity as int4
- time as datetime
Basic Security.
TO DO: More detail on MAC
addressses and ARP poisoning.
In my opinion, the only
services, which should be running on a firewall, are syslog and cron. You should also have a printer logging whatever gets sent
to syslog. The reason for having a printer is that if your
machine does get hacked, and the cracker overwrites the logs, you
will still be able to see how the exploit was performed. Your
firewall should also preferably be running off a CD-ROM and
loading its ruleset from a write protected floppy disk.
Knowing the MAC addresses
present on your network is very important. The firewall must be
aware of any rogue MAC addresses, which may be originating from a
machine which, may have been unlawfully introduced into your
network.
Locking Down The
Firewall During The Boot Process.
The first step that you will
want to take is to secure your firewall while it is booting. By
default, iptables allows unrestricted packet movement on the
INPUT, OUTPUT and FORWARD chains. This poses a security threat
while your machine is booting, and opens up your network to
various types of assault. To avoid this, you must instruct
iptables to block all packet movement BEFORE the network
interfaces start up.
On the Redhat distributions
the link "S10network" found in "/etc/rc.d/rc3.d"
is responsible for starting the network. You may also have "S08iptables"
found in "/etc/rc.d/rc3.d". This link is responsible
for initialising the firewall routines. I prefer to delete the
default "S08iptables" link and create my own link
starting with "S08". The link starting with "S08"
gets executed before the one starting with "S10" thus
ensuring that no packets get through.
There are various kernel
options which you can set to enhance security. A few of them are
set in the example below.
In order to secure the
firewall during boot, do the following:
- Go to the "/etc/rc.d"
directory
- Using your favorite
text editor create a file called "rc.autofwinit"
- Copy and paste the
script below into "rc.autofwinit"
- Exit the editor.
- Execute the command
"chmod 755 rc.autofwinit"
- Go to the "/etc/rc.d/rc3.d"
directory
- Execute the command
"rm -f S08iptables"
- Execute the command
"ln -s /etc/rc.d/rc.autofwinit S08iptables_start"
- Execute the command
"./S08iptables_start"
|
The
rc.autofwinit script
|
#!/bin/sh
#
# rc.autofwinit - Initialises firewall on boot
#
# Copyright (C) 2001,2002 Vasoo Veerapen (dive_mauritius@killspamforever.hotmail.com);
# http://www.islandsoft.net/veerapen.html
#
# This program is free software; you can distribute it and/or modify it under the terms of
# the GNU General Public License as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# 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
# or from the site that you downloaded it from; if not, write to
# the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
#
#
# Maybe you are more interested in scuba diving, marine conservation or my
# homeland, the paradise island of Mauritius where the Dodo used to live?
# Its simply http://www.islandsoft.net/
#
# ----------------------------------------------------------------------
echo "Initialising firewalling...Dropping all packets"
IPT=/sbin/iptables
#Block ICMP redirects
for CONF in /proc/sys/net/ipv4/conf/*/accept_redirects; do
echo 0 > $CONF
done
# Block IP Source Routing
for CONF in /proc/sys/net/ipv4/conf/*/accept_source_route; do
echo 0 > $CONF
done
# Block IP spoofing
for CONF in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $CONF
done
# Clear tables
for TABLE in filter nat; do
$IPT -t $TABLE –F
$IPT -t $TABLE –X
done
# Drop all packets
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
echo "Done initialising."
sleep 2
|
Defining an Iptables
Script.
Once the firewall boot
process is secured you must create the firewall script which will
log invalid packets to syslog. The iptables script presented
below is very basic. If you wanted to be more adventurous, then
you could use the DMZ script from the "Iptables Tutorial"
found at http://iptables-tutorial.haringstad.com/ and enhance it.
- Go to the "/etc/rc.d"
directory
- Using your favorite
text editor create a file called "rc.autofirewall"
- Copy and paste the
script below into "rc.autofirewall"
- Exit the editor.
- Make the file
executable by the shell, by running the command "chmod
755 rc.autofirewall"
- Run the script by
typing in "./rc.autofirewall"
- There should be no
errors. If there are, check your script syntax, iptables
and kernel setup.
|
The
rc.autofwrules script
|
#!/bin/sh
#
# rc.autofwrules - Firewall script for automatic firewall hardening
#
# Copyright (C) 2001,2002 Vasoo Veerapen (dive_mauritius@killspamforever.hotmail.com)
# http://www.islandsoft.net/veerapen.html
#
# This program is free software; you can distribute it and/or modify it under the terms of
# the GNU General Public License as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# 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
# or from the site that you downloaded it from; if not, write to
# the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
#
# Maybe you are more interested in scuba diving, marine conservation or my
# homeland, the paradise island of Mauritius where the Dodo used to live?
# Its simply http://www.islandsoft.net/
#
# ----------------------------------------------------------------------
IPT="/sbin/iptables"
INT_IF="eth0"
EXT_IF="ppp0"
LOG_LEVEL="notice"
#
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
#*******************************************************************************
#FILTER_FLAGS
#*******************************************************************************
echo Entering FILTER_FLAGS
$IPT -N FILTER_FLAGS
$IPT -F FILTER_FLAGS
##----------------------------------------------------------------------------##
$IPT -A FILTER_FLAGS -p tcp --tcp-flags ALL FIN -m limit \
--limit 5/minute -j LOG --log-level $LOG_LEVEL \
--log-prefix "iptables:SCAN:"
$IPT -A FILTER_FLAGS -p tcp --tcp-flags ALL FIN -j DROP
##----------------------------------------------------------------------------##
echo Leaving FILTER_FLAGS
#*******************************************************************************
# BANNED
#*******************************************************************************
echo Entering BANNED
$IPT -N BANNED
$IPT -F BANNED
##----------------------------------------------------------------------------##
# Leave blank
##----------------------------------------------------------------------------##
echo Leaving BANNED
$IPT -A INPUT -j BANNED
$IPT -A INPUT -j FILTER_FLAGS
$IPT -A OUTPUT -j BANNED
$IPT -A OUTPUT -j FILTER_FLAGS
#------------- End firewall script
|
Creating a Named
Pipe.
The named pipe is the
interface between syslog and the blocking script.
- Go to the "/etc/rc.d"
directory
- Execute "mknod /etc/rc.d/syslog_auth
p"
- Execute "chmod 600 /etc/rc.d/syslog_auth"
For more info, "man
mknod" is your friend.
Setting Up a
Blocking Script.
Once iptables and the named
pipe are set up, it is time to create a script that will handle
messages coming from the syslog daemon. The script is the core of
the automatic hardening process. The example below demonstrates
how to automatically lock out machines, and communicate with a
database server running PostgreSQL.
- Go to the "/etc/rc.d"
directory
- Using your favourite
text editor create a file called "rc.autoharden"
- Copy and paste the
script below into "rc.autoharden"
- Exit the editor.
- Excute "chmod 755
rc.autoharden"
- Run the script by
typing in "./rc.autoharden"
- You should see some
kernel messages go by, but there should be no errors. If
there are, check your script syntax, and Perl setup
- Open a new tty using
Alt-F2 for example. Log in as root.
- Execute "/sbin/iptables
-L" and observe its output. Keep note of the "BANNED"
chain.
|
The
rc.autofwharden script
|
#!/usr/bin/perl –w
#
# rc.autofwharden - Processes messages from syslogd
#
# Copyright (C) 2001,2002 Vasoo Veerapen (dive_mauritius@killspamforever.hotmail.com);
# http://www.islandsoft.net/veerapen.html
#
# This program is free software; you can distribute it and/or modify it under the terms of
# the GNU General Public License as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# 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
# or from the site that you downloaded it from; if not, write to
# the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
#
#
# Maybe you are more interested in scuba diving, marine conservation or my
# homeland, the paradise island of Mauritius where the Dodo used to live?
# Its simply http://www.islandsoft.net/
#
# ----------------------------------------------------------------------
use Pg;
use strict;
my $log_datetime="";
my $log_address="";
my @parms = ();
my $msgSource = "";
my $sourceIP = "";
my $sourcefile = "dump";
my $tmprec = "";
my $conn="";
my $result="";
my $temp="";
#Open the database first
$conn=Pg::connectdb("dbname=adaptive user=postgres password=password");
( PGRES_CONNECTION_OK eq $conn->status )
and print "Pg::connectdb ok:\n"
or die "Pg::connectdb failed: ", $conn->errorMessage, "\n";
#Open a named pipe
#open(FIFO, "< /etc/rc.d/syslog_auth") or die $!;
#printf "Pipe opened. \n";
#while(<FIFO>) {
#Or maybe you want to open a test file instead of a pipe?
open(SOURCE, "< $sourcefile") or die $!;
printf "File opened. \n";
while (<SOURCE>) {
@parms = split(/ /, $_);
$msgSource = $parms[5];
if ($msgSource eq "iptables:SCAN:")
{
#Set date and time
$log_datetime="$parms[1]-$parms[0]-2002 $parms[2]";
#Set source address
$temp = $parms[9];
$log_address = substr($temp, 4, length($temp) -4);
printf "Adding address %s to database. \n", $log_address;
$result = $conn->exec("INSERT INTO iptables (ipaddress, severity, time) VALUES ('$log_address', '1','$log_datetime')");
die $conn->errorMessage unless PGRES_COMMAND_OK eq $result->resultStatus;
$temp = "/sbin/iptables -A BANNED -s $log_address -j DROP";
printf "%s \n", $temp;
system($temp);
}
}
#close(FIFO);
#Close the test file instead.
close(SOURCE);
$result=$conn->exec("DROP DATABASE adaptive");
die $conn->errorMessage unless PGRES_COMMAND_OK eq $result->resultStatus;
#--------------- End of rc.autofwharden PERL Script;
|
Configuring Syslogd.
The final step is to
configure the syslog daemon. Normally, syslog echoes messages to
a tty and the file "/var/log/messages". We will
instruct syslog to echo messages to the named pipe instead.
- Go to the /etc
directory
- Make a backup copy of
syslog.conf
- Edit syslog.conf
Look for an entry starting
like
*.info;mail.none;authpriv.none
If you can't/can find the
line then add/change the line to look like
*.info;mail.none;authpriv.none |/etc/rc.d/syslog_auth
- Do not use spaces
between authpriv.none and the pipe sign | Always use TAB.
- Do not leave spaces
between the pipe sign | and /etc/rc.d/syslog_auth
- Save syslog.conf
- Run the command "ps -eaf | grep syslogd" to identify the PID
- Run a "kill -1"
command to the PID of syslogd e.g. "kill -1 698"
Viewing the Results.
From a remote system run
nmap available from http://www.insecure.org/nmap with the Fin scan option.
On the firewall machine, run
the command "/sbin/iptables -L" and note the difference
in the "Banned" chain.
To view the firewall
database, login as a postgresql user and type in
- psql adaptive
- select * from iptables;
This should give you a list
of all banned addresses added to the database.
Adaptive Firewall
FAQ.
Q. How safe is the adaptive
firewalling code in this document?
A. The hardening script in
this tutorial is very basic. Since the script automatically bans
machines, you can imagine what would happen if someone managed to
spoof the source addresses. In this case, legitimate IP addresses
would get blocked. However, during a legitimate attack, you could
identify which domain was the most offending, and ban any machine
attempting to connect from it.
Q. Why is my firewall
continuously logging ACK, FIN, URGP=0 ?
A. In 99.99% cases this is
normal behaviour. This is due to the connection state matching
code in Iptables which by default tracks each connection for 60
seconds. Once a connection is inactive for 60 seconds, Iptables
wipes it from its tracking table, but the server at the other end
does not know that. When the server tries to close the connection
from its end, it sends a packet with this TCP flag sequence which
gets intercepted by the firewall.
Acknowledgments.
I would like to thank the
following people for contributing towards this document.
Oskar Andreasson
Copyright © 2002, Vasoo Veerapen.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 82 of Linux Gazette, September 2002
|
|