Loading...
 
Location : Got Root >
Linux firewall rulesets and snippets of rule sets
3d browser Print

Setting up the basics

We like to use the iptables command in our scripts with the full path set, that is, instead of calling it as:

iptables

We use:

/sbin/iptables

We do this because we want to make sure our scripts are calling the right copy of iptables, in case we've installed some newer or experimental copy of the userland program. To make this easier, we also set it as a variable at the top of our firewall scripts in this manner:

IPTABLES="/sbin/iptables"

So in our scripts, if you see this:

$IPTABLES

That just short hand for /sbin/iptables or whatever the path is to your copy of IPTABLES. Change this variable to reflect the location that is appropriate for your system (i.e. /usr/local/bin/iptables).

How to set your default policy to a paranoid setting

$IPTABLES -P OUTPUT  DROP
$IPTABLES -P INPUT   DROP
$IPTABLES -P FORWARD DROP

Fixing MTU/MSS problems

$IPTABLES -A OUTPUT -o eth1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$IPTABLES -A FORWARD -o eth1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

QOS tricks

#QOS tricks
$IPTABLES -A PREROUTING -t mangle -p tcp --sport telnet -j TOS --set-tos Minimize-Delay
$IPTABLES -A PREROUTING -t mangle -p tcp --sport ftp -j TOS --set-tos Minimize-Delay
$IPTABLES -A PREROUTING -t mangle -p tcp --sport ftp-data -j TOS --set-tos Maximize-Throughput

Simple portscan detector Note: You will need to install the "recent" module for these rules to work. If you do not have the "recent" module installed, simply remove this section from these rules "-m recent --set". Remove that, and it should work.

$IPTABLES -N PORTSCAN
        #portscan detection module
        # NMAP FIN/URG/PSH
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL FIN,URG,PSH -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL FIN,URG,PSH -m recent --set -j PORTSCAN
        # SYN/RST
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags SYN,RST SYN,RST -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags SYN,RST SYN,RST -m recent --set -j PORTSCAN
        # SYN/FIN -- Scan(probably)
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags SYN,FIN SYN,FIN -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags SYN,FIN SYN,FIN -m recent --set -j PORTSCAN
        # NMAP FIN Stealth
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL FIN -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL FIN -m recent --set -j PORTSCAN
        # ALL/ALL Scan
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL ALL -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL ALL -m recent --set -j PORTSCAN
        # NMAP Null Scan
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL NONE -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL NONE -m recent --set -j PORTSCAN
        #XMAS
        $IPTABLES -A INPUT -i all -p tcp  --tcp-flags ALL URG,ACK,PSH,RST,SYN,FIN -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp  --tcp-flags ALL URG,ACK,PSH,RST,SYN,FIN -m recent --set -j PORTSCAN
        $IPTABLES -A PORTSCAN  -m limit --limit 1/second -j LOG  --log-level info --log-prefix "PORTSCAN -- SHUN "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
        $IPTABLES -A PORTSCAN -j DROP

Drop packets with bad flags

Note: You will need to install the "recent" module for these rules to work. If you do not have the "recent" module installed, simply remove this section from these rules "-m recent --set". Remove that, and it should work.

# Drop packets with bad tcp flags
        $IPTABLES -N BAD_FLAGS
        $IPTABLES -A INPUT -p tcp --tcp-option 64 -m recent --set -j BAD_FLAGS
        $IPTABLES -A INPUT -p tcp --tcp-option 128 -m recent --set -j BAD_FLAGS
        $IPTABLES -A BAD_FLAGS  -m limit --limit 1/second -j LOG  --log-level info --log-prefix "BAD_FLAGS -- SHUN "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
        $IPTABLES -A BAD_FLAGS -j DROP

Drop packets with bad IP options set

Note: You will need to install the "recent" module for these rules to work. If you do not have the "recent" module installed, simply remove this section from these rules "-m recent --set". Remove that, and it should work.

$IPTABLES -N IPOPTS
$IPTABLES -A INPUT -m ipv4options --ssrr -m recent --set -j IPOPTS
$IPTABLES -A INPUT -m ipv4options --lsrr -m recent --set -j IPOPTS
$IPTABLES -A INPUT -m ipv4options --rr -m recent --set -j IPOPTS
$IPTABLES -A IPOPTS -j LOG --log-prefix "BAD IPOPTS SHUN " --log-tcp-sequence  --log-tcp-options  --log-ip-options -m limit --limit 1/second
$IPTABLES -A IPOPTS -j DROP

Drop packets that are too small Note: You will need to install the "recent" module for these rules to work. If you do not have the "recent" module installed, simply remove this section from these rules "-m recent --set". Remove that, and it should work.

