Linux Firewall Using a Laptop

This article describes how I took an old Sharp PC-9020 Pentium 120 laptop computer and turned it into a NAT router/firewall.  The issues encountered are presented first, with the actual files modified at the end.  This article assumes the reader possesses an intermediate level of knowledge on Linux.

Motivation

I needed a firewall for my DSL connection, and I needed it to be small and preferably, draw little power.  I thought about buying a DSL router from LinkSys or D-Link, but my main concern was the lack of control over the box.  I do not know if there is a security list for these things, and I'm very afraid of trying to upgrade a BIOS.

I had my old P-120, whose floppy frive was totally dead, that had not been used for almost a year.  I decided to put it to use.

Risks

Since I had already replaced the hard drive in this laptop twice (due to overheating from being on for several days straight while running Linux), I knew I had to overcome the heating problem in the laptop.  There is also the risk of no usable floppy drive.

Implementation

First step was to procure two PCMCIA NIC's. I already had an old LinkSys 10mbps card, so I went to the local computer store and bought another one. Even though the second card is a newer model, it worked just fine.

Without a floppy drive, and a bootable CD-ROM, I removed the hard drive and inserted it and the two PCMCIA NIC's into an IBM ThinkPad 600X laptop, and installed Mandrake Linux 7.2 on it.  (I have since bought a 2.5" -> 3.5" adapter so I can use this drive in my desktop computer.  These adapters are available on-line for $13, or about $6 on ebay.com.)  This takes care of the no floppy issue.

Next, I put the hard drive and NIC's into the old P-120, and I secured it using my own advice.

To overcome the heat, I set the BIOS hard drive shutdown feature and set it to 1 minute.  Historically, this has done nothing on this computer.  Next, I made a startup script and set it to run in rn level 3 to shutdown the hard drive after 1 minute of inactivity.  Of course, Linux puts a mark in the system logs every 20 minutes, just to let you know it's still alive, so now I was faced with a hard drive that never shutdown, or one that would spin up every 20 minutes, rapidly reducing its life.  I solved this with a ramdisk where I store the logs.

Next, because I'm using a ramdisk, I need to make sure it gets mounted when the mount -a command is run, so I added this entry to /etc/fstab:

/dev/ram /var/log ext2 defaults 1 1
and commented these entries:
# /mnt/cdrom /mnt/cdrom supermount fs=iso9660,dev=/dev/cdrom 0 0
# /mnt/floppy /mnt/floppy supermount fs=vfat,dev=/dev/fd0 0 0

Since the logs are being written to periodically, and at random intervals, the bdflush daemon would flush the hard disk buffers and keep the hard drive spinning.  To overcome this, I set up a 2 MB ramdisk and mounted it under /var/log.  This works great, except now there is no continuity between reboots.  Next, I created a taraball of the /var/log directory and stored it in /var/log.tgz.  Right after mounting the ramdisk, I untar the tarball so the logs are ready for use.  I also added a script to save the logs in the same tarball whenever the system leaves the current run level.

Testing

First, I tested the firewall capabilities by going to grc.com and using the Shields Up scanner.  Due to a problem in the Windows 2000 Server, Steve Gibson can't validate your firewall consistently (he says this on his web site).  So I next went to http://scan.sygatetech.com and tested the firewwall.  It worked perfectly.

Next, I tested the hard drive shutdown features using this script:

#!/bin/ash
while [ 1 ]; do
 echo `date` `hdparm -C /dev/hda`
 sleep 60
done


and I redirected the output to /var/log do I could analyze how often the hard drive was up.  As it turned out, the cron daemon started up the hard drive as it processed the daily cron jobs.  Since none of the files cahnge frequently on this box, I moved all of the daily jobs in /etc/cron.daily over to /etc/cron.weekly.

Outstanding Issues

Currently, there is no provision to save the logs in case of a system crash.  In my experience at WorldMarket Services, system crashes are always due to hardware failures, and the logs are never current anyway.

Also, there is no alerting mechanism for when the ramdrive fills up, which will cause logging to stop.  This happened to me when a Security Professional scanned the firewall (which currently shows no vulnerabilities).  I currently have the ramdisk set to 4 MB.

Summary

