iptables howto (standalone host)

OS Used: Any Linux with iptables.
First written: January 2007
Last updated: March 2008

I find that creating a shell script is easiest way to set up your iptables firewall. Below is the script I use to make any changes to my iptables setup. Every time I need something changed, I edit the file, and run it again. That way I don't need to mess around trying to insert rules between other rules all from memory on the command line.

For those that don't know, the rules are processes in a hierarchical order (from the top down)

 

iptables v1.3.5
Note:  ipforwarding is now not a part of the iptables initscripts.
 *
 * To enable ipforwarding at bootup:
 * /etc/sysctl.conf and set net.ipv4.ip_forward = 1
 * and/or
 *   net.ipv6.ip_forward = 1
 * for ipv6.

 

Required Kernel Configuration

Networking options  --->
   [*] TCP/IP networking
      [*] IP: advanced router
   [*] Network packet filtering (replaces ipchains)
If you use 2.4.x, you have to enable the following for DHCP:
   [*] Socket Filtering

   IP: Netfilter Configuration  --->
      [*] Connection tracking (required for masq/NAT)
         [x] FTP protocol support
         [x] IRC protocol support
      [*] IP tables support (required for filtering/masq/NAT)
         [*] IP range match support
         [x] MAC address match support
         [*] Multiple port match support
         [*] Packet filtering
            [*] REJECT target support
            [x] REDIRECT target support
         [*] Full NAT
            [*] MASQUERADE target support
         [s] Packet mangling
            [s] MARK target support
         [x] LOG target support

 

iptables script

This is where we define our rules.

#!/bin/bash
# standalone iptables firewall script for hostname.domain.tld
# http://www.uplinkzero.com/howto/iptables-standalone-host

PATH=${PATH}:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
MAILTO=root


# This is how iptables processes packets
 #################################################################################################
 #          +------------+                +----------+                 +-------------+           #
 #  Packet -| PREROUTING |--- routing-----| FORWARD  |---------+-------| POSTROUTING |- Packets  #
 #  input   +------------+    decision    +-­---------+         |       +-------------+    out    #
 #                               |                             |                                 #
 #                          +-------+                      +--------+                            #
 #                          | INPUT |---- Local process ---| OUTPUT |                            #
 #                          +-------+                      +--------+                            #
 #################################################################################################


SSH=`cat ssh.txt`
BLOCKED=`cat blocked.txt`
PRIVATE=`cat private.txt`
MILITARY=`cat military.txt`
RESERVED=`cat reserved.txt`


# Set my IP addresses. (IP1 being the main IP)
  IP1=1.1.1.1
  IP2=1.1.1.2
  IP3=1.1.1.3
  IP4=1.1.1.4
  IP5=1.1.1.5
  IP6=1.1.1.6
  IP7=1.1.1.7

# Flush tables
  iptables -t filter -F
  iptables -t filter -X
  iptables -t nat -F
  iptables -t nat -X

# Set default action (action to be applied when no rule is met)
  iptables -t filter -P INPUT DROP
  iptables -t filter -P OUTPUT DROP
  iptables -t filter -P FORWARD DROP

# Accept all loopback connections and connections from own IP
  iptables -t filter -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
  iptables -t filter -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
  iptables -t filter -A INPUT -s $IP1 -d $IP1 -j ACCEPT
  iptables -t filter -A OUTPUT -s $IP1 -d $IP1 -j ACCEPT




    ##########################################################################################
    #                              Permanently Blocked IPs                                   #
    ##########################################################################################

# List of IPs I want to block
for ip in $BLOCKED
do
  iptables -t filter -A INPUT -s $ip -j LOG --log-prefix " FW BLOCK BLOCKED "
  iptables -t filter -A INPUT -s $ip -j DROP
done

# Private IP addresses
for ip in $PRIVATE
do
  iptables -t filter -A INPUT -s $ip -j LOG --log-prefix " FW BLOCK PRIV "
  iptables -t filter -A INPUT -s $ip -j DROP
done

# Military IP addresses
for ip in $MILITARY
do
  iptables -t filter -A INPUT -s $ip -j LOG --log-prefix " FW BLOCK MIL "
  iptables -t filter -A INPUT -s $ip -j DROP
done

# IANA reserved IP addresses
for ip in $RESERVED
do
  iptables -t filter -A INPUT -s $ip -j LOG --log-prefix " FW BLOCK IANA "
  iptables -t filter -A INPUT -s $ip -j DROP
done




    ##########################################################################################
    #                                        Stateful                                        #
    ##########################################################################################

# Allow established and related stuff in
  iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT




    ##########################################################################################
    #                                    Management Rules                                    #
    ##########################################################################################


# Allow SSH from IPs in ssh.txt
  for ip in $SSH
  do
    iptables -t filter -A INPUT -s $ip -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix " FW IN SSH "
    iptables -t filter -A INPUT -s $ip -p tcp --dport 22 -j ACCEPT
  done

