Automatic Firewall Hardening with Linux and IPTABLES
Written by Vasoo Veerapen (dive_mauritius@hotmail.com)
Version 1.1, modified on the
20th of January 2002.
The original documents can always be found at http://www.islandsoft.net/veerapen.html
Please note that any content within this document is Copyrighted material at all times. Any reproduction, modification, or use of this document and/or contents from the islandsoft.net domain, in part or entirety, is prohibited unless explicit permission is obtained from the author.
The objective of this document is to show you how you can automatically harden your IPTABLES based firewall in real-time which is a technique used by commercial firewalls to prevent invalid packets from reaching protected networks. The content has been tested against Linux Mandrake 8.0 with Kernel 2.4.3 and IPTABLES 1.2.1a. Mandrake claim their distribution to be Red Hat compliant so the content in this article should be fully Red Hat compatible. I don't have any experience whatsoever with other distros, 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 click here.
There are many books available on Linux Security. I like these ones.
Real
World Linux Security (Intrusion, Prevention, Detection and Recovery)
Hacking Linux Exposed
Usually IPTABLES only logs messages via the SYSLOGD mechanism. Logs by themselves are fine for basic security but do not address advanced security issues. For advanced security you need to make your system 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 paging network admins or blocking offending IP addresses. All too often, firewall logs are checked once daily, or utilities such as LOGCHECK are used in scheduled CRON jobs to inform network admins of anything abnormal. By the time the logs are verified, the damage to your system is already done.
Linux SYSLOGD incorporates a neat feature which allows SYSLOGD to send the messages it receives to user defined pipes which can pass the message in turn to a script of your choice. The message flow is outlined below.
IPTABLES > SYSLOGD > named pipe > custom script
In the following exercise, I will show you how to add a DROP command to IPTABLES in order to block offending IP addresses in real-time as soon as a FIN scan is detected. You could of course program your scripts to do a multitude of other things as well.
You can get the entire tarball for this exercise here.
Requirements for this exercise:
Machine X (192.168.0.1)
Needs IPTABLES, SYSLOGD enabled, the C shell(csh) and Apache. This is the
machine that we will be tinkering with and where you will need to install
the demo scripts.
Machine Y (192.168.0.2)
Install
NMAP on Machine Y
This is what we will be doing:
(1) Create a firewall script using IPTABLES
(2) Create a named
pipe.
(3) Create a firewall hardening script.
(4) Convey data from
the named pipe to the firewall hardening script.
(5) Tell SYSLOGD to
echo messages to the named pipe.
(6) Send SIGHUP to syslogd.
(7) Use
NMAP to generate SYN/FIN scans
(1) Create a Firewall Script using IPTABLES
I have included the demo IPTABLES script as a text version for you to download. Make the script executable and run it. Don't forget to be logged in as root.
chmod 750 script_name
./script_name
#!/bin/sh # # Automatic Firewall Hardening # by Vasoo Veerapen (dive_mauritius@hotmail.com) # http://www.islandsoft.net/veerapen.html # # Please note that this script is Copyrighted material at all times. # Any reproduction, modification or use of this document and/or its contents, # in part or entirety, is prohibited unless permission is obtained from the author. # # Maybe you are 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 # # Revised on 1st of December 2001 # # ---------------------------------------------------------------------- # # This is a very basic IPTABLES script which checks for TCP scans with # only the FIN bit set. FIN never occurs on its own and is an indication # that someone is probably scanning your firewall and up to no good. # # If a scan is detected, it gets logged and the firewall is hardened # against the offending IP address. This is a base for much more # complex operations such as intrusion detection, paging network # admins, etc. # # The hardening is performed via syslogd which echoes messages # to a named pipe rather than the screen. The named pipe then conveys # data from syslogd to a hardening script of your choice. # # ----------------------------------------------------------------------- # # Q: How do I generate SYN/FIN scans? # A: Get NMAP at http://www.insecure.org/nmap # # Q: How do I create a named pipe? # A: mknod /path/named_pipe p # chmod 600 /path/named_pipe # # Q: How do I tell syslogd to send data to the named pipe? # A: Edit /etc/syslog.conf # Look for an entry starting like # *.info;mail.none;authpriv.none # Change the line to look like # *.info;mail.none;authpriv.none |/path/named_pipe # # Replace the space between .none and | with a TAB! # # Q: How do I convey data from the named pipe to my script. # A: (/path/my_script < /path/named_pipe)& # Then send kill -1 to syslogd. # # Unless you want to type in this command every time you restart your # system I suggest that it be issued on system startup. # I use Red Hat/Mandrake, so in my case I put it into /etc/rc.d/rc.local IPT="/sbin/iptables" INT_IF="eth0" LOG_LEVEL="notice" $IPT -F INPUT $IPT -F OUTPUT $IPT -F FORWARD $IPT -P INPUT ACCEPT $IPT -P OUTPUT ACCEPT $IPT -P FORWARD DROP #******************************************************************************* #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 "*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
(2) Create a Named Pipe
This creates a FIFO buffer which can store information coming from syslogd.
mknod /path/my_pipe p
chmod 600 /path/my_pipe
You could also use the mkfifo command. For more information, man is your friend.
(3) Create a Firewall Hardening Script
This script analyses the messages sent from SYSLOGD. If the messages contain the *SCAN* string, they get processed and the appropriate action is taken. I have included the demo script as a text version for you to download.
#!/bin/csh -f # # Please note that this script is Copyrighted material at all times. # Any reproduction, modification or use of this document and/or its contents, # in part or entirety, is prohibited unless permission is obtained from the author. # loop: set x="$<" echo "$x" | grep -q '*SCAN*' if ($status == 0 ) then set banned_ip=`echo "$x" | sed "s/.*SRC=\([^ ]*\) .*/\1/"` echo "# IP address $banned_ip was terminated." /sbin/iptables -A BANNED -s $banned_ip -j DROP /sbin/iptables -A BANNED -d $banned_ip -j DROP endif goto loop #-----End shell script
(4) Convey Data from the Named Pipe to Script
At the command line, type in the following
(/path/my_script < /path/my_pipe)&
Unless you want to type in this command every time you restart your system I suggest that it be issued on system startup. In my case I placed the above line into /etc/rc.d/rc.local
(5) Tell syslogd to echo messages to the named
pipe.
Backup and edit /etc/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 |/path/my_pipe
Remember the following points:
Make sure that you do not use spaces
between authpriv.none and the pipe sign | Always use TAB.
Do not leave spaces
between the pipe sign | and /path/my_pipe. They must be side by side
without any spaces between them.
(6) Send SIGHUP to syslogd
Run ps -ax to find the pid of SYSLOGD. Issue a kill -1 to SYSLOGD
kill -1 [pid of syslogd]
(7) Use NMAP to send SYN/FIN scans
I have Apache (httpd) running on machine X (192.168.0.1) and I have installed my state-of-the-art IPTABLES firewall without forgetting my extremely intelligent C shell script.
On Machine Y (192.168.0.2) I open my favorite web browser.
On Y, I type in http://192.168.0.1/ and get my default Apache page. Nothing abnormal here. Now trying something slightly more evil, I go to the command line and type
nmap -sF -p 80 192.168.0.1
Taking a look at the screen on Machine X, I see
IP Address 192.168.0.2 was terminated.
Issue the command iptables -L on Machine X to verify if this is indeed the case.
Now try to get access to http://192.168.0.1 from Machine Y
Please note that any content within this document is Copyrighted material at all times. Any reproduction, modification, or use of this document and/or contents from the islandsoft.net domain, in part or entirety, is prohibited unless explicit permission is obtained from the author.