$IPTABLES -N SMALL
$IPTABLES -A INPUT -p udp -m length --length 0:27 -m recent --set -j SMALL
$IPTABLES -A INPUT -p tcp -m length --length 0:39 -m recent --set -j SMALL
$IPTABLES -A INPUT -p icmp -m length --length 0:27 -m recent --set -j SMALL
$IPTABLES -A INPUT -p 30 -m length --length 0:31 -m recent --set -j SMALL
$IPTABLES -A INPUT -p 47 -m length --length 0:39 -m recent --set -j SMALL
$IPTABLES -A INPUT -p 50 -m length --length 0:49 -m recent --set -j SMALL
$IPTABLES -A INPUT -p 51 -m length --length 0:35 -m recent --set -j SMALL
$IPTABLES -A INPUT -m length --length 0:19 -m recent --set -j SMALL
$IPTABLES -A SMALL -m limit --limit 1/second -j LOG  --log-level info --log-prefix "SMALL -- SHUN "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
$IPTABLES -A SMALL -j DROP

Use simple atomic string matching to drop packets that are possible attacks

Note: You need the STRING patch for this work with your kernel and iptables.

$IPTABLES -N STRINGS
#packets coming in
$IPTABLES -A INPUT -p tcp --dport 22 -m string --string '"Version_Mapper"' -j STRINGS
$IPTABLES -A FORWARD -p tcp --dport 22 -m string --string '"Version_Mapper"' -j STRINGS
$IPTABLES -A INPUT -p tcp --dport 22 -m string --string '"/bin/sh"' -j STRINGS
$IPTABLES -A INPUT -p tcp --dport 443 -m string --string "TERM=xterm" -j STRINGS
$IPTABLES -A STRINGS -m recent --set -j DROP

A little trick to help hide your firewall from traceroute

Note: You may need the TTL patch for this work with your kernel and iptables.

$IPTABLES -N TTL
$IPTABLES -t mangle -A PREROUTING -p UDP --dport 33434:33542 -j TTL --ttl-inc 1
$IPTABLES -A TTL -j ACCEPT

Reject all BOGUS packets

$IPTABLES -N BOGUS
$IPTABLES -t filter -p all -A INPUT -m conntrack --ctstate INVALID -j BOGUS
$IPTABLES -t filter -p all -A OUTPUT -m conntrack --ctstate INVALID -j BOGUS
$IPTABLES -t filter -p all -A FORWARD -m conntrack --ctstate INVALID -j BOGUS
#$IPTABLES -A BOGUS -m limit --limit 1/second -j LOG  --log-level info --log-prefix "INVALID PACKET -- DROP "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
$IPTABLES -A BOGUS -j REJECT

Note: We commented out the logging because on busy firewalls this can make some very noisy logging, but try turning it on to see how it works for you. With the logging turned off you will miss knowing about some attacks, although the firewall will still stop them.

Drop "unclean" packets

Note: We don't use these rules on our firewalls anymore. They are experimental, and may cause problems for you.

$IPTABLES -N DIRTY
$IPTABLES -A INPUT -m unclean   -j DIRTY
$IPTABLES -A OUTPUT -m unclean  -j DIRTY
$IPTABLES -A FORWARD -m unclean  -j DIRTY
$IPTABLES -A DIRTY -m limit --limit 1/second -j LOG  --log-level info --log-prefix "UNCLEAN PACKET -- DROP "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
$IPTABLES -A DIRTY -j DROP

More advanced port scan detector

Note: You will need to install the PSD patch for iptables into your kernel for these to work.

$IPTABLES -N PSD
        $IPTABLES -A INPUT -i eth+ -m psd -m limit --limit 5/minute -j PSD
        $IPTABLES -A INPUT -i ipsec+ -m psd -m limit --limit 5/minute -j PSD
        $IPTABLES -A INPUT -i tun+ -m psd -m limit --limit 5/minute -j PSD
        $IPTABLES -A FORWARD -i eth+ -m psd -m limit --limit 5/minute -j PSD
        $IPTABLES -A FORWARD -i ipsec+ -m psd -m limit --limit 5/minute -j PSD
        $IPTABLES -A FORWARD -i tun+ -m psd -m limit --limit 5/minute -j PSD
        $IPTABLES -A PSD  -m limit --limit 1/second -j LOG  --log-level info --log-prefix "PSD -- DROP "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
        $IPTABLES -A PSD -j DROP

Block fragments

Note: These rules should never trip, if they do, something is seriously wrong with your firewall or you are not use any stateful rules - which means your firewall is configured incorrectly in most cases.

$IPTABLES -N NOFRAGS
$IPTABLES -A OUTPUT -p ip -f -j NOFRAGS
$IPTABLES -A INPUT -p ip -f -j NOFRAGS
$IPTABLES -A FORWARD -p ip  -f -j NOFRAGS
$IPTABLES -A NOFRAGS   -m limit --limit 1/second -j LOG  --log-level info --log-prefix "Fragment -- DROP "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
$IPTABLES -A NOFRAGS  -j DROP

Detect and drop syn floods

$IPTABLES -N syn-flood
$IPTABLES -A INPUT -i eth+ -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j syn-flood
$IPTABLES -A FORWARD -i eth+ -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j syn-flood
$IPTABLES -A syn-flood -m limit --limit 4/s --limit-burst 16 -j RETURN
$IPTABLES -A syn-flood -m limit --limit 75/s --limit-burst 100 -j RETURN
$IPTABLES -A syn-flood -j LOG --log-prefix "SYN FLOOD " --log-tcp-sequence  --log-tcp-options  --log-ip-options -m limit --limit 1/second
$IPTABLES -A syn-flood -j DROP