# SSH Cleanup rule
  iptables -t filter -A INPUT -p tcp --dport 22 -j LOG --log-prefix " FW BLOCK SSH "
  iptables -t filter -A INPUT -p tcp --dport 22 -j DROP




    ##########################################################################################
    #                                    Port Redirects                                      #
    ##########################################################################################

# Redirect traffic originally for IP7 port 80 to port 5222
#  iptables -t nat -A PREROUTING -d $IP7 -p tcp --dport 80 -j REDIRECT --to-ports 5222

# Allow port 80 so that the redirect can take place. 
#  iptables -t filter -A INPUT -d $IP7 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN JAB-C2S-80 "
#  iptables -t filter -A INPUT -d $IP7 -p tcp --dport 80 -m state --state NEW -j ACCEPT




    ##########################################################################################
    #                                    Incoming Rules                                      #
    ##########################################################################################
    #________________________________________________________________________________________
    #
    # We accept only new connections in the incoming rules. 
    # Established and Related packets come in on the established and related rule above.
    #________________________________________________________________________________________


# Allow icmp requests (ping) on all IPs
  iptables -t filter -A INPUT -p icmp -j LOG --log-prefix " FW IN PING "
  iptables -t filter -A INPUT -p icmp -j ACCEPT

# Allow ftp in
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 21 -m state --state NEW -j LOG --log-prefix " FW IN FTP "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 21 -m state --state NEW -j ACCEPT

# Allow SMTP
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 25 -m state --state NEW -j LOG --log-prefix " FW IN SMTP "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 25 -m state --state NEW -j ACCEPT

# Allow DNS
  iptables -t filter -A INPUT -d $IP1 -p udp --dport 53 -m state --state NEW -j LOG --log-prefix " FW IN DNS "
  iptables -t filter -A INPUT -d $IP1 -p udp --dport 53 -m state --state NEW -j ACCEPT

# Allow HTTP
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 80 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 80 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP3 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP3 -p tcp --dport 80 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP4 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP4 -p tcp --dport 80 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP5 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP5 -p tcp --dport 80 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP6 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP6 -p tcp --dport 80 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP7 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " FW IN HTTP "
  iptables -t filter -A INPUT -d $IP7 -p tcp --dport 80 -m state --state NEW -j ACCEPT

# Allow HTTPS
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 443 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 443 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP3 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP3 -p tcp --dport 443 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP4 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP4 -p tcp --dport 443 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP5 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP5 -p tcp --dport 443 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP6 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP6 -p tcp --dport 443 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP7 -p tcp --dport 443 -m state --state NEW -j LOG --log-prefix " FW IN HTTPS "
  iptables -t filter -A INPUT -d $IP7 -p tcp --dport 443 -m state --state NEW -j ACCEPT

# Allow IMAP
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 143 -m state --state NEW -j LOG --log-prefix " FW IN IMAP "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 143 -m state --state NEW -j ACCEPT

# Allow IMAPS
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 993 -m state --state NEW -j LOG --log-prefix " FW IN IMAPS "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 993 -m state --state NEW -j ACCEPT

# Allow POP3
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 110 -m state --state NEW -j LOG --log-prefix " FW IN POP3 "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 110 -m state --state NEW -j ACCEPT

# Allow POP3S
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 995 -m state --state NEW -j LOG --log-prefix " FW IN POP3S "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 995 -m state --state NEW -j ACCEPT

# Allow ntop
#  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 3000 -m state --state NEW -j LOG --log-prefix " FW IN NTOP "
#  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 3000 -m state --state NEW -j ACCEPT

# Allow Jabber (XMPP)
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 5222 -m state --state NEW -j LOG --log-prefix " FW IN JAB-C2S "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 5222 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 5223 -m state --state NEW -j LOG --log-prefix " FW IN JAB-C2S-SSL "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 5223 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 5269 -m state --state NEW -j LOG --log-prefix " FW IN JAB-S2S "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 5269 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 7777 -m state --state NEW -j LOG --log-prefix " FW IN JAB-DATA "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 7777 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 3478 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 3478 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 3479 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 3479 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 3478 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 3478 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 3479 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP2 -p tcp --dport 3479 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p udp --dport 3478 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP1 -p udp --dport 3478 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1 -p udp --dport 3479 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP1 -p udp --dport 3479 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP2 -p udp --dport 3478 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP2 -p udp --dport 3478 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP2 -p udp --dport 3479 -m state --state NEW -j LOG --log-prefix " FW IN JAB-VOIP "
  iptables -t filter -A INPUT -d $IP2 -p udp --dport 3479 -m state --state NEW -j ACCEPT

