Linux-Noob Forums
Another Example Firewall - Printable Version

+- Linux-Noob Forums (https://www.linux-noob.com/forums)
+-- Forum: Linux Server Administration (https://www.linux-noob.com/forums/forum-8.html)
+--- Forum: Security and Firewalls (https://www.linux-noob.com/forums/forum-87.html)
+--- Thread: Another Example Firewall (/thread-2721.html)



Another Example Firewall - P38 - 2005-04-30


Here is another firewall example for you to review and offer me suggestions on how I can make it better. Feel free to use it in your own machines if you like the way it looks.

 

To use this firewall, copy it to a file on your machine, remove this text down to the line that starts #!/bin/sh leaving. Chmod the file to 700 or some such so that it can only be run as root. Edit the file and change the IP address variables at the top of the file to match your system. Then, run the script you have created. The firewall should load without errors. If there are errors, you will need to determine their cause and clear them up before you go forward.

 

After the script has run, do a "/etc/init.d/iptables restart" in order to save the firewall to your systems iptables cache. You will not need to re-run this script until/unless you make changes to it.

 

Now, this firewall, as configured, has one external interface. The external interface has three static ip addresses assigned to it. On my system, the three addresses are each assigned to a separate apache virtual server for serving up three different domains.

 

The firewall box, in my configuration, runs a web server, a mail server and a ssh server. You will notice ports open for this in the firewall. You will also notice that it only allows connections, with the exception of the web server, to the "primary external" ip address. Connections to the other external addresses are blocked.

 

Most incoming traffic is subject to rate restrictions on incoming new connections. There are exceptions to this because some services are better run with the limitations, but the ability to rate limit incoming connections has proven beneficial over and over in keeping out the bad traffic.

 

I continue to experiment with this firewall so you may see a few entries commented out. As I try different things, this is how I temporarily turn off things that I am currently not using.

 

If you have questions about how something works, please post them. I learn every time I dig into iptables and I will be happy to try to help.

 

P38

 



Code:
#!/bin/sh -x

################################################################################
###################################################
# EXTERNAL INTERFACE CONFIGURATION

INET_IP="1.1.1.1"        # External Interface 1
INET_IP2="1.1.1.2"        # External Interface 2
INET_IP3="1.1.1.3"        # External Inferface 3
INET_IFACE="eth0+"
INET_BROADCAST="1.1.1.255"


################################################################################
###################################################
# LOCAL LAN

LAN0_IP="172.16.1.1"        # Internal Interface 1
LAN0_IP_RANGE="172.16.1.0/24"
LAN0_IFACE="tun+"

LAN1_IP="172.16.2.1"        # Internal Interface 2
LAN1_IP_RANGE="172.16.2.0/24"
LAN1_IFACE="eth1"

BOB="172.16.2.100"        # Internal Machine with PCAnywhere Access
PCANYWHERE_PORT1="5631"        # PCAnywhere port
PCANYWHERE_PORT2="5632"        # PCAnywhere port

SAM="172.16.2.116"        # Internal Game Machine that runs World of Warcraft
WOW_PORT1="3724"        #
WOW_PORT2="6112"        # World of Warcraft ports
WOW_PORT3="6881:6999"        #

LAN2_IP="172.16.3.0"        # Internal Interface 3
LAN2_IP_RANGE="172.16.3.0/24"    #
LAN2_IFACE="eth2"        #


################################################################################
###################################################
# LOCALHOST

LO_IFACE="lo"
LO_IP="127.0.0.1"

################################################################################
###################################################
# SET PATH to BINARIES

IPTABLES="/sbin/iptables"
MODPROBE="/sbin/modprobe"
DEPMOD="/sbin/depmod"
E="/bin/echo"

################################################################################
###################################################
# IP Ranges only used for internal networks.

MARTIN0="10.0.0.0/8"
MARTIN1="172.16.0.0/12"
MARTIN2="192.168.0.0/16"
MARTIN3="192.254.0.0/16"

################################################################################
###################################################
# MULTICAST

MULTICAST_RANGE="224.0.0.0/8"

################################################################################
###################################################
# MODULES

$DEPMOD -a

$MODPROBE ip_tables
$MODPROBE ip_conntrack
$MODPROBE iptable_filter
$MODPROBE iptable_mangle
$MODPROBE iptable_nat
$MODPROBE ipt_LOG
$MODPROBE ipt_limit
$MODPROBE ipt_state
$MODPROBE ipt_owner
$MODPROBE ipt_REJECT
$MODPROBE ipt_MASQUERADE
$MODPROBE ip_conntrack_ftp
$MODPROBE ip_conntrack_irc
$MODPROBE ip_nat_ftp
$MODPROBE ip_nat_irc

################################################################################
###################################################
# FLUSH and DELETE all existing rules

$E "0" > /proc/sys/net/ipv4/ip_forward

$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -t nat -F POSTROUTING
$IPTABLES -t nat -F PREROUTING
$IPTABLES -F bad_tcp_packets
$IPTABLES -X bad_tcp_packets
$IPTABLES -F tcp_packets
$IPTABLES -X tcp_packets
$IPTABLES -F udp_packets
$IPTABLES -X udp_packets
$IPTABLES -F icmp_packets
$IPTABLES -X icmp_packets
$IPTABLES -F allowed
$IPTABLES -F allowed_2
$IPTABLES -X allowed
$IPTABLES -X allowed_2

################################################################################
###################################################
# POLICIES

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

################################################################################
###################################################
# CREATE CHAINS

$IPTABLES -N bad_tcp_packets
$IPTABLES -N allowed
$IPTABLES -N allowed_2
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets

################################################################################
###################################################
# bad_tcp_packets chain

$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK  -m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:NEW_not_SYN] '
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

################################################################################
###################################################
# allowed chain (rate limits enforced)

$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP --syn -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
$IPTABLES -A allowed -p TCP -j LOG  --log-level "NOTICE" --log-prefix '[DROP:RATE_LIMIT] '
$IPTABLES -A allowed -p TCP -j REJECT

################################################################################
###################################################
# allowed_2 chain  (no rate limits)

$IPTABLES -A allowed_2 -p TCP --syn -j ACCEPT
$IPTABLES -A allowed_2 -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed_2 -p TCP -j LOG  --log-level "NOTICE" --log-prefix '[DROP:NOT_ALLOWED] '
$IPTABLES -A allowed_2 -p TCP -j REJECT

################################################################################
###################################################
# tcp_packets chain

# less restricted TCP connection attempts (no rate limiting and no allow to any external interface)

$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 25 -j allowed_2                    # allow smtp
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed_2                     # allow http

# restricted TCP connections (with rate limiting and restricted to primary external interface)

$IPTABLES -A tcp_packets -p TCP -s 0/0 -d $INET_IP --dport 22 -j allowed                    # allow ssh
$IPTABLES -A tcp_packets -p TCP -s 0/0 -d $INET_IP --dport 113 -j allowed                   # allow ident
$IPTABLES -A tcp_packets -p TCP -s 0/0 -d $INET_IP --dport 5000 -j allowed                  # allow openvpn
$IPTABLES -A tcp_packets -p TCP -s 0/0 -d $INET_IP --dport 6881:6999 -j ACCEPT              # unrestricted access to ports bittorrent download/upload
$IPTABLES -A tcp_packets -p TCP -s 0/0 -d $INET_IP --dport 40000:40099 -j allowed           # ports for ssh port forwarding and local irc dcc

# Drop Microsoft Packets (TCP) so they don't show up in the logs

$IPTABLES -A tcp_packets -p TCP -i $INET_IFACE --destination-port 135:139 -j DROP
$IPTABLES -A tcp_packets -p TCP -i $INET_IFACE --destination-port 445 -j DROP

# Drop and log the rest

$IPTABLES -A tcp_packets
$IPTABLES -A tcp_packets -p TCP -j LOG  --log-level "NOTICE" --log-prefix '[DROP:TCP_PACKETS] '
$IPTABLES -A tcp_packets -p TCP -j REJECT --reject-with tcp-reset


################################################################################
###################################################
# UDP ports

$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 123 -j ACCEPT                     # ntp
$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 5000 -j ACCEPT                    # openssh
$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 40000:40099 -j ACCEPT             # used for ssh port forwarding

# Drop Microsoft Packets (UDP) so they don't show up in the firewall logs

$IPTABLES -A udp_packets -p UDP -i $INET_IFACE --destination-port 135:139 -j DROP
$IPTABLES -A udp_packets -p UDP -i $INET_IFACE --destination-port 67:68 -j DROP

# Drop and log the rest

$IPTABLES -A udp_packets -p UDP -j LOG  --log-level "NOTICE" --log-prefix '[DROP:UDP_PACKETS] '
$IPTABLES -A udp_packets -p UDP -j REJECT

################################################################################
###################################################
# ICMP rules

$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT

# Drop and log the rest

$IPTABLES -A icmp_packets -p ICMP -j LOG  --log-level "NOTICE" --log-prefix '[DROP:ICMP_PACKETS] '
$IPTABLES -A icmp_packets -p ICMP -j REJECT



################################################################################
###################################################
################################################################################
###################################################
# INPUT chain

$IPTABLES -A INPUT -p tcp -j bad_tcp_packets

# Allow DHCP from internal networks

$IPTABLES -A INPUT -p ALL -i $LAN0_IFACE -s 0.0.0.0/32 -j ACCEPT   # allow for DHCP
$IPTABLES -A INPUT -p ALL -i $LAN1_IFACE -s 0.0.0.0/32 -j ACCEPT   # allow for DHCP
$IPTABLES -A INPUT -p ALL -i $LAN2_IFACE -s 0.0.0.0/32 -j ACCEPT   # allow for DHCP

# Internal Networks

$IPTABLES -A INPUT -p ALL -i $LAN0_IFACE -s $LAN0_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LAN1_IFACE -s $LAN1_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LAN2_IFACE -s $LAN2_IP_RANGE -j ACCEPT

$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN0_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN1_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN2_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP2 -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP3 -j ACCEPT

# Rules for denied IP or NETWORKs

$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s $INET_IP -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:SPOOF] '
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s $INET_IP2 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:SPOOF] '
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s $INET_IP3 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:SPOOF] '

