SECURITY-rc.firewall.hunley

From: Douglas J. Hunley

I know that the question of security keeps coming up on this list (especially firewalls) so I've been snagging a couple minutes of 'free-time' here and there to hack together this firewall script. This is a cleaned up version of the code I run at home.  I thought I'd post it here for perusal as it is fairly well-commented.

Enjoy!

NOTES:
1. I allow DHCP (since that's how I get my IP), FTP, SSH, SMTP, DNS (I run a caching DNS server), HTTP, and IDENT
2. I have two(2) NICs in my box. One external Internet, one internal LAN (192.168.x.x)
3. I run portsentry which writes the IP address of any machine that attempts to scan/attack me to /etc/hosts.deny. So there is code in this firewall to restore the blocked hosts..
 

#!/bin/sh

# Shamelessly stolen code from PMFirewall, TrinityOS, and various
# other documents/articles on the Net

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

IPCHAINS=/sbin/ipchains
OUTERIF=eth0
REMOTENET=0/0
OUTERIP=`ifconfig $OUTERIF | grep inet | cut -d : -f 2 | cut -d \ -f 1`
OUTERMASK=`ifconfig $OUTERIF | grep Mas | cut -d : -f 4`
OUTERNET=$OUTERIP/$OUTERMASK
INTERNALIF=eth1
INTERNALIP=`ifconfig $INTERNALIF | grep inet | cut -d : -f 2 | cut -d \ -f 1`
INTERNALMASK=`ifconfig $INTERNALIF | grep Mas | cut -d : -f 4`
INTERNALNET=$INTERNALIP/$INTERNALMASK

case "$1" in

#####START FIREWALL#####
start)
echo "Starting firewall:"
## Flush rule sets, start from scratch
echo -e "\tFlushing INPUT ruleset"
$IPCHAINS -F input
echo -e "\tFlushing OUTPUT ruleset"
$IPCHAINS -F output
echo -e "\tFlushing FORWARD ruleset"
$IPCHAINS -F forward

## firewall rules
echo -e "\tStarting DEFAULT ruleset"
## Allow loopback interface
echo -e "\t\tAllowing inbound/outbound lo (loopback) connections"
$IPCHAINS -A input -i lo -s 0/0 -d 0/0 -j ACCEPT
$IPCHAINS -A output -i lo -s 0/0 -d 0/0 -j ACCEPT

# Allow packets with ack bit set, they are from an established connection.
echo -e "\t\tAllowing incoming w/ ACK set (established connections)"
$IPCHAINS -A input ! -y -p tcp -s $REMOTENET -d $OUTERNET -j ACCEPT

# Turn on Source Address Verification

if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
then
echo -e "\t\tDisabling IP Spoofing"
for f in /proc/sys/net/ipv4/conf/*/rp_filter
do
echo 1 > $f
done
fi

# Turn on SYN COOKIES PROTECTION (Thanks Holger!)
if [ -e /proc/sys/net/ipv4/tcp_syncookies ]
then
echo -e "\t\tEnabling TCP SYN Cookie protection"
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
fi

# Turn on ICMP sanity checks
# Disable ICMP broadcast echo
if [ -e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts ]
then
echo -e "\t\tDisabling replies to ICMP echo broadcasts"
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
fi

# Enable bad error message protection
if [ -e /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses ]
then
echo -e "\t\tEnable 'bad error message' protection"
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
fi

# Disable ICMP Redirects
if [ -e /proc/sys/net/ipv4/conf/all/accept_redirects ]
then
echo -e "\t\tDisabling ICMP redirects"
for i in /proc/sys/net/ipv4/conf/*/accept_redirects
do
echo 0 > $i
done
fi

# Disable source-routed packets
if [ -e /proc/sys/net/ipv4/conf/all/accept_source_route ]
then
echo -e "\t\tDisabling source-routed packets"
for i in /proc/sys/net/ipv4/conf/*/accept_source_route
do
echo 0 > $i
done
fi

# Log spoofed, source-routed, or redirected packets
if [ -e /proc/sys/net/ipv4/conf/all/log_martians ]
then
echo -e "\t\tTurning on logging of 'Martian' packets"
for i in /proc/sys/net/ipv4/conf/*/log_martians
do
echo 1 > $i
done
fi