# Jabber Web Interface
#  iptables -t filter -A INPUT -d $IP1 -s $IP1 -p tcp --dport 9090 -m state --state NEW -j LOG --log-prefix " FW IN JAB-WEB X "
#  iptables -t filter -A INPUT -d $IP1 -s $IP1 -p tcp --dport 9090 -m state --state NEW -j ACCEPT
#  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 9090 -m state --state NEW -j LOG --log-prefix " FW IN JAB-WEB "
#  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 9090 -m state --state NEW -j ACCEPT
#  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 9091 -m state --state NEW -j LOG --log-prefix " FW IN JAB-WEB-SSL "
#  iptables -t filter -A INPUT -d $IP1 -p tcp --dport 9091 -m state --state NEW -j ACCEPT

# Allow Open Arena
  iptables -t filter -A INPUT -d $IP1  -p tcp --dport 27960 -m state --state NEW -j LOG --log-prefix " FW IN OpenArena "
  iptables -t filter -A INPUT -d $IP1  -p tcp --dport 27960 -m state --state NEW -j ACCEPT
  iptables -t filter -A INPUT -d $IP1  -p udp --dport 27960 -m state --state NEW -j LOG --log-prefix " FW IN OpenArena "
  iptables -t filter -A INPUT -d $IP1  -p udp --dport 27960 -m state --state NEW -j ACCEPT




    ##########################################################################################
    #                                    Outgoing Rules                                      #
    ##########################################################################################

# I Allow all out because I'm lazy
  iptables -A OUTPUT -j ACCEPT
  iptables -t filter -A OUTPUT -j ACCEPT




    ##########################################################################################
    #                                    Drop/Cleanup Rules                                  #
    ##########################################################################################

# We always finish with a drop anything not specified above
  iptables -t filter -A INPUT -j DROP
  iptables -t filter -A FORWARD -j DROP
  iptables -t filter -A OUTPUT -j DROP




    ##########################################################################################
    #                                   SAVE and QUIT                                        #
    ##########################################################################################

echo " "
echo "Rules applied..."
echo "Executing iptables-save..."
`iptables-save`
echo " "
echo " "
echo " "
echo " "
echo "iptables script finished"
echo " "
echo " "

exit 0

ssh.txt

this file will list the ips from where you'd like to allow ssh

blocked.txt - these are IPs that we want to block.

69.41.160.0/19 
198.54.202.100
209.67.216.0/24

private.txt - private IP address space.

3.0.0.0/8
4.0.0.0/8 
8.0.0.0/8 
9.0.0.0/8 
12.0.0.0/8 
13.0.0.0/8 
15.0.0.0/8 
16.0.0.0/8 
17.0.0.0/8 
18.0.0.0/8 
19.0.0.0/8 
20.0.0.0/8 
21.0.0.0/8 
28.0.0.0/8 
32.0.0.0/8 
33.0.0.0/8 
34.0.0.0/8 
35.0.0.0/8 
38.0.0.0/8 
40.0.0.0/8 
44.0.0.0/8 
45.0.0.0/8 
47.0.0.0/8 
48.0.0.0/8 
52.0.0.0/8 
53.0.0.0/8 
54.0.0.0/8 
55.0.0.0/8 
56.0.0.0/8

military.txt - military assigned IP addresses

6.0.0.0/8 
11.0.0.0/8 
22.0.0.0/8 
25.0.0.0/8 
26.0.0.0/8 
29.0.0.0/8 
30.0.0.0/8 
49.0.0.0/8 
50.0.0.0/8 
51.0.0.0/8 
214.0.0.0/8 
215.0.0.0/8

reserved.txt - IANA reserved IP addresses

0.0.0.0/8 
1.0.0.0/8 
2.0.0.0/8 
5.0.0.0/8 
7.0.0.0/8 
23.0.0.0/8 
27.0.0.0/8 
31.0.0.0/8 
36.0.0.0/8 
37.0.0.0/8 
39.0.0.0/8 
42.0.0.0/8
92.0.0.0/8 
93.0.0.0/8 
94.0.0.0/8 
95.0.0.0/8 
100.0.0.0/8 
101.0.0.0/8 
102.0.0.0/8 
103.0.0.0/8 
104.0.0.0/8 
105.0.0.0/8 
106.0.0.0/8 
107.0.0.0/8 
108.0.0.0/8 
109.0.0.0/8 
110.0.0.0/8 
111.0.0.0/8 
112.0.0.0/8 
113.0.0.0/8 
114.0.0.0/8 
115.0.0.0/8 
197.0.0.0/8 
223.0.0.0/8 
240.0.0.0/8 
241.0.0.0/8 
242.0.0.0/8 
243.0.0.0/8 
244.0.0.0/8 
245.0.0.0/8 
246.0.0.0/8 
247.0.0.0/8 
248.0.0.0/8 
249.0.0.0/8 
250.0.0.0/8 
251.0.0.0/8 
252.0.0.0/8 
253.0.0.0/8 
254.0.0.0/8 
255.0.0.0/8