IPTABLES Firewall Example
IPCHAINS Firewall Example (you are here)

# Red Hat 7.1 Linux firewall using ipchains
# May, 2001
# configured by Dennis G. Allard and Don Cohen, https://oceanpark.com
#
# Permission to copy is granted provided that credit is given
# to the author and whatever HOWTOs are used to understand this
# stuff.
#
# No warrenty is implied.  Use at your own risk!!

# This web page documents my old ipchains firewall.  I have
# updated my firewall to use iptable and udpated the description
# of my firewall at https://oceanpark.com/notes/firewall_example.html.

# This file is /etc/sysconfig/ipchains, intended for
# consumption by the script /etc/rc.d/init.d/ipchains,
# which makes use of the script /sbin/ipchains-restore.

# In Red Hat 7.1, the man page for ipchains and for
# ipchains-restore does not document the syntax of this
# file.  I had to read the script to understand better
# what is going on.

# The firewall that the Red Hat 7.1 installer set up for me
# in response to my request for a high level of security
# was too restrictive.   And, I couldn't find any GUI tool
# in either GNOME or KDE to reconfigure the firewall.
# For example, the KDE menu item for editing my firewall
# showed an empty set of rules even though this file and
# the above startup script existed.  So I had no confidence
# in the GUI firewall tools, resulting in my decision to edit 
# this file manually.

# The network
# -----------
#
# This firewall was running on a gateway machine having two
# ethernet interfaces, an external one, eth0, which  is
# my DSL connection to my ISP, and an internal one, eth1
# which is assigned to 198.211.65.1, an IP number on my
# class C network.  I run a web server, DNS server, and
# sendmail on the firewall machine itself.
#
# Using this file in a more complex network would require
# some modifications. Particular attention would need to
# be given to using the right the IP numbers and interfaces,
# among other things. :-)

# Running this script
# -------------------
#
# Red Hat 7.1 runs /etc/rc.d/init.d/ipchains at system
# startup, which uses this file as input.  You can
# turn ipchains on and off via chkconfig.  See:
#
#   chkconfig --list | grep ipchains
#
# You can restart the ipchains firewall via:
#
#   /etc/rc.d/init.d/ipchains restart
#
# A good way to show your ipchains rules is with:
#
#   ipchains -vnL


# Preliminaries
# -------------
#
# To permit machines internal to the network to be able to
# send IP packets to the outside world, enable IP Forwarding:
#
#   echo 1 > /proc/sys/net/ipv4/ip_forward
#
# Prevent SYN floods from consuming memory resources:
#
#   echo 1 > /proc/sys/net/ipv4/tcp_syncookies
#
# I place the above echo commands into /etc/rc.d/rc.local
# so that they will be executed at boot time.


# The basic idea of this firewall
# -------------------------------
#
# Provide rules that are applied in the following order:
#
# ACCEPT all UDP packets for certain UDP services
#
# DENY all other UDP packets.
#
# ACCEPT SYN packets just for certain TCP services
# SYN packets are specified via the -y flag in the input
# rules defined below.  Note that certain services can be
# further filtered by xinetd.
#
# DENY all other TCP SYN packets.
#
# ACCEPT all other TCP packets (the default input chain policy.)
#
# In other words, we allow any TCP packet through that is part of an
# established TCP connection, but we are very selective in just which
# connections we permit to be made to start off with.  IMPORTANT:
# ipchains is less powerful than iptables  since iptables, introduced
# in linux kernel 2.4 provides for Stateful Packet Inspection.  ipchains
# will allow packets in that are not part of an existing TCP connection.
# Although such packets will not normally be processed by an application,
# they can be used as part of a denial of service attack.  We recommend
# that you use an iptables firewall, which is able to audit connections
# more completely. See:
#
#   IPTABLES Firewall Example
#
# A brief explanation of SYN packets goes as follows.  TCP connections
# are initiated via a hand shaking protocol between the client and server
# programs at either end of the connection.  The very first TCP packet
# is sent by the client to the server and is called a SYN packet,
# because it has the SYN flag set to 1 in the TCP packet header.  We
# only allow SYN packets for the specific servers running on specific
# ports of specific hosts.  Subsequently, we only permit further TCP
# packets in that are determined to be part of a connection whose
# initial SYN packet was already accepted and responded to by one of our
# servers.  By stopping all other packets in their tracks, we limit
# attempts to attack our internal network.
# 
# There are subtle ways that Denial of Service attacks can be performed
# if an attacker is able to somehow gain access to a machine inside our
# network or otherwise hijack a connection.  However, even in such
# cases, current research is leading to ways to greatly limit the effect
# of such attacks. For further reading, see: https://www.cs3-inc.com/ddos.html.
#
# For detailed background reading about iptables, please refer to:
# https://www.netfilter.org/documentation/tutorials/blueflux/iptables-tutorial.html
#