# Reject ICMP REDIRECT packets to prevent OS fingerprinting
echo -e "\t\tRejecting ICMP REDIRECT packets"
$IPCHAINS -A input -j REJECT -i $OUTERIF -p icmp -s $REMOTENET -d $OUTERIP --icmp-type redirect -l
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type redirect

# Reject ICMP Address Mask packets to prevent OS fingerprinting
echo -e "\t\tReject ICMP Address Mask packets"
$IPCHAINS -A input -j REJECT -i $OUTERIF -p icmp -s $REMOTENET -d $OUTERIP --icmp-type address-mask-request -l
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type address-mask-request -l
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type address-mask-reply -l

# Do not reply to ICMP TTL-EXPIRED packets
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type ttl-zero-during-reassembly -l

# Do not reply to ICMP PARAMETER-PROBLEM packets
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type parameter-problem -l

# Do not reply to ICMP TIMESTAMP packets to prevent OS fingerprinting
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type timestamp-request -l
$IPCHAINS -A output -j REJECT -i $OUTERIF -p icmp -s $OUTERIP -d $REMOTENET --icmp-type timestamp-reply -l

echo -e "\tStarting LOCAL ruleset"
# Block Nonroutable IP's from entering on the External Interface
echo -e "\t\tBlocking incoming packets from non-routable IP's"
echo -e "\t\t\t10.0.0.0/8"
$IPCHAINS -A input -j REJECT -s 10.0.0.0/8 -d $OUTERNET -i $OUTERIF
echo -e "\t\t\t127.0.0.0/8"
$IPCHAINS -A input -j REJECT -s 127.0.0.0/8 -d $OUTERNET -i $OUTERIF
echo -e "\t\t\t172.16.0.0/12"
$IPCHAINS -A input -j REJECT -s 172.16.0.0/12 -d $OUTERNET -i $OUTERIF
echo -e "\t\t\t192.168.0.0/16"
$IPCHAINS -A input -j REJECT -s 192.168.0.0/16 -d $OUTERNET -i $OUTERIF
 

# - Specific port blocks on the external interface -
# This section blocks off ports/services to the outside that have
# vulnerabilities. This will not affect the ability to use these services
# within your network.
#

# Back Orifice (logged)
echo -e "\t\tBlocking inbound Back Orifice packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 31337 -j REJECT -l
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 31337 -j REJECT -l

# NetBus (logged)
echo -e "\t\tBlocking inbound NetBus packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 12345:12346 -j REJECT -l
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 12345:12346 -j REJECT -l

# Trin00 (logged)
echo -e "\t\tBlocking inbound Trin00 packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 1524 -j REJECT -l
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 27665 -j REJECT -l
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 27444 -j REJECT -l
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 31335 -j REJECT -l

# Multicast
echo -e "\t\tBlocking inbound/outbound Multicast (MBONE) packets"
$IPCHAINS -A input -s 224.0.0.0/8 -d $REMOTENET -j REJECT
$IPCHAINS -A input -s $REMOTENET -d 224.0.0.0/8 -j REJECT

### ALLOWED NETWORKS
# Add in any rules to specifically allow connections from hosts/nets that
# would otherwise be blocked.
#$IPCHAINS -A input -s [trusted host/net] -d $OUTERNET <ports> -j ACCEPT

### BLOCKED NETWORKS
# Add in any rules to specifically block connections from hosts/nets that
# have been known to cause problems. These packets are logged.
#$IPCHAINS -A input -s [banned host/net] -d $OUTERNET <ports> -j REJECT -l

### BLOCK ICMP ATTACKS
#
#$IPCHAINS -A input -b -i $OUTERIF -p icmp -s [host/net] -d $OUTERNET -j REJECT -l