The net result of my project is the hard drive spins up for a few minutes each day (don't know why, yet), and I have an ultra-secure firewall that has a built-in battery backup.

Files

Here are the files that I modified or created to implement this project.

/etc/hosts.deny

ALL: ALL 

/etc/hosts.allow

ALL: LOCAL, 10.0.0. 

/etc/rc.d/rc.firewall

echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter 

/etc/rc.d/rc.sysinit (due to the size of this file, only edits and placement are shown)

# Enter root and /proc into mtab. (pixel) also added /initrd/loopfs for loopback root
mount -f /initrd/loopfs 2>/dev/null
mount -f /
mount -f /proc
###
# Added 06/16/01 to support RAMDISK logs
action "Setting up /var/log on ramdisk" /bin/true 
dd if=/dev/zero of=/dev/ram bs=1k count=4096 > /dev/null
mke2fs -vm0 /dev/ram 4096 > /dev/null
###
# If Aurora wasn't started prior to this, and if the partition where
# Monitor resides is mounted, start it now. Otherwise, we'l have to
# wait until it is mounted...
:
:
:
# Mount all other filesystems (except for NFS and /proc, which is already
# mounted). Contrary to standard usage,
# filesystems are NOT unmounted in single user mode.
# (pixel) also do not mount loopback, will be done later
action "Mounting local filesystems" mount -a -t
nonfs,smbfs,ncpfs,proc,loop
###
# Added 06/16/06 for ramdisk logging 
cd /var/log 
tar -xpf ../log.tgz ###
# (pixel) Check loopback filesystems

/etc/init.d/killramdisk

### 
# Added 06/16/01 to support ramdisk logging
#
# This script saves the ramdisk log to hard drive 
### 
echo "Saving /var/log" 
cd /var/log
tar -cpf ../log.tgz * 

/etc/init.d/hdparms

### 
# Added 06/16/01 to shutdown the hard drive after 1 minute 
# 
### 
hdparm -S 12 /dev/hda

/etc/init.d/firewall (This script was taken from "Optimizing and Securing Linux Red Hat Edition, available from www.openna.com, then modified to suit my needs. Some parts of this script have been outdated, but this is irrelevent to this application as I want to prevent all connections from all networks except my own.)

#!/bin/sh
#
# Invoked from /etc/rc.d/init.d/firewall.
# chkconfig: - 60 95
# description: Starts and stops the IPCHAINS Firewall \
# used to provide Firewall network services.

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
if [ ${NETWORKING} = "no" ]; then
    exit 0
fi

if [ ! -x /sbin/ipchains ]; then
    exit 0
fi

# See how we were called.
case "$1" in
    start)
echo -n "Starting Firewalling Services: "
# Some definitions for easy maintenance.

# ----------------------------------------------------------------------------
# EDIT THESE TO SUIT YOUR SYSTEM AND ISP.

EXTERNAL_INTERFACE="eth0"               # Internet connected interface
LOCAL_INTERFACE_1="eth1"                # Internal LAN interface
LOOPBACK_INTERFACE="lo"                 # Your local naming convention
IPADDR=`/sbin/ifconfig | grep -A 4 $EXTERNAL_INTERFACE | awk '/inet/ { print $2 } ' | sed -e s/addr://` # Your IP address
LOCALNET_1="10.0.0.0/24"                # Whatever private range you use
# IPSECSG="my.ipsecsg.address"          # Space separated list of remote VPN gateways
# FREESWANVI="ipsec0"                   # Space separated list of virtual interfaces
ANYWHERE="any/0"                        # Match any IP address
NAMESERVER_1=`grep nameserver /etc/resolv.conf | cut -f2 -d" " | grep -v "^192" | head -1`      # Everyone must have at least one
NAMESERVER_2=`grep nameserver /etc/resolv.conf | cut -f2 -d" " | grep -v "^192" | tail -1`      # Your secondary name server
MY_ISP=`echo $IPADDR | cut -f 1-3 -d"."`.0/24   # ISP & NOC address range
SMTP_SERVER="mail.georgetoft.com"       # Your Mail Hub Server.
POP_SERVER="mail.georgetoft.com"        # External pop server, if any
NEWS_SERVER="news.qwest.net"            # External news server, if any
# SYSLOG_SERVER="syslog.internal.server"        # Your syslog internal server
LOOPBACK="127.0.0.0/8"                  # Reserved loopback address range
CLASS_A="10.0.0.0/8"                    # Class A private networks
CLASS_B="172.16.0.0/12"                 # Class B private networks
CLASS_C="192.168.0.0/16"                # Class C private networks
CLASS_D_MULTICAST="224.0.0.0/4"         # Class D multicast addresses
CLASS_E_RESERVED_NET="240.0.0.0/5"      # Class E reserved addresses
BROADCAST_SRC="0.0.0.0"                 # Broadcast source address
BROADCAST_DEST="255.255.255.255"        # Broadcast destination address
PRIVPORTS="0:1023"                      # Well known, privileged port range
UNPRIVPORTS="1024:65535"                # Unprivileged port range

# ----------------------------------------------------------------------------

# SSH starts at 1023 and works down to 513 for
# each additional simultaneous incoming connection.
SSH_PORTS="1022:1023" # range for SSH privileged ports

# traceroute usually uses -S 32769:65535 -D 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"

# ----------------------------------------------------------------------------
# Default policy is DENY
# Explicitly accept desired INCOMING & OUTGOING connections
# Remove all existing rules belonging to this filter
ipchains -F
# Clearing all current rules and user defined chains
ipchains -X
# Set the default policy of the filter to deny.
# Don't even bother sending an error message back.
ipchains -P input DENY
ipchains -P output DENY
ipchains -P forward DENY
# set masquerade timeout to 10 hours for tcp connections
ipchains -M -S 36000 0 0
# Don't forward fragments. Assemble before forwarding.
ipchains -A output -f -i $LOCAL_INTERFACE_1 -j DENY

# ----------------------------------------------------------------------------
# MODULES MASQUERADING
# Uncomment bellow all modules lines that you need
# These modules are necessary to masquerade their respective services.
/sbin/modprobe ip_masq_ftp
/sbin/modprobe ip_masq_raudio ports=554,7070,7071,6970,6971
/sbin/modprobe ip_masq_irc
#/sbin/modprobe ip_masq_vdolive
#/sbin/modprobe ip_masq_cuseeme
#/sbin/modprobe ip_masq_quake

# ----------------------------------------------------------------------------
# LOOPBACK
# Unlimited traffic on the loopback interface.
ipchains -A input -i $LOOPBACK_INTERFACE -j ACCEPT
ipchains -A output -i $LOOPBACK_INTERFACE -j ACCEPT

# ----------------------------------------------------------------------------
# Network Ghouls
# Deny access to jerks
# /etc/rc.d/rc.firewall.blocked contains a list of
# ipchains -A input -i $EXTERNAL_INTERFACE -s address -j DENY
# rules to block from any access.
# Refuse any connection from problem sites
#if [ -f /etc/rc.d/rc.firewall.blocked ]; then
# . /etc/rc.d/rc.firewall.blocked
#fi

# ----------------------------------------------------------------------------
# SPOOFING & BAD ADDRESSES
# Refuse spoofed packets.
# Ignore blatantly illegal source addresses.
# Protect yourself from sending to bad addresses.
# Refuse spoofed packets pretending to be from the external address.
ipchains -A input -i $EXTERNAL_INTERFACE -s $IPADDR -j DENY -l

# Refuse packets claiming to be to or from a Class A private network
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_A -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_A -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_A -j REJECT -l
ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_A -j REJECT -l

# Refuse packets claiming to be to or from a Class B private network
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_B -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_B -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_B -j REJECT -l
ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_B -j REJECT -l

# Refuse packets claiming to be to or from a Class C private network
# ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_C -j DENY -l
# ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_C -j DENY -l
# ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_C -j REJECT -l
# ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_C -j REJECT -l

# Refuse packets claiming to be from the loopback interface
ipchains -A input -i $EXTERNAL_INTERFACE -s $LOOPBACK -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $LOOPBACK -j REJECT -l

# Refuse broadcast address SOURCE packets
ipchains -A input -i $EXTERNAL_INTERFACE -s $BROADCAST_DEST -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $BROADCAST_SRC -j DENY -l

# Refuse Class D multicast addresses (in.h) (NET-3-HOWTO)
# Multicast is illegal as a source address.
# Multicast uses UDP.
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_D_MULTICAST -j DENY -l

# Refuse Class E reserved IP addresses
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_E_RESERVED_NET -j DENY -l

# refuse addresses defined as reserved by the IANA
# 0.*.*.*, 1.*.*.*, 2.*.*.*, 5.*.*.*, 7.*.*.*, 23.*.*.*, 27.*.*.*
# 31.*.*.*, 37.*.*.*, 39.*.*.*, 41.*.*.*, 42.*.*.*, 58-60.*.*.*
# 67-95.*.*.*, 96-126.*.*.*, 197.*.*.*, 201.*.*.* (?), 217-223.*.*.*
ipchains -A input -i $EXTERNAL_INTERFACE -s 1.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 2.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 5.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 7.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 23.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 27.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 31.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 37.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 39.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 41.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 42.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 58.0.0.0/7 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 60.0.0.0/8 -j DENY -l

#67: 01000001 - /3 includes 64 - need 67-79 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 67.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 68.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 69.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 70.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 71.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 72.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 73.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 74.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 75.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 76.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 77.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 78.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 79.0.0.0/8 -j DENY -l

#80: 01010000 - /4 masks 80-95
ipchains -A input -i $EXTERNAL_INTERFACE -s 80.0.0.0/4 -j DENY -l

# 96: 01100000 - /4 masks 96-111
ipchains -A input -i $EXTERNAL_INTERFACE -s 96.0.0.0/4 -j DENY -l

#126: 01111110 - /3 includes 127 - need 112-126 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 112.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 113.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 114.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 115.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 116.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 117.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 118.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 119.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 120.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 121.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 122.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 123.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 124.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 125.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 126.0.0.0/8 -j DENY -l

#217: 11011001 - /5 includes 216 - need 217-219 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 217.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 218.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 219.0.0.0/8 -j DENY -l

#223: 11011111 - /6 masks 220-223
ipchains -A input -i $EXTERNAL_INTERFACE -s 220.0.0.0/6 -j DENY -l

# ----------------------------------------------------------------------------
# ICMP
# To prevent denial of service attacks based on ICMP bombs, filter
# incoming Redirect (5) and outgoing Destination Unreachable (3).
# Note, however, disabling Destination Unreachable (3) is not
# advisable, as it is used to negotiate packet fragment size.
# For bi-directional ping.
# Message Types: Echo_Reply (0), Echo_Request (8)
# To prevent attacks, limit the src addresses to your ISP range.
#
# For outgoing traceroute.
# Message Types: INCOMING Dest_Unreachable (3), Time_Exceeded (11)
# default UDP base: 33434 to base+nhops-1
#
# For incoming traceroute.
# Message Types: OUTGOING Dest_Unreachable (3), Time_Exceeded (11)
# To block this, deny OUTGOING 3 and 11
# 0: echo-reply (pong)
# 3: destination-unreachable, port-unreachable, fragmentation-needed, etc.
# 4: source-quench
# 5: redirect
# 8: echo-request (ping)
# 11: time-exceeded
# 12: parameter-problem
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 0 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 3 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 4 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 11 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 12 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $MY_ISP 8 -d $IPADDR -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 0 -d $MY_ISP -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 3 -d $MY_ISP -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 4 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 8 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 12 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 11 -d $MY_ISP -j ACCEPT

# ----------------------------------------------------------------------------
# UDP INCOMING TRACEROUTE
# traceroute usually uses -S 32769:65535 -D 33434:33523
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $MY_ISP $TRACEROUTE_SRC_PORTS \
-d $IPADDR $TRACEROUTE_DEST_PORTS -j ACCEPT -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $ANYWHERE $TRACEROUTE_SRC_PORTS \
-d $IPADDR $TRACEROUTE_DEST_PORTS -j DENY -l

# ----------------------------------------------------------------------------
# DNS server
# ----------
# DNS: full server
# server/client to server query or response
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -s $ANYWHERE $UNPRIVPORTS -d $IPADDR 53 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp -s $IPADDR 53 -d $ANYWHERE $UNPRIVPORTS -j ACCEPT

# DNS client (53)
# ---------------
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -s $NAMESERVER_1 53 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp -s $IPADDR $UNPRIVPORTS -d $NAMESERVER_1 53 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -s $NAMESERVER_2 53 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp -s $IPADDR $UNPRIVPORTS -d $NAMESERVER_2 53 -j ACCEPT
# TCP client to server requests are allowed by the protocol
# if UDP requests fail. This is rarely seen. Usually, clients
# use TCP as a secondary nameserver for zone transfers from
# their primary nameservers, and as hackers.
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $NAMESERVER_1 53 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $NAMESERVER_1 53 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $NAMESERVER_2 53 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $NAMESERVER_2 53 -j ACCEPT


# ----------------------------------------------------------------------------
# TCP accept only on selected ports
# ---------------------------------

# ------------------------------------------------------------------
# SSH server (22)
# ---------------
#ipchains -A input -i $EXTERNAL_INTERFACE -p tcp -s $ANYWHERE $UNPRIVPORTS -d $IPADDR 22 -j ACCEPT
#ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y -s $IPADDR 22 -d $ANYWHERE $UNPRIVPORTS -j ACCEPT
#ipchains -A input -i $EXTERNAL_INTERFACE -p tcp -s $ANYWHERE $SSH_PORTS -d $IPADDR 22 -j ACCEPT
#ipchains -A input -i $EXTERNAL_INTERFACE -p tcp -s $ANYWHERE $SSH_PORTS -d $IPADDR 22 -j ACCEPT
#ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y -s $IPADDR 22 -d $ANYWHERE $SSH_PORTS -j ACCEPT

# SSH client (22)
# ---------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 22 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 22 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 22 -d $IPADDR $SSH_PORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $SSH_PORTS -d $ANYWHERE 22 -j ACCEPT

# ------------------------------------------------------------------
# HTTP client (80)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 80 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 80 -j ACCEPT

# ------------------------------------------------------------------
# HTTPS client (443)
# ------------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 443 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 443 -j ACCEPT

# ------------------------------------------------------------------
# POP client (110)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $POP_SERVER 110 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $POP_SERVER 110 -j ACCEPT
ipchains -A input -i $LOOPBACK_INTERFACE -p tcp ! -y -s $LOOPBACK 110 -d $LOOPBACK $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $LOOPBACK_INTERFACE -p tcp -s $LOOPBACK $UNPRIVPORTS -d $LOOPBACK 110 -j ACCEPT

# ------------------------------------------------------------------
# NNTP NEWS client (119)
# ----------------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $NEWS_SERVER 119 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $NEWS_SERVER 119 -j ACCEPT

# ------------------------------------------------------------------
# FINGER client (79)
# ------------------
# ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
# -s $ANYWHERE 79 \
# -d $IPADDR $UNPRIVPORTS -j ACCEPT
# ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
# -s $IPADDR $UNPRIVPORTS \
# -d $ANYWHERE 79 -j ACCEPT

# ------------------------------------------------------------------
# SYSLOG client (514)
# -----------------
# ipchains -A output -i $LOCAL_INTERFACE_1 -p udp \
# -s $IPADDR 514 \
# -d $SYSLOG_SERVER 514 -j ACCEPT

# ------------------------------------------------------------------
# AUTH server (113)
# -----------------
# Reject, rather than deny, the incoming auth port. (NET-3-HOWTO)
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp -s $ANYWHERE -d $IPADDR 113 -j REJECT
# AUTH client (113)
# -----------------
# ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
# -s $ANYWHERE 113 \
# -d $IPADDR $UNPRIVPORTS -j ACCEPT
# ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
# -s $IPADDR $UNPRIVPORTS \
# -d $ANYWHERE 113 -j ACCEPT

# ------------------------------------------------------------------
# SMTP client (25)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 25 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 25 -j ACCEPT

# ------------------------------------------------------------------
# IRC client (6667)
# -----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 6667 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 6667 -j ACCEPT

# ------------------------------------------------------------------
# ICQ client (4000)
# -----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 2000:4000 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 2000:4000 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -s $ANYWHERE 4000 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 4000 -j ACCEPT

# ------------------------------------------------------------------
# FTP client (20, 21)
# -------------------
# outgoing request
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 21 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 21 -j ACCEPT
# NORMAL mode data channel
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp -s $ANYWHERE 20 -d $IPADDR $UNPRIVPORTS -j ACCEPT
# NORMAL mode data channel responses
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 20 -j ACCEPT
# PASSIVE mode data channel creation
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# PASSIVE mode data channel responses
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE $UNPRIVPORTS -d $IPADDR $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------------
# RealAudio / QuickTime client
# ----------------------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 554 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 554 -j ACCEPT
# TCP is a more secure method: 7070:7071
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 7070:7071 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 7070:7071 -j ACCEPT
# UDP is the preferred method: 6970:6999
# For LAN machines, UDP requires the RealAudio masquerading module and
# the ipmasqadm third-party software.
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -s $ANYWHERE $UNPRIVPORTS -d $IPADDR 6970:6999 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE $UNPRIVPORTS -j ACCEPT

# ------------------------------------------------------------------
# WHOIS client (43)
# -----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y -s $ANYWHERE 43 -d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -s $IPADDR $UNPRIVPORTS -d $ANYWHERE 43 -j ACCEPT

# ------------------------------------------------------------------
# OUTGOING TRACEROUTE
# -------------------
ipchains -A output -i $EXTERNAL_INTERFACE -p udp -s $IPADDR $TRACEROUTE_SRC_PORTS -d $ANYWHERE $TRACEROUTE_DEST_PORTS -j ACCEPT

# ----------------------------------------------------------------------------
# Unlimited traffic within the local network.
# All internal machines have access to the firewall machine.
ipchains -A input -i $LOCAL_INTERFACE_1 -s $LOCALNET_1 -j ACCEPT
ipchains -A output -i $LOCAL_INTERFACE_1 -d $LOCALNET_1 -j ACCEPT

# ----------------------------------------------------------------------------
# FreeS/WAN IPSec VPN
# -------------------
# If you are using the FreeSWAN IPSec VPN, you will need to fill in the
# addresses of the gateways in the IPSECSG and the virtual interfaces for
# FreeS/Wan IPSEC in the FREESWANVI parameters. Look at the beginning of
# this firewall script rules file to set the parameters.
# IPSECSG is a Space separated list of remote gateways. FREESWANVI is a
# Space separated list of virtual interfaces for FreeS/Wan IPSEC
# implementation. Only include those that are actually used.
# Allow IPSEC protocol from remote gateways on external interface
# IPSEC uses three main types of packet:
# IKE uses the UDP protocol and port 500,
# ESP use the protocol number 50, and
# AH use the protocol number 51
# ipchains -A input -i $EXTERNAL_INTERFACE -p udp  -s $IPSECSG -j ACCEPT
# ipchains -A output -i $EXTERNAL_INTERFACE -p udp  -d $IPSECSG -j ACCEPT
# ipchains -A input -i $EXTERNAL_INTERFACE -p 50  -s $IPSECSG -j ACCEPT
# ipchains -A output -i $EXTERNAL_INTERFACE -p 504  -d $IPSECSG -j ACCEPT
# ipchains -A input -i $EXTERNAL_INTERFACE -p 51  -s $IPSECSG -j ACCEPT
# ipchains -A output -i $EXTERNAL_INTERFACE -p 51  -d $IPSECSG -j ACCEPT
# Allow all traffic to FreeS/WAN Virtual Interface
# ipchains -A input -i $FREESWANVI  -s $ANYWHERE  -d $ANYWHERE -j ACCEPT
# ipchains -A output -i $FREESWANVI  -s $ANYWHERE  -d $ANYWHERE -j ACCEPT
# Forward anything from the FreeS/WAN virtual interface IPSEC tunnel
# ipchains -A forward -i $FREESWANVI  -s $ANYWHERE  -d $ANYWHERE -j ACCEPT
# Disable IP spoofing protection to allow IPSEC to work properly
# echo 0 > /proc/sys/net/ipv4/conf/ipsec0/rp_filter
# echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter

# ----------------------------------------------------------------------------
# Masquerade internal traffic.
# All internal traffic is masqueraded externally.
ipchains -A forward -i $EXTERNAL_INTERFACE -s $LOCALNET_1 -j MASQ
# ----------------------------------------------------------------------------
# Enable logging for selected denied packets
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp -d $IPADDR -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -d $IPADDR $PRIVPORTS -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp -d $IPADDR $UNPRIVPORTS -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp -s $ANYWHERE 5 -d $IPADDR -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp -s $ANYWHERE 13:255 -d $IPADDR -j DENY -l
# ----------------------------------------------------------------------------
;;

    stop)
    echo -n "Shutting Firewalling Services: "
    # Remove all existing rules belonging to this filter
    ipchains -F
    # Delete all user-defined chain to this filter
    ipchains -X
    # Reset the default policy of the filter to accept.
    ipchains -P input ACCEPT
    ipchains -P output ACCEPT
    ipchains -P forward ACCEPT
    ;;

    status)
    status firewall
    ;;

    restart|reload)
    $0 stop
    $0 start
    ;;

    *)
    echo "Usage: firewall {start|stop|status|restart|reload}"
    exit 1

esac
exit 0

Symlinks

These symlinks exist in /etc/rc0.d, /etc/rc1.d, /etc/rc2.d, /etc/rc3.d, /etc/rc5.d, /etc/rc6.d)
S99z_hdparms -> /etc/rc.d/init.d/hdparms 
K99z_killramdisk -> ../init.d/killramdisk 

This symlink exists in /etc/cron.hourly

nameservice.cron -> /etc/init.d/nameservice