Firewall Features of the Linux 2.2 Kernel
by Steven Pritchard, Linux Users of Central Illinois

Compile kernel.

Say Y or M as appropriate to all of the following:

Networking support (CONFIG_NET) [Y/n/?]
Network firewalls (CONFIG_FIREWALL) [Y/n/?]
TCP/IP networking (CONFIG_INET) [Y/n/?]
IP: firewalling (CONFIG_IP_FIREWALL) [Y/n/?]
IP: always defragment (required for masquerading) (CONFIG_IP_ALWAYS_DEFRAG) [Y/n/?]
IP: transparent proxy support (CONFIG_IP_TRANSPARENT_PROXY) [Y/n/?]
IP: masquerading (CONFIG_IP_MASQUERADE) [Y/n/?]
IP: masquerading special modules support (CONFIG_IP_MASQUERADE_MOD) [Y/n/?]
IP: ipportfw masq support (EXPERIMENTAL) (CONFIG_IP_MASQUERADE_IPPORTFW) [M/n/y/?]

You'll want to turn on most other firewalling/masquerading options as well. Obviously you'll also need to turn on the appropriate drivers for PPP and/or SLIP, ethernet devices, etc.

Boot new kernel.

Install new tools.

ipchains - http://www.rustcorp.com/linux/ipchains/
ipmasqadm - http://juanjox.linuxhq.com/

Set up networking.

Turn on IP forwarding.

Either

echo 1 > /proc/sys/net/ipv4/ip_forward
or on Red Hat (or similar systems), set FORWARD_IPV4=yes in /etc/sysconfig/network (or check the appropriate box in netcfg).

Set up firewalling rules.


#!/bin/sh
#
# firewall     This shell script takes care of starting and stopping
#              IP masquerading and firewalling.
#

# Run the old 2.0 script if we're running a 2.0 kernel.

if [ `uname -r | cut -d. -f1-2` = "2.0" ]; then
    exec /etc/rc.d/init.d/firewall-2.0 $*
fi

# Fill in with your Internet-accessible address.
INET_ADDR=

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

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

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

# See how we were called.
case "$1" in
  start)
        echo -n "Starting firewall: "

        # Load ip_masq modules.
        for module in /lib/modules/`uname -r`/ipv4/ip_masq_*.o

        do
            modprobe `echo ${module} | cut -d/ -f6`

        done

        # Set up firewalling rules.
        ipchains -P input ACCEPT
        ipchains -P output ACCEPT
        ipchains -P forward REJECT

        # Block reserved addresses on the appropriate interfaces.

        # I originally had these set to REJECT, but that doesn't

        # make sense since the traffic is by definition invalid.

        ipchains -I input  -p all -s 192.168.0.0/16 -i ppp0 -j DENY
        ipchains -I output -p all -s 192.168.0.0/16 -i ppp0 -j DENY
        ipchains -I input  -p all -s 172.16.0.0/12  -i ppp0 -j DENY
        ipchains -I output -p all -s 172.16.0.0/12  -i ppp0 -j DENY
        ipchains -I input  -p all -s 10.0.0.0/8     -i ppp0 -j DENY
        ipchains -I output -p all -s 10.0.0.0/8     -i ppp0 -j DENY
        ipchains -I input  -p all -s 127.0.0.0/8    -i ppp0 -j DENY
        ipchains -I output -p all -s 127.0.0.0/8    -i ppp0 -j DENY

        ipchains -I input  -p all -s 127.0.0.0/8    -i eth0 -j DENY
        ipchains -I output -p all -s 127.0.0.0/8    -i eth0 -j DENY

        ipchains -I input  -p all -s 127.0.0.0/8    -i eth1 -j DENY
        ipchains -I output -p all -s 127.0.0.0/8    -i eth1 -j DENY

        # Forward anything on eth0 -> eth1 and vice-versa.

        ipchains -A forward -p all -s 192.168.0.0/24 -d 192.168.1.0/24 -i eth1 \
                 -j ACCEPT
        ipchains -A forward -p all -s 192.168.1.0/24 -d 192.168.0.0/24 -i eth0 \
                 -j ACCEPT

        # Don't allow connections from eth1 -> eth0.

        ipchains -A input -p tcp -s 192.168.1.0/24 -d 192.168.0.0/24 -i eth1 \
                 -y -j REJECT
        ipchains -A input -p udp -s 192.168.1.0/24 -d 192.168.0.0/24 -i eth1 \
                 -j REJECT

        # MASQ everything in 192.168.0.0 (from the ethernet interfaces).
        ipchains -A forward -p all -s 192.168.0.0/16 -d 0.0.0.0/0 -i ppp0 \
                 -j MASQ

        # Forward useful ports appropriately.

        # Make sure $INET_ADDR is filled in with your ppp0 address above.
        # domain -> server:domain
        ipmasqadm portfw -a -P udp -L $INET_ADDR 53 -R 192.168.1.1 53
        ipmasqadm portfw -a -P tcp -L $INET_ADDR 53 -R 192.168.1.1 53
        # http -> server:http
        ipmasqadm portfw -a -P tcp -L $INET_ADDR 80 -R 192.168.1.1 80

        touch /var/lock/subsys/firewall

        echo
        ;;
  stop)
        echo -n "Shutting down firewall: "

        # Flush portfw rules.
        ipmasqadm portfw -f

        # Flush firewalling rules & accept everything.

        ipchains -F input
        ipchains -F output
        ipchains -F forward
        ipchains -P input ACCEPT
        ipchains -P output ACCEPT
        ipchains -P forward ACCEPT

        # Unload modules
        for module in `cat /proc/modules | grep '^ip_masq' | cut -d' ' -f1`
        do
            rmmod ${module}
        done

        echo "done"
        rm -f /var/lock/subsys/firewall

        ;;
  restart)
        $0 stop
        $0 start
        ;;
  *)
        echo "Usage: firewall {start|stop}"

        exit 1
esac

exit 0