# oceanpark.com firewall rules (using ipchains)
# ---------------------------------------------

# Tell ipchains-restore what default policies to use...
:input ACCEPT
:forward ACCEPT
:output ACCEPT

# The above will accept anything not prevented by the following rules.

# Deny any packet coming in on the public internet interface eth0
# which has source address of our local network (attempt to spoof an
# address which should never come from any place but eth1) or which
# claims to be from the reserved local loop network 127.0.0.0.
-A input -i eth0 -s 198.211.65.0/24 -j DENY
-A input -i eth0 -s 127.0.0.0/8 -j DENY

# Accept all tcp SYN packets for protocols SMTP, HTTP, and SSH
# Note, SMTP connections are further audited by my SMTP server
-A input -s 0/0 -d 198.211.65.1/32 25 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 80 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 22 -p tcp -y -j ACCEPT

# If you query remote DNS servers, permit UDP responses from it
# -A input -s <remote DNS server IP> 53 -d 0/0 -p udp -j ACCEPT

# I had to add the following line to make my DNS server honor requests
# from the public internet.
-A input -s 0/0 -d 0/0 53 -p udp -j ACCEPT

# Open up IMAP server (see /etc/xinetd.conf for who can use it)
-A input -s 0/0 -d 0/0 143 -p tcp -y -j ACCEPT

# Open up FTP server (see /etc/xinetd.conf for who can use it)
-A input -s 0/0 -d 0/0 20 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 21 -p tcp -y -j ACCEPT

# Allow all inputs from the internal and local interfaces
-A input -s 0/0 -d 0/0 -i eth1 -j ACCEPT
-A input -s 0/0 -d 0/0 -i lo -j ACCEPT

# If we wanted to use masqueading (can do even for legit internal IPs)
# -A forward -s 198.211.65.78 -j MASQ

# Finally, DENY all connection requests to any UDP port not yet provided
# for and all SYN connection requests to any TCP port not yet provided
# for.  Using DENY instead of REJECT means that no 'ICMP port
# unreachable' response is sent back to the client attempting to
# connect.  I.e., DENY just ignores connection attempts.  Hence, use of
# DENY causes UDP connection requests to time out and TCP connection
# requests to hang.  Hence, using DENY instead of REJECT may have
# the effect of frustrating attackers due to increasing the amount of
# time taken to probe ports.

# Note that there is a fundamental difference between UDP and TCP
# protocols.  With UDP, there is no 'successful connection' response.
# With TCP, there is.  So an attacking client will be left in the dark
# about whether or not the denied UDP packets arrived and will hang
# waiting for a response from denied TCP ports.  An attacker will not
# be able to immediately tell if UDP connection requests are simply
# taking a long time, if there is a problem with connectivity between
# the attacking client and the server, or if the packets are being
# ignored.  This increases the amount of time it takes for an attacker
# to scan all UDP ports.  Similarly, TCP connection requests to denied
# ports will hang for a long time.  By using REJECT instead of DENY, you
# would prevent access to a port in a more 'polite' manner, but give out
# more information to wannabe attackers, since the attacker can positively
# detect that a port is not accessible in a small amount of time from
# the 'ICMP pot unreachable' response.

-A input -s 0/0 -d 0/0 -p udp -j DENY
-A input -s 0/0 -d 0/0 -p tcp -y -j DENY

# end of firewall rules
If you find this firewall script useful, consider making a donation to support my work.

This Web page is highly ranked by Google. If you would like to help improve this Web page to provide a more comprehensive presentation of firewall examples, augmented by graphic illustrations and links to other resources, please contact allard@oceanpark.com.