#DHCP CLIENT ALLOW
echo -e "\t\tAllow DHCP client requests"
$IPCHAINS -A input -p udp -s $REMOTENET -d $REMOTENET 67:68 -i $OUTERIF -j ACCEPT
$IPCHAINS -A input -p udp -s $INTERNALNET -d $INTERNALNET 67:68 -i $INTERNALIF -j ACCEPT
#FTP
echo -e "\t\tAllow inbound FTP packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 20 -j ACCEPT
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 21 -j ACCEPT
#SSH
echo -e "\t\tAllow inbound SSH packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 22 -j ACCEPT
#SMTP
echo -e "\t\tAllow inbound SMTP packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 25 -j ACCEPT
#DNS
echo -e "\t\tAllow inbound DNS packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 53 -j ACCEPT
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 53 -j ACCEPT
#HTTPD
echo -e "\t\tAllow inbound HTTP requests"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 80 -j ACCEPT
#IDENTD
echo -e "\t\tAllow inbound IDENT packets (a small hole, but needed)"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 113 -j ACCEPT
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 113 -j ACCEPT
#NETBIOS
echo -e "\t\tReject inbound NetBIOS packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $REMOTENET 135:139 -i $OUTERIF -j REJECT
$IPCHAINS -A input -p udp -s $REMOTENET -d $REMOTENET 135:139 -i $OUTERIF -j REJECT
$IPCHAINS -A input -p tcp -s $REMOTENET -d $REMOTENET 445 -i $OUTERIF -j REJECT
$IPCHAINS -A input -p udp -s $REMOTENET -d $REMOTENET 445 -i $OUTERIF -j REJECT
#RIP
echo -e "\t\tReject inbound RIP packets"
$IPCHAINS -A input -p udp -s $REMOTENET -d $REMOTENET 520 -i $OUTERIF -j REJECT
#NFS
echo -e "\t\tReject inbound NFS packets"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $REMOTENET 2049 -i $OUTERIF -j REJECT -l
$IPCHAINS -A input -p udp -s $REMOTENET -d $REMOTENET 2049 -i $OUTERIF -j REJECT -l
#XSERVER
echo -e "\t\tReject inbound connections to XFree86 ports"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $REMOTENET 5999:6003 -i $OUTERIF -j REJECT
$IPCHAINS -A input -p udp -s $REMOTENET -d $REMOTENET 5999:6003 -i $OUTERIF -j REJECT

## Masq Rules
echo -e "\tStarting MASQ ruleset"

## Modules to help certain services

echo -e "\t\tLoading MASQ modules"
/sbin/depmod -a >/dev/null 2>&1
echo -e "\t\t\tFTP"
/sbin/modprobe ip_masq_ftp >/dev/null 2>&1
echo -e "\t\t\tReal Audio"
/sbin/modprobe ip_masq_raudio >/dev/null 2>&1
echo -e "\t\t\tIRC"
/sbin/modprobe ip_masq_irc >/dev/null 2>&1
echo -e "\t\t\tICQ"
/sbin/modprobe ip_masq_icq >/dev/null 2>&1
echo -e "\t\t\tQuake"
/sbin/modprobe ip_masq_quake >/dev/null 2>&1
echo -e "\t\t\tUSER"
/sbin/modprobe ip_masq_user >/dev/null 2>&1
echo -e "\t\t\tVDOLive"
/sbin/modprobe ip_masq_vdolive >/dev/null 2>&1

## Masquerading firewall timeouts: tcp conns 8hrs, tcp after fin pkt 60s, udp 10min
echo -e "\t\tSetting MASQ timeout"
echo -e "\t\t\tTCP connections = 8 hours"
echo -e "\t\t\tTCP after FIN = 60 seconds"
echo -e "\t\t\tUDP connections = 10 minutes"
$IPCHAINS -M -S 14400 60 600

## Set up kernel to enable IP masquerading
echo -e "\t\tEnabling IP Masquerading"
echo 1 > /proc/sys/net/ipv4/ip_forward

## Set up kernel to handle dynamic IP masquerading
echo -e "\t\tConfiguring kernel for dynamic IP MASQ"
echo 1 > /proc/sys/net/ipv4/ip_dynaddr

## Don't Masquerade internal-internal traffic
echo -e "\t\tAllowing internal-internal MASQ traffic"
$IPCHAINS -A forward -s $INTERNALNET -d $INTERNALNET -j ACCEPT