$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s $INET_IP -j DROP
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s $INET_IP2 -j DROP
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s $INET_IP3 -j DROP

$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN0 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:MARTIN_0] '
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN1 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:MARTIN_1] '
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN2 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:MARTIN_2] '
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN3 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:MARTIN_3] '

$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN0 -j DROP
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN1 -j DROP
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN2 -j DROP
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -s   $MARTIN3 -j DROP

$IPTABLES -A INPUT -p ALL -i $LAN0_IFACE  -s ! $LAN0_IP_RANGE -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:BAD_INTERNAL_IP0] '
$IPTABLES -A INPUT -p ALL -i $LAN1_IFACE  -s ! $LAN1_IP_RANGE -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:BAD_INTERNAL_IP1] '
$IPTABLES -A INPUT -p ALL -i $LAN2_IFACE  -s ! $LAN2_IP_RANGE -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:BAD_INTERNAL_IP2] '

$IPTABLES -A INPUT -p ALL -i $LAN0_IFACE  -s ! $LAN0_IP_RANGE -j DROP
$IPTABLES -A INPUT -p ALL -i $LAN1_IFACE  -s ! $LAN1_IP_RANGE -j DROP
$IPTABLES -A INPUT -p ALL -i $LAN2_IFACE  -s ! $LAN2_IP_RANGE -j DROP

