Sunteți pe pagina 1din 11

Configuring IPTABLES for Snort-Inline

by
Tim Slighter
January 23, 2003
Brief background on Snort-Inline
Snort-Inline is more or less a snort binary that can be configured to receive sp
ecific
input from IPTABLES. The key syntax used with IPTABLES is â QUEUEâ . â QUEUEâ
instructs IPTABLES to pass any matching protocol traffic to the ip_queue module.
Snort-Inline processes the matching traffic that has been passed to ip_queue and
determines response based upon the configuration file (snort.conf) and rules fil
es.
This document is for instructions on how to get Snort-Inline working with IPTABL
ES.
First assuming the user has working knowledge of Redhat, IPTABLES and Snort,
this procedure has been tested with Redhat 7.3 Kernel 2.4.18-3. Lets break this
paper down into logical sections:
Determining what packages and RPM's are required
Obtaining all required packages and RPM's
Configuring and compiling required RPM's and source code
Configuring your rc.firewall script
Configuring and compiling Snort-Inline
Test run your new project
Understanding and working with the results
Security considerations
Please note that the rc.firewall script has been provided by Rob McMillen
<mailto:rvmcmil@cablespeed.com> through the generosity of Honeynet.org
(http://www.honeynet.org/papers/honeynet). The rc.firewall script provided in th
is paper
has been edited in order to work with Snort-Inline and IPTABLES for a functional
Intrusion Response System.
Determining what packages and RPM's are required
For the scope and purpose of this document, rc.firewall will be run in "Nat" mod
e.
Snort-Inline will also be required for this implementation. Honeynet.org provide
s a
Snort-Inline startup script that is very useful. If anyone is interested in runn
ing in
â Bridgeâ mode, please visit the Honetnet.org website for tools and scripts.
Obtaining all required packages and RPM's
Unless the source RPM for IPTABLES has been previously built into the kernel, th
e
standard IPTABLES RPM will not work correctly with Snort-Inline. The required
RPM can be obtained from Netfilter.org @ http://www.netfilter.org/downloads.html
-
1.2.7a. Locate the file iptables-1.2.7a.tar.bz2 and download it. Snort-Inline ca
n be
located and downloaded from the Snort.org site @
http://www.snort.org/dl/contrib/patches/inline/ as file "snort-inline.tgz". Or s
imply go to
http://www.snort.org/ and click on "downloads" - "contrib" - "patches" - "inline
". The
Honeynet provided startup script as well as other tools for Snort-Inline are ava
ilable
at http://www.honeynet.org/papers/honeynet/tools/. Make sure to grab the snort-i
nline
startup script!
Configuring and compiling required RPM's and source code
Unpack the iptables-1.2.7a.tar.bz2 using bunzip2 and change into the newly creat
ed
directory. Refer to the INSTALL file to correctly install the new IPTABLES sourc
e
code. In the event that this file is not found, use the brief instructions below
to
compile the IPTABLES source code:
FOLLOW THESE STEPS:
1) Next, make the package.
% make KERNEL_DIR=<<where-you-built-your-kernel>>
2) Finally, you need to install the shared libraries, and the binary:
# make install KERNEL_DIR=<<where-you-built-your-kernel>>
If you are a developer, you can install the headers, development libraries
and associated development man pages, with:
# make install-devel
That's it!
the KERNEL_DIR variable should most likely be /usr/src/linux-2.4. In the event t
here
are issues compiling this source code, refer to the Netfilter.org website for su
pport.
Configuring your rc.firewall script
Configuring the rc.firewall script is fairly straight forward but can be edited
to meet
any requirements. The main entries that need to edited are briefly shown below:
COMMON VARS section
MODE="nat"
Use this mode unless your system is operating as a router for other systems with
address translation
PUBLIC_IP=""
This can be set to an IP address provided for either a virtual interface or an e
xternal
interface not being used. Not important but something might need to be entered
here.
INET_IFACE=""
This should be the ifconfig variable of the external interface. Do NOT use the s
ame
value for this and the LAN_IFACE value or the script will not run. If you do not
have
second interface, create a virtual interface eth0:1 and use that variable. This
value
does not affect Snort-Inline but is required for this script to function
In this script PUBLIC_IP and INET_IFACE can probably be left empty
LAN_IFACE=""
This value will be the same that Snort-Inline will be running on. Commonly "eth0
" is
the value
LAN_IP_RANGE=""
IP Range of internal network (192.168.1.0 or according to the class subnet used)
LAN_BCAST_ADRESS=""
Broadcast address according to the subnet used
################# All LAN fields MUST have an entry ####################
QUEUE="yes"
This must be set to "YES" for snort-inline to work
VARIABLES FOR NAT MODE section
ALIAS_MASK="255.255.255.0"
Set this according to subnet being used
HPOT_IP=""
This will be the IP address of the interface you are running Snort-Inline on. St
ealth
will NOT work here.
SPECIAL CONSIDERATION VARIABLE section
DNS_HOST=""
If DNS is required, then enter the IP address of the system you are running Snor
t-
Inline on here
DNS_SVRS=""
If DNS is required, then the IP address of the DNS server must be entered here
The rc.firewall script also contains entries taking advantage of â -j LOGâ for
IPTABLES. Log level 6 defaults to â infoâ and will appear in /var/log/messages
according to the â log-prefix that is used. If these LOG entries do not appear in the
/var/log/messages file, check /etc/syslog.conf to ensure that *.info is present
and
logging to /var/log/messages This script will hopefully be available on the Snor
t
website. For the time being, the script is available at the end of the document.
Configuring and compiling Snort-Inline
Tar xzf the "snort-inline.tgz" file and change into the "snort-inline" directory
. Issue
the command "./configure --enable-inline" in order to build for inline. Follow t
his with
a "make" and "make install". In order to simplify the process run the configure
script
as "./configure --prefix=/usr/local/snort --enable-inline" or there will be some
minor
editing waiting for you later on. In the event that configure was run without th
e --
prefix, issue a "cp -R snort-inline /usr/local/snort" and cd to /usr/local/snort
/etc and
begin edits on the snort.conf file. Much like the original snort, edit this file
according
to the vars, preprocessors and rules that meet your requirements. This process
should be simple enough to not require any further documentation. The next step
is
to alter all of the rules files. cd to ../rules and either open and edit each ru
les file that
will be used or take advantage of sed and some programming skills to perform a
"global" search and replace on the all of the rules files. For the purpose of th
is
document, the proper editing of one rules file will provide a sound starting poi
nt. For
example, vi the scan.rules files and issue the following command ":1,%s/alert/dr
op/g"
and enter and this should globally replace all occurrences of "alert" with "drop
". Do
the same to each rules file that will be used as specified in the snort.conf fil
e.
Providing that the snort-inline startup script was downloaded from Honeynet.org,
"cp"
this file to /etc/init.d and edit it according to where the directories and bina
ries are
located. Ensure that ALL instances of eth* are changed to reflect the interface
that
snort-inline will be running on. The bottom line of the script should look somet
hing
close to what is shown below:
$SNORT -D -d -c /usr/local/snort/etc/snort.conf -Q -i eth0 -l $DIR/$DATE
As always, prior to running this issue a "mkdir /var/log/snort". The first time
running
snort-inline may generate an error and the program will stop. A quick easy
workaround to get rid of this problem is to edit the snort-inline startup script
and
place the following entry at the top of the file "/sbin/modprobe ip_queue". Fina
lly,
copy the script to a location where snort-inline can be started automatically "c
p snortinline.
sh /etc/init.d/snort" and chmod +x to make it executable.
Test run your new project
With the snort-inline script configured according to requirements and the rc.fir
ewall in
place with a chmod +x in /etc/init.d. Start the rc.firewall script issuing
"/etc/init.d/rc.firewall". Uncomment the "set -x" line in the rc.firewall script
for verbose
debugging if there are problems. Follow this by starting the snort-inline script
"/etc/init.d/snort". Issue a ps -ef to ensure that snort-inline is running as an
ticipated.
Check for a new $DATE directory created in /var/log/snort that will be created w
hen
snort-inline initializes.
Understanding and working with the results
Find a hub or switch and connect the system running snort-inline on the same
network with a system that can run nmap and other pen-test oriented tools. Initi
ally,
running nmap -sF -sX -sN -sS and -sT scans will most likely return results the f
irst
few times. Continue running the scans and timeouts will start taking place. Cond
uct
other tests that are known to fire alerts on snort signatures and observe the re
sults.
In our lab, the success rate for snort-inline responding with a "drop" was aroun
d 80%
when scanning a single host. When enough scans were conducted to generate
timeouts, subsequent success rates were over 90%. Conduct tests in accordance
with what would normally take place from an external scan on your environment.
Security considerations
In order to further secure a snort-inline system, edit the rc.firewall script or
create
your IPTABLES that enhances restrictions on the INPUT table, such that the INPUT
table becomes IPTABLES -P INPUT DROP. Originally setting the INPUT table to
ACCEPT allows all traffic to pass through primarily for testing purposes. Feel f
ree to
edit the rc.firewall script to meet the needs of your organization.
rc.firewall script
#!/bin/bash
#
# rc.firewall, ver 0.6 - 5 Jan 2003
# http://www.honeynet.org/papers/honeynet/tools/
# Rob McMillen <rvmcmil@cablespeed.com>
# This scripts has been borrowed from honeynet.org and customized for strict con
trol of
IPTABLES in conjunction with Snort-Inline
#
# PURPOSE
#
# This scripts has been redesigned for use with IPTABLES and Snort-Inline specif
ically.
Use IPTABLES to specify
# what traffic is analyzed, logged, or QUEUED. The primary method to deploy a wo
rking
and successful IPTABLES
# is by placing allowed hosts, services, traffic etc at the beginning of the cha
in, followed by -
j LOG and finally -j QUEUE
# This will vary according to environment and requirements for each organization
. Make
note that anything used with -j QUEUE
# will pass everything in that IPTABLES rule to Snort-Inline. Providing that all
snort rules
have "drop" in place of "alert"
# the specific traffic will ONLY be blocked providing it meets any of the criter
ia in any of
the snort rules. In many situations
# it would be recommendable to place -j QUEUE at the top of the IPTABLES chain b
ut run
the risk of the traffic being dropped
# since it will not match any criteria in the IPTABLES chain or Snort-Inline. Us
e your own
judgment according to the requirements
# of your organization.
#
# REQUIREMENTS
# This utility will not work with a standard IPTABLES RPM, one must compile the
source
RPM or the best solution would be to download
# the most recent source from Netfilter.org. The Tarball from Netfilter contains
INSTALL
and README files on how to recompile your
# new IPTABLES into the kernel. Providing that works well for you, then you shou
ld be
able to proceed with this script with no issues.
#
# In order for the genII script to work, your kernel must
# be compiled with bride and bridge firewall support.
# Red Hat kernel 2.4.18-3 has this by default, most other
# kernels do not. If yours does not, you will most likely
# need to patch and recompile your kernel. You can find the
# patch at
# http://bridge.sourceforge.net/download.html
#
# You will also need bridge utilities to allow this script to
# enable/configure bridging. I used bridge-utils-0.9.3-4 during
# the testing of this script.
###
INSTALLATION
# Once you have configured the variables of this script, you
# simply execute this script. It calls on IPTables and
# does everything for you (nice, huh? :). You must have IPTables
# installed on your system, and kernel version 2.4.x.
##
# MODE is the mode the firewall will use to operate. There are
# two possible values at this time: nat, bridge. "nat" is GenI
# where your gateway is routing in layer3. "bridge" is GenII
# where your gateway is bridging in layer2. Of these two
# options, "bridge" is the preferred, more secure MODE.
#
# MODE="nat" In this mode, the firewall will translate each ip
# in the PUBLIC_IP variable to each ip in the HPOT_IP variable.
# Order is important, so make sure you place the ipâ s in the
# variables as you would like them translated. For example,
# PUBLIC_IP="192.168.1.1 192.168.1.2 192.168.1.3"
# HPOT_IP="192.168.0.1 192.168.0.2 192.168.0.3"
#
# will translate as follows:
# 192.168.1.1 => 192.168.0.1
# 192.168.1.2 => 192.168.0.2
# 192.168.1.3 => 192.168.0.3
#
# Each variable is a space delimited list; therefore, you can have
# as many as you want (or as many as an interface can have aliases).
#
# The following variables must match the setting for the translated
# network. In the example above, they would be the settings of the
# 192.168.0.* network
#
# LAN_IP_RANGE="192.168.0.0/24"
# LAN_BCAST_ADDRESS="192.168.0.255"
#
# MODE="bridge" This mode should not be used unless your system is acting as a r
outer
without address translation.
# In this mode, the firewall will act as a bridge,
# bridging and bridge firewalling will need to be compiled into the
# kernel. Default kernel for Redhat 7.3 (2.4.18-3) has it, but its
# upgrade does not. All other default kernels do not support IPtables
# in bridging mode. Therefore, your bridge will allow everything in and
# everything out, completely bypassing your firewall rules.
#
# The following variables must match the settings for the bridged
# network. If both sides of the bridge are on 10.0.0.*,
#
# LAN_IP_RANGE="192.168.1.0/24"
# LAN_BCAST_ADDRESS="192.168.1.255"
##
# NOTE: A quick check to ensure you have the LAN variables correct
# is to check /var/log/messages. If you see logs stating
# SPOOFED SOURCE, you probably have them set wrong. Also,
# make sure your Honeypot default gateway is set to the
# firewall internal interface when in nat mode and the
# border router or routing device when in bridge mode.
#### If you want to see all the commands or which command is giving your
# problems, remove the comment below.
#set -x
#*************************************************************************
# USER VARIABLE SECTION
#*************************************************************************
###############
# COMMON VARS #
###############
# The MODE variable tells the script to #setup a bridge HoneyWall
# or a NATing HoneyWall.
MODE="nat"
#MODE="bridge"
# A space delimited list of honeypots IPs (public IP)
# If you are in "bridge" mode, this is the list of your
# honeypot IP's that will be behind the bridge. If you are
# in "nat" mode, this is the list of public IPs you will
# be using for IP address translation. Still confused? Its
# the list of IPs the hackers will attack.
PUBLIC_IP=""
### Variable for external network
INET_IFACE="" # This should be the ifconfig variable of the external
interface. Do NOT use the same value for this # and
the LAN_IFACE value or the script will not run. If you do not have second interf
ace, create
# a virtual interface eth0:1 and use that variable. This
value does not affect Snort-Inline but is
# required for this script to function
### Variables for internal network
LAN_IFACE="" # This value will be the same that Snort-Inline will be
running on. Commonly "eth0" is the value
LAN_IP_RANGE="" # IP Range of internal network (192.168.1.0 or
according to the class subnet used)
LAN_BCAST_ADRESS="" # IP Broadcast range for internal network
### IPTables script can be used with the Snort-Inline filter
### You can find the current release at
### http://www.snort.org/dl/contrib/patches/inline/
QUEUE="yes" # This must be set to "yes" or Snort-Inline will not work as anticip
ated
#QUEUE="no" # Do not use experimental QUEUE support
### Set the connection outbound limits for different protocols.
SCALE="hour" # second, minute, hour, etc.
TCPRATE="9" # Number of TCP connections per $SCALE
UDPRATE="20" # Number of UDP connections per $SCALE
ICMPRATE="50" # Number of ICMP connections per $SCALE
OTHERRATE="10" # Number of other IP connections per $SCALE
######################
# END OF COMMON VARS #
######################
##########################
# VARIABLES FOR NAT MODE #
##########################
# You use these variables ONLY if you are using NAT mode.
# If you are in bridging mode, then these variables will
# not be used.
#
ALIAS_MASK="255.255.255.0" # Network mask to be used alias (This value can be
changed according to your subnet mask)
HPOT_IP="" # This will be the IP address of the interface you are running
Snort-Inline on. Stealth will NOT
# work here.
#############################
# END OF NAT MODE VARIABLES #
#############################
##################################
# SPECIAL CONSIDERATION VARIABLE #
##################################
# You may want to allow unrestricted outbound DNS access.
# If you want to restrict the hosts that can access public dns servers,
# set the DNS_HOST variable to the ip of the honeypots allowed to
# make queries. Otherwise, leave it blank and the proper set of
# ipâ s will be assigned in order to allow all of your honeypots to
# make dns queries.
DNS_HOST="" # If you require DNS, then enter the IP address of the
system you are running Snort-Inline on here
# List of DNS servers your honeypot(s) are allowed to go to.
# This is once a gain a space delimited list.
DNS_SVRS="" # If you require DNS then the IP address of the DNS
server must be entered here
##########################################################
# VARIABLES THAT RESTRICT WHAT THE FIREWALL CAN SEND OUT #
##########################################################
# This variable will limit outbound Firewall connections
# to ports identified in the ALLOWED_TCP_OUT and
# ALLOWED_UDP_OUT variables. If set to yes, it will
# restrict the firewall. If set to no, it will allow all
# outbound connections generated by the firewall.
# NOTE: There must be a management interface in bridge
# mode in order to have a firewall interface to restrict.
#RESTRICT="yes" # DO NOT USE this option!!
RESTRICT="no"
ALLOWED_UDP_OUT="53 123"
ALLOWED_TCP_OUT="22 80 21"
##########################
# END RESTRICT VARIABLES #
##########################
############################################
# LOCATION OF PROGRAMS USED BY THIS SCRIPT #
############################################
IPTABLES="/sbin/iptables"
BRIDGE="/usr/sbin/brctl"
IFCONFIG="/sbin/ifconfig"
ROUTE="/sbin/route"
MODPROBE="/sbin/modprobe"
LSMOD="/sbin/lsmod"
####################
# END OF PROG VARS #
####################
#*************************************************************************
# END OF USER VARIABLE SECTION (DO NOT EDIT BEYOND THIS POINT)
#*************************************************************************
#########
# First, confirm that IPChains is NOT running. If
# it is running, clear the IPChains rules, remove the kernel
# module, and warn the end user.
/sbin/lsmod | grep ipchain
IPCHAINS=$?
if [ "$IPCHAINS" = 0 ]; then
echo ""
echo "Dooh, IPChains is currently running! IPTables is required by"
echo "the rc.firewall script. IPChains will be unloaded to allow"
echo "IPTables to run. It is recommened that you permanently"
echo "disable IPChains in the /etc/rc.d startup scripts and enable"
echo "IPTables instead."
ipchains -F
rmmod ipchains
fi
#########
# Flush rules
#
$IPTABLES -F
$IPTABLES -F -t nat
$IPTABLES -F -t mangle
$IPTABLES -X
echo ""
# Let's figure out dns
if [ $DNS_HOST -z ]
then
if [ $MODE = "bridge" ]
then
DNS_HOST=$PUBLIC_IP
else
DNS_HOST=$HPOT_IP
fi
fi
#########
# Load all required IPTables modules
#
### Needed to initially load modules
/sbin/depmod -a
### Add iptables target LOG.
$MODPROBE ipt_LOG
### Add iptables QUEUE support (Experimental)
if test $QUEUE = "yes"
then
# Insert kernel mod
$MODPROBE ip_queue
# check to see if it worked, if not exit with error
$LSMOD | grep ip_queue
IPQUEUE=$?
if [ "$IPQUEUE" = 1 ]; then
echo ""
echo "It appears you do not have the ip_queue kernel module compiled"
echo "for your kernel. This module is required for Snort-Inline and"
echo "QUEUE capabilities. You either have to disable QUEUE, or compile"
echo "the ip_queue kernel module for your kernel. This module is part"
echo "of the kernel source."
exit
fi
echo "Enabling Snort-Inline capabilities, make sure Snort-Inline is"
echo "running in -Q mode, or all outbound traffic will be blocked"
fi
### Support for connection tracking of FTP and IRC.
$MODPROBE ip_conntrack_ftp
$MODPROBE ip_conntrack_irc
### Enable ip_forward
echo "1" > /proc/sys/net/ipv4/ip_forward
###############################
####IPTABLES ENTRIES###########
###############################
# Set up the new policy on the IPTABLES INPUT chain. Use ACCEPT first to make su
re
that everything works and then lock this down later
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
# Start off on the INPUT table and allow anything back in that was originated fr
om your
system
$IPTABLES -A INPUT -i $LAN_IFACE -p all -m state --state ESTABLISHED, RELATED
-j ACCEPT
# Allow all Traffic on your loopback interface
$IPTABLES -A INPUT -i lo -p all -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
# This might be a good time to pass all incoming traffic over to Snort
$IPTABLES -A INPUT -i $LAN_IFACE -p all -j QUEUE
# USE these lines below if you need to log every protocol that is coming into yo
ur system.
This can be disk and resource intensive!!
### Inbound TCP
$IPTABLES -A INPUT -i $LAN_IFACE -p tcp -m state --state NEW -j LOG --log-level
6 --
log-prefix "INBOUND TCP: "
$IPTABLES -A INPUT -i $LAN_IFACE -p tcp -m state --state NEW -j ACCEPT
### Inbound UDP
$IPTABLES -A INPUT -i $LAN_IFACE -p udp -m state --state NEW -j LOG --log-level
6 --
log-prefix "INBOUND UDP: "
$IPTABLES -A INPUT -i $LAN_IFACE -p udp -m state --state NEW -j ACCEPT
### Inbound ICMP
$IPTABLES -A INPUT -i $LAN_IFACE -p icmp -m state --state NEW -j LOG --log-level
6
--log-prefix "INBOUND ICMP: "
$IPTABLES -A INPUT -i $LAN_IFACE -p icmp -m state --state NEW -j ACCEPT
### Inbound anything else
$IPTABLES -A INPUT -i $LAN_IFACE -m state --state NEW -j LOG --log-level 6 --log
prefix
"INBOUND OTHER: "
# Okay, this is where the magic all happens. All outbound traffic is counted,
# logged, and limited here. Targets (called Handlers) are what actually limit
# the connections. All 'Handlers' are defined at the bottom of the script.
# Egress filtering, don't want to let our compromised honeypot send spoofed pack
ets.
# Stops most outbound DoS attacks. However, we might want to allow our honeypots
to
# use dhcp to get an ip while in bridge mode.
if [ $MODE = "bridge" ]
then
$IPTABLES -A OUTPUT -i $LAN_IFACE -p udp -s $LAN_IP_RANGE --sport 68 -d
255.255.255.255 --dport 67 -j LOG --log-level 6 --log-prefix "DHCP OUT REQUEST:
"
$IPTABLES -A OUTPUT -i $LAN_IFACE -p udp -s $LAN_IP_RANGE --sport 68 -d
255.255.255.255 --dport 67 -j ACCEPT
fi
$IPTABLES -A OUTPUT -i $LAN_IFACE -s ! $LAN_IP_RANGE -j LOG --log-level 6 --
log-prefix "SPOOFED SOURCE: "
$IPTABLES -A OUTPUT -i $LAN_IFACE -s ! $LAN_IP_RANGE -j DROP
### DNS / NTP Perhaps one of your honeypots needs consistent
### outbound access to provide internal service.
for srvr in ${DNS_SVRS}; do
for host in ${DNS_HOST}; do
$IPTABLES -A OUTPUT -p udp -i $LAN_IFACE -s ${host} -d ${srvr} --dport 53 -j
LOG --log-level 6 --log-prefix "Legal DNS: "
$IPTABLES -A OUTPUT -p udp -i $LAN_IFACE -s ${host} -d ${srvr} --dport 53 -j
ACCEPT
done
done
if [ $MODE = "nat" ]
then
LIMIT_IP=$HPOT_IP
elif [ $MODE = "bridge" ]
then
LIMIT_IP=$PUBLIC_IP
fi
# This will ensure we don't restrict Honeypots talking to eachother, and
# we don't log them as outbound connections. If you do not want to see
# this log, comment out the logging rule. You will still need the ACCEPT
# rule to ensure they honeypots can talk to eachother freely.
# $IPTABLES -A OUTPUT -i $LAN_IFACE -s ${host} -d $LAN_IP_RANGE -j LOG --
log-level 6 --log-prefix "Honeypot -> Honeypot: "
$IPTABLES -A OUTPUT -i $LAN_IFACE -s ${host} -d $LAN_IP_RANGE -j ACCEPT
fi
# After all of this hard work...make sure that all of the IPTABLES entries are s
aved
/sbin/iptables-save > /etc/sysconfig/iptables
fi

S-ar putea să vă placă și