## Don't Masquerade external interface direct
echo -e "\t\tTurning off MASQ for direct outbound packets"
$IPCHAINS -A forward -s $OUTERNET -d $REMOTENET -j ACCEPT

## Masquerade all internal IP's going outside
echo -e "\t\tMASQ all packets destined for eth1"
$IPCHAINS -A forward -s $INTERNALNET -d $REMOTENET -j MASQ

## Set Default rule on MASQ chain to Deny
echo -e "\t\tSetting default MASQ ruleset to REJECT"
$IPCHAINS -P forward REJECT

## Allow all connections from the network to the outside
echo -e "\t\tAllowing all internal connections to the outside"
$IPCHAINS -A input -s $INTERNALNET -d $REMOTENET -j ACCEPT
$IPCHAINS -A output -s $INTERNALNET -d $REMOTENET -j ACCEPT

# This section manipulates the Type Of Service (TOS) bits of the
# packet. For this to work, you must have CONFIG_IP_ROUTE_TOS enabled
# in your kernel

# Set telnet, www, smtp, pop3 and FTP for minimum delay
echo -e "\t\tSetting default TOS bits"
echo -e "\t\t\tWWW, SMTP, POP3, FTP = minimum delay"
$IPCHAINS -A output -p tcp -d 0/0 80 -t 0x01 0x10
$IPCHAINS -A output -p tcp -d 0/0 22 -t 0x01 0x10
$IPCHAINS -A output -p tcp -d 0/0 23 -t 0x01 0x10
$IPCHAINS -A output -p tcp -d 0/0 21 -t 0x01 0x10
$IPCHAINS -A output -p tcp -d 0/0 110 -t 0x01 0x10
$IPCHAINS -A output -p tcp -d 0/0 25 -t 0x01 0x10

# Set ftp-data for maximum throughput
echo -e "\t\t\tFTP-Data = maximum throughput"
$IPCHAINS -A output -p tcp -d 0/0 20 -t 0x01 0x08

# Allow outgoing ICMP
echo -e "\t\tAllow outbound ICMP"
$IPCHAINS -A output -p icmp -s $INTERNALNET -d $REMOTENET -j ACCEPT
 

# Allow incoming and outgoing ICMP
echo -e "\tAllowing ICMP traffic inbound/outbound"
$IPCHAINS -A input -p icmp -s $REMOTENET -d $OUTERNET -j ACCEPT
$IPCHAINS -A output -p icmp -s $OUTERNET -d $REMOTENET -j ACCEPT

# These are open to sockets created by connections allowed by ipchains
echo -e "\tAllowing inbound unpriviledged port connects"
$IPCHAINS -A input -p tcp -s $REMOTENET -d $OUTERNET 1023:65535 -j ACCEPT
$IPCHAINS -A input -p udp -s $REMOTENET -d $OUTERNET 1023:65535 -j ACCEPT

## Set default policy
echo -e "\tSetting default outbound policy to ACCEPT"
$IPCHAINS -A output -j ACCEPT
echo -e "\tSetting default inbound policy to REJECT"
$IPCHAINS -A input -j REJECT -l
echo -e "\tBlocking previously blocked hosts"
for ip in `grep '^ALL:' /etc/hosts.deny | cut -d: -f2 | cut -c2-`
do
$IPCHAINS -I input -s $ip -j REJECT -l
done
echo
echo -e "\tInternal: $INTERNALIF $INTERNALNET"
echo -e "\tExternal: $OUTERIF $OUTERNET"
echo
;;

#####STOP FIREWALL####
stop)
echo -n "Shutting down firewall:"
$IPCHAINS -F input
$IPCHAINS -F output
$IPCHAINS -F forward
$IPCHAINS -P forward DENY
echo -e "\033[71G done" ;;

restart)
$0 stop
$0 start
;;

*)

echo ""
echo " USAGE: firewall [command] "
echo ""
echo " COMMANDS:"
echo " start Enables Firewall and Masquerading (if installed)."
echo " stop Disables Firewall and Masquerading (if installed)."
echo " restart Flushes and reloads the rules in firewall."
echo " help Displays this list of options."
echo ""
exit 1 ;;

esac
exit 0

searchSearch Index