# Drop Multicast from the external network.

$IPTABLES -A INPUT -i $INET_IFACE -d $MULTICAST_RANGE -j REJECT
$IPTABLES -A INPUT -i $INET_IFACE -s $MULTICAST_RANGE -j REJECT

# Rules for incoming packets from the internet.

$IPTABLES -A INPUT -p ALL  -d $INET_IP  -m state --state ESTABLISHED,RELATED  -j ACCEPT
$IPTABLES -A INPUT -p ALL  -d $INET_IP2 -m state --state ESTABLISHED,RELATED  -j ACCEPT
$IPTABLES -A INPUT -p ALL  -d $INET_IP3 -m state --state ESTABLISHED,RELATED  -j ACCEPT
$IPTABLES -A INPUT -p TCP  -i $INET_IFACE -j tcp_packets
$IPTABLES -A INPUT -p UDP  -i $INET_IFACE -j udp_packets
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets

# Log weird packets that don't match the above.

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level "NOTICE" --log-prefix '[ALERT!!] '

################################################################################
###################################################
################################################################################
###################################################
# FORWARD chain

$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets

# Accept the packets we actually want to forward

$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $LAN0_IFACE -j ACCEPT
$IPTABLES -A FORWARD -i $LAN1_IFACE -j ACCEPT
$IPTABLES -A FORWARD -i $LAN2_IFACE -j ACCEPT