Enforce SYN only connections on NEW connections

$IPTABLES -A INPUT -p tcp  ! --syn -m conntrack --ctstate NEW -j LOG --log-prefix "New not syn:"
$IPTABLES -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
$IPTABLES -A FORWARD -p tcp  ! --syn -m conntrack --ctstate NEW -j LOG --log-prefix "New not syn:"
$IPTABLES -A FORWARD -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

Send TCP resets for incoming AUTH connections

Note: This will help with "stalled" SMTP connections, IRC and other protocols that try to do an ident lookup against the host initiating the connection. This is a performance ruleset, and not specifically a security one.

$IPTABLES -A INPUT -p tcp -s any/0 --dport 113 -j REJECT --reject-with tcp-reset
$IPTABLES -A FORWARD -p tcp -i eth+ -s any/0 --dport 113 -j REJECT --reject-with tcp-reset

Note: You will need to install the "recent" module for these rules to work. If you do not have the "recent" module installed, simply remove this section from these rules "-m recent --set". Remove that, and it should work.

Drop packets to "odd" ports

$IPTABLES -N ODDPORTS
$IPTABLES -A INPUT -p udp --sport 2:21 -m recent --set  -j ODDPORTS
$IPTABLES -A INPUT -p udp --dport 2:21 -m recent --set  -j ODDPORTS
$IPTABLES -A INPUT -p tcp --dport 0 -m recent --set -j ODDPORTS
$IPTABLES -A INPUT -p tcp --sport 0 -m recent --set -j ODDPORTS
$IPTABLES -A FORWARD -i eth+ -p udp --dport 2:21 -m recent --set  -j ODDPORTS
$IPTABLES -A FORWARD -i eth+ -p tcp --dport 0 -m recent --set -j ODDPORTS
$IPTABLES -A FORWARD -i eth+ -p tcp --sport 0 -m recent --set -j ODDPORTS
$IPTABLES -A ODDPORTS -m limit --limit 1/second -j LOG  --log-level info --log-prefix "ODDPORTS -- SHUN "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
$IPTABLES -A ODDPORTS -j DROP

Ruleset to block repeat offenders

Note: This ruleset is "called" from other ruleset thru the use of the "-m recent" switch. You must have the "recent" module installed for these rules to work. Anywhere you have a DROP sequence (or REJECT) and want to add the offending IP into a temporarily list of offender hosts, just add the "-m recent" switch. Example follows after ruleset:

$IPTABLES -N OFFENDER
$IPTABLES -A INPUT -p all -m recent --rcheck --seconds 300 -j OFFENDER $IPTABLES -A FORWARD -p all -m recent --rcheck --seconds 300 -j OFFENDER
$IPTABLES -A OFFENDER -m limit --limit 1/second -j LOG  --log-level info --log-prefix "OFFENDER -- SHUN "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
$IPTABLES -A OFFENDER -j DROP

Example Use:

Note: You will need to install the "recent" module for these rules to work too. If you do not have the "recent" module installed, simply remove this section from these rules "-m recent --set". Remove that, and it should work.

$IPTABLES -N PORTSCAN
        #portscan detection module
        # NMAP FIN/URG/PSH
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL FIN,URG,PSH -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL FIN,URG,PSH -m recent --set -j PORTSCAN
      # SYN/RST
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags SYN,RST SYN,RST -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags SYN,RST SYN,RST -m recent --set -j PORTSCAN
        # SYN/FIN -- Scan(probably)
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags SYN,FIN SYN,FIN -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags SYN,FIN SYN,FIN -m recent --set -j PORTSCAN
        # NMAP FIN Stealth
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL FIN -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL FIN -m recent --set -j PORTSCAN
        # ALL/ALL Scan
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL ALL -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL ALL -m recent --set -j PORTSCAN
        # NMAP Null Scan
        $IPTABLES -A INPUT -i all -p tcp --tcp-flags ALL NONE -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp --tcp-flags ALL NONE -m recent --set -j PORTSCAN
        #XMAS
        $IPTABLES -A INPUT -i all -p tcp  --tcp-flags ALL URG,ACK,PSH,RST,SYN,FIN -m recent --set -j PORTSCAN
        $IPTABLES -A FORWARD -i all -p tcp  --tcp-flags ALL URG,ACK,PSH,RST,SYN,FIN -m recent --set -j PORTSCAN
        $IPTABLES -A PORTSCAN  -m limit --limit 1/second -j LOG  --log-level info --log-prefix "PORTSCAN -- SHUN "  --log-tcp-sequence  --log-tcp-options  --log-ip-options
        $IPTABLES -A PORTSCAN -j DROP


Contributors to this page: Michael Shinn20259 points  .
Page last modified on Wednesday 23 of March, 2005 18:30:38 EST by Michael Shinn20259 points .
The content on this page is licensed under the terms of the Got Root License.

Our Books