# Red Hat 7.1 Linux firewall using ipchains
# May, 2001
# configured by Dennis G. Allard, http://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 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 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, hence my decision to edit 
# this file manually.

# The network
# -----------
#
# This firewall is 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 'smurfing' via:
#
#   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.
#
# An explanation of SYN packets that I found somewhere
# on the net goes as follows (and I quote):
#
#   TCP connections require packets going in both directions
#   to work at all.  The solution is to block only the packets
#   used to request a connection.  These packets are called
#   SYN packets (ok, technically they're packets with the SYN
#   flag set, and the FIN and ACK flags cleared, but we call
#   them SYN packets). By disallowing only these packets, we
#   can stop attempted connections in their tracks.
#
# I wonder if this permits some form of man-in-the-middle
# attack that somehow hijacks an established TCP connection
# by guessing sequence numbers. That topic is over my head
# for now so I just mention my concern and happily proceed...


# 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

# Permit DNS queries...
# I'm not sure why the following line was configured by Red Hat installer
# although I believe it may be needed for systems that don't have a local
# DNS server behind the firewall.
# -A input -s <your 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