# Forward PCANYWHERE PORTS to BOB
# Port 5631/tcp (PCANYWHERE_PORT1)

$IPTABLES -A FORWARD -i $INET_IFACE -d $BOB -p tcp --dport $PCANYWHERE_PORT1 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
$IPTABLES -A FORWARD -i $INET_IFACE -d $BOB -p tcp --dport $PCANYWHERE_PORT1 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:PCA_FWD_RATE_LMT] '
$IPTABLES -A FORWARD -i $INET_IFACE -d $BOB -p tcp --dport $PCANYWHERE_PORT1 -j DROP

# Port 5632/udp (PCANYWHERE_PORT2)

$IPTABLES -A FORWARD -i $INET_IFACE -d $BOB -p tcp --dport $PCANYWHERE_PORT2 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
$IPTABLES -A FORWARD -i $INET_IFACE -d $BOB -p tcp --dport $PCANYWHERE_PORT2 -m limit --limit 3/minute --limit-burst 3 -j LOG  --log-level "NOTICE" --log-prefix '[DROP:PCA_FWD_RATE_LMT] '
$IPTABLES -A FORWARD -i $INET_IFACE -d $BOB -p udp --dport $PCANYWHERE_PORT2 -j DROP

# WOW Ports

#$IPTABLES -A FORWARD -i $INET_IFACE -d $SAM -p tcp --dport $WOW_PORT1 -j ACCEPT
#$IPTABLES -A FORWARD -i $INET_IFACE -d $SAM -p tcp --dport $WOW_PORT2 -j ACCEPT
#$IPTABLES -A FORWARD -i $INET_IFACE -d $SAM -p tcp --dport $WOW_PORT3 -j ACCEPT

# Log weird packets that don't match the above.

$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level "NOTICE" --log-prefix '[DROP:FORWARD_PACKET_DIED] '

################################################################################
###################################################
################################################################################
###################################################
# OUTPUT chain

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN0_IP -j ACCEPT

$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets

################################################################################
###################################################
# Special OUTPUT rules to decide which IP's to allow.

$IPTABLES -A OUTPUT -p ALL -s $LAN1_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN2_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP2 -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP3 -j ACCEPT

################################################################################
###################################################
# Log weird packets that don't match the above.

$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level "NOTICE" --log-prefix '[DROP:OUTPUT_PACKET_DIED] '

################################################################################
###################################################
################################################################################
###################################################
# NAT table

################################################################################
###################################################
# IP Forwarding and Network Address Translation

$IPTABLES -t nat -A PREROUTING -p tcp -i $INET_IFACE -d $INET_IP --dport $PCANYWHERE_PORT1 -j DNAT --to-destination $BOB:$PCANYWHERE_PORT1
$IPTABLES -t nat -A PREROUTING -p udp -i $INET_IFACE -d $INET_IP --dport $PCANYWHERE_PORT2 -j DNAT --to-destination $BOB:$PCANYWHERE_PORT2

#$IPTABLES -t nat -A PREROUTING -p tcp -i $INET_IFACE -d $INET_IP --dport $WOW_PORT1 -j DNAT --to-destination $SAM:$WOW_PORT1
#$IPTABLES -t nat -A PREROUTING -p tcp -i $INET_IFACE -d $INET_IP --dport $WOW_PORT2 -j DNAT --to-destination $SAM:$WOW_PORT2
#$IPTABLES -t nat -A PREROUTING -p tcp -i $INET_IFACE -d $INET_IP --dport $WOW_PORT3 -j DNAT --to-destination $SAM:$WOW_PORT3


$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP

################################################################################
###################################################
################################################################################
###################################################

$E "1" > /proc/sys/net/ipv4/ip_forward