#-----------( Firestarter 1.0.3, Netfilter kernel subsystem in use )----------#
#                                                                             #
# This firewall was generated by Firestarter on 2008-09-03 14:34              #
# http://www.fs-security.com                                                  #
#                                                                             #
#-----------------------------------------------------------------------------#


# --------( Initial Setup - Firewall Modules Autoloader )--------

# Remove ipchains module if found
$LSM | grep ipchains -q -s && $RMM ipchains

# Try to load every module we need
$MPB ip_tables 2> /dev/null
$MPB iptable_filter 2> /dev/null
$MPB ipt_state 2> /dev/null
$MPB ip_conntrack 2> /dev/null
$MPB ip_conntrack_ftp 2> /dev/null
$MPB ip_conntrack_irc 2> /dev/null
$MPB ipt_REJECT 2> /dev/null
$MPB ipt_TOS 2> /dev/null
$MPB ipt_MASQUERADE 2> /dev/null
$MPB ipt_LOG 2> /dev/null
$MPB iptable_mangle 2> /dev/null
$MPB ipt_ipv4optsstrip 2> /dev/null
if [ "$NAT" = "on" ]; then
	$MPB iptable_nat 2> /dev/null
	$MPB ip_nat_ftp 2> /dev/null
	$MPB ip_nat_irc 2> /dev/null
fi
if [ "EXT_PPP" = "on" ]; then
	$MPB bsd_comp 2> /dev/null
	$MPB ppp_deflate 2> /dev/null
fi


# --------( Initial Setup - Firewall Capabilities Check )--------

# Make sure the test chains does not exist
$IPT -F test 2> /dev/null
$IPT -X test 2> /dev/null
if [ "$NAT" = "on" ]; then
	$IPT -t nat -F test 2> /dev/null
	$IPT -t nat -X test 2> /dev/null
fi

# Iptables support check, mandatory feature
if [ "`$IPT -N test 2>&1`" ]; then
	echo Fatal error: Your kernel does not support iptables.
	return 100
fi

# Logging support check
log_supported=1
if [ "`$IPT -A test -j LOG 2>&1`" ]; then
	echo Warning: Logging not supported by kernel, you will recieve no firewall event updates.
	log_supported=""
fi

if [ "$NAT" = "on" ]; then
	# NAT support check
	nat_supported=1
	if [ "`$IPT -t nat -N test 2>&1`" ]; then
		echo Warning: Network address translation not supported by kernel, feature disabled.
		nat_supported=""
	fi
fi

# Mangle support check
mangle_supported=1
if [ "`$IPT -t mangle -F 2>&1`" ]; then
	echo Warning: Packet mangling not supported by kernel, feature disabled.
	mangle_supported=""
fi

# IP options stripping support check
stripoptions_supported=1
if [ "`$IPT -t mangle -A test -j IPV4OPTSSTRIP 2>&1`" ]; then
  stripoptions_supported=""
fi


# --------( Chain Configuration - Flush Existing Chains )--------

# Purge standard chains (INPUT, OUTPUT, FORWARD).

$IPT -F
$IPT -X
$IPT -Z

# Purge extended chains (MANGLE & NAT) if they exist.

if [ "$mangle_supported" ]; then
  $IPT -t mangle -F
  $IPT -t mangle -X
  $IPT -t mangle -Z
fi
if [ "$nat_supported" ]; then
  $IPT -t nat -F
  $IPT -t nat -X
  $IPT -t nat -Z
fi


# --------( Chain Configuration - Configure Default Policy )--------

# Configure standard chains (INPUT, OUTPUT, FORWARD).

$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

# Configure extended chains (MANGLE & NAT) if required.

if [ "$mangle_supported" ]; then
  $IPT -t mangle -P INPUT ACCEPT
  $IPT -t mangle -P OUTPUT ACCEPT
  $IPT -t mangle -P PREROUTING ACCEPT
  $IPT -t mangle -P POSTROUTING ACCEPT
fi
if [ "$nat_supported" ]; then
  $IPT -t nat -P OUTPUT ACCEPT
  $IPT -t nat -P PREROUTING ACCEPT
  $IPT -t nat -P POSTROUTING ACCEPT
fi


# --------( Chain Configuration - Create Default Result Chains )--------

# Create a new chain for filtering the input before logging is performed
$IPT -N LOG_FILTER 2> /dev/null
$IPT -F LOG_FILTER

# Hosts for which logging is disabled
while read host garbage
	do
		$IPT -A LOG_FILTER -s $host -j $STOP_TARGET
	done < /etc/firestarter/events-filter-hosts

# Ports for which logging is disabled
while read port garbage
	do
		$IPT -A LOG_FILTER -p tcp --dport $port -j $STOP_TARGET
		$IPT -A LOG_FILTER -p udp --dport $port -j $STOP_TARGET
	done < /etc/firestarter/events-filter-ports

# Create a new log and stop input (LSI) chain.
$IPT -N LSI 2> /dev/null
$IPT -F LSI
$IPT -A LSI -j LOG_FILTER
if [ "$log_supported" ]; then
	# Syn-flood protection
	$IPT -A LSI -p tcp --syn -m limit --limit 1/s -j LOG --log-level=$LOG_LEVEL --log-prefix "Inbound "
	$IPT -A LSI -p tcp --syn -j $STOP_TARGET
	# Rapid portscan protection
	$IPT -A LSI -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j LOG --log-level=$LOG_LEVEL --log-prefix "Inbound "
	$IPT -A LSI -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j $STOP_TARGET
	# Ping of death protection
	$IPT -A LSI -p icmp --icmp-type echo-request -m limit --limit 1/s -j LOG --log-level=$LOG_LEVEL --log-prefix "Inbound "
	$IPT -A LSI -p icmp --icmp-type echo-request -j $STOP_TARGET
	# Log everything
	$IPT -A LSI -m limit --limit 5/s -j LOG --log-level=$LOG_LEVEL --log-prefix "Inbound "
fi
$IPT -A LSI -j $STOP_TARGET # Terminate evaluation

# Create a new log and stop output (LSO) chain.
$IPT -N LSO 2> /dev/null
$IPT -F LSO
$IPT -A LSO -j LOG_FILTER
if [ "$log_supported" ]; then
	# Log everything
	$IPT -A LSO -m limit --limit 5/s -j LOG --log-level=$LOG_LEVEL --log-prefix "Outbound "
fi
$IPT -A LSO -j REJECT # Terminate evaluation


# --------( Initial Setup - Nameservers )--------

# Allow regular DNS traffic
while read keyword server garbage
	do
		if [ "$keyword" = "nameserver" ]; then
			$IPT -A INPUT -p tcp ! --syn -s $server -d 0/0 -j ACCEPT
			$IPT -A INPUT -p udp -s $server -d 0/0 -j ACCEPT
			$IPT -A OUTPUT -p tcp -s $IP -d $server --dport 53 -j ACCEPT
			$IPT -A OUTPUT -p udp -s $IP -d $server --dport 53 -j ACCEPT
		fi
	done < /etc/resolv.conf


# --------( Initial Setup - Configure Kernel Parameters )--------

source /etc/firestarter/sysctl-tuning


# --------( Intial Setup - User Defined Pre Script )--------

source /etc/firestarter/user-pre


# --------( Rules Configuration - Specific Rule - Loopback Interfaces )--------

# Allow all traffic on the loopback interface
$IPT -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT
$IPT -A OUTPUT -o lo -s 0/0 -d 0/0 -j ACCEPT


# --------( Rules Configuration - Type of Service (ToS) - Ruleset Filtered by GUI )--------

if [ "$FILTER_TOS" = "on" ]; then
	if [ "$TOS_CLIENT" = "on" -a $mangle_supported ]; then
		# ToS: Client Applications
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 20:21 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 22 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 68 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 80 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 443 --set-tos $TOSOPT
	fi
	if [ "$TOS_SERVER" = "on" -a $mangle_supported ]; then
		# ToS: Server Applications
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 20:21 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 22 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 25 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 53 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 67 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 80 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 110 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 143 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 443 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 1812 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 1813 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 2401 --set-tos $TOSOPT
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 8080 --set-tos $TOSOPT
	fi
	if [ "$TOS_SERVER" = "on" -a $mangle_supported ]; then
		# ToS: The X Window System
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 22 --set-tos 0x10
		$IPT -t mangle -A OUTPUT -p tcp -j TOS --dport 6000:6015 --set-tos 0x08
	fi
fi


# --------( Rules Configuration - ICMP )--------

if [ "$FILTER_ICMP" = "on" ]; then
	if [ "$ICMP_ECHO_REQUEST" = "on" ]; then
		# ICMP: Ping Requests
		$IPT -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
	fi
	if [ "$ICMP_ECHO_REPLY" = "on" ]; then
		# ICMP: Ping Replies
		$IPT -A INPUT -p icmp --icmp-type echo-reply -m limit --limit 1/s -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type echo-reply -m limit --limit 1/s -j ACCEPT
	fi
	if [ "$ICMP_TRACEROUTE" = "on" ]; then
		# ICMP: Traceroute Requests
		$IPT -A INPUT -p udp --dport 33434 -j ACCEPT
		$IPT -A FORWARD -p udp --dport 33434 -j ACCEPT
	else
		$IPT -A INPUT -p udp --dport 33434 -j LSI
		$IPT -A FORWARD -p udp --dport 33434 -j LSI
	fi
	if [ "$ICMP_MSTRACEROUTE" = "on" ]; then
		# ICMP: MS Traceroute Requests
		$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type destination-unreachable -j ACCEPT
	fi
	if [ "$ICMP_UNREACHABLE" = "on" ]; then
		# ICMP: Unreachable Requests
		$IPT -A INPUT -p icmp --icmp-type host-unreachable -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type host-unreachable -j ACCEPT
	fi
	if [ "$ICMP_TIMESTAMPING" = "on" ]; then
		# ICMP: Timestamping Requests
		$IPT -A INPUT -p icmp --icmp-type timestamp-request -j ACCEPT
		$IPT -A INPUT -p icmp --icmp-type timestamp-reply -j ACCEPT
	fi
	if [ "$ICMP_MASKING" = "on" ]; then
		# ICMP: Address Masking
		$IPT -A INPUT -p icmp --icmp-type address-mask-request -j ACCEPT
		$IPT -A INPUT -p icmp --icmp-type address-mask-reply -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type address-mask-request -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type address-mask-reply -j ACCEPT
	fi
	if [ "$ICMP_REDIRECTION" = "on" ]; then
		# ICMP: Redirection Requests
		$IPT -A INPUT -p icmp --icmp-type redirect -m limit --limit 2/s -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type redirect -m limit --limit 2/s -j ACCEPT
	fi
	if [ "$ICMP_SOURCE_QUENCHES" = "on" ]; then
		# ICMP: Source Quench Requests
		$IPT -A INPUT -p icmp --icmp-type source-quench -m limit --limit 2/s -j ACCEPT
		$IPT -A FORWARD -p icmp --icmp-type source-quench -m limit --limit 2/s -j ACCEPT
	fi

	# Catch ICMP traffic not allowed above
	$IPT -A INPUT -p icmp -j LSI
	$IPT -A FORWARD -p icmp -j LSI
else
	# Allow all ICMP traffic when filtering disabled
	$IPT -A INPUT -p icmp -m limit --limit 10/s -j ACCEPT
	$IPT -A FORWARD -p icmp -m limit --limit 10/s -j ACCEPT
fi

if [ "$NAT" = "on" ]; then
	# --------( Rules Configuration - Masquerading - Sysctl Modifications )--------

	#Turn on IP forwarding
	if [ -e /proc/sys/net/ipv4/ip_forward ]; then
		echo 1 > /proc/sys/net/ipv4/ip_forward
	fi

	# --------( Rules Configuration - Masquerading - Default Ruleset )--------

	#TCPMSS Fix - Needed for *many* broken PPPO{A/E} clients
	$IPT -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

	if [ "$stripoptions_supported" -a "$mangle_supported" ]; then
		#IPv4OPTIONS Fix - Strip IP options from a forwarded packet
		$IPT -t mangle -A PREROUTING -j IPV4OPTSSTRIP
	fi

	# --------( Rules Configuration - Forwarded Traffic )--------

	if [ "$nat_supported" ]; then
		#Masquerade outgoing traffic
		$IPT -t nat -A POSTROUTING -o $IF -j MASQUERADE
	fi

	# Temoporarily set the field separator for CSV format
	OLDIFS=$IFS
	IFS=','

	# Services forward from the firewall to the internal network
	while read service ext_port host int_port garbage
		do
			scrub_parameters
			$IPT -A FORWARD -i $IF -p tcp -d $host --dport $int_port -j ACCEPT
			$IPT -A FORWARD -i $IF -p udp -d $host --dport $int_port -j ACCEPT
			$IPT -A PREROUTING -t nat -i $IF -p tcp --dport $ext_port -j DNAT --to-destination $host:$int_port_dashed
			$IPT -A PREROUTING -t nat -i $IF -p udp --dport $ext_port -j DNAT --to-destination $host:$int_port_dashed
		done < /etc/firestarter/inbound/forward

	IFS=$OLDIFS

fi


# --------( Rules Configuration - Inbound Traffic )--------

if [ "$BLOCK_NON_ROUTABLES" = "on" ]; then
	# Block traffic from non-routable address space on the public interfaces
	$IPT -N NR 2> /dev/null
	$IPT -F NR
	while read block garbage
		do
			$IPT -A NR -s $block -d $NET -i $IF -j LSI
		done < /etc/firestarter/non-routables
	$IPT -A INPUT -s ! $NET -i $IF -j NR
fi

# Block Broadcast Traffic
if [ "$BLOCK_EXTERNAL_BROADCAST" = "on" ]; then
	$IPT -A INPUT -i $IF -d 255.255.255.255 -j DROP
	if [ "$BCAST" != "" ]; then
		$IPT -A INPUT -d $BCAST -j DROP
	fi
fi

if [ "$NAT" = "on" -a "$BLOCK_INTERNAL_BROADCAST" = "on" ]; then
	$IPT -A INPUT -i $INIF -d 255.255.255.255 -j DROP
	if [ "$INBCAST" != "" ]; then
		$IPT -A INPUT -i $INIF -d $INBCAST -j DROP
	fi
fi

# Block Multicast Traffic
#  Some cable/DSL providers require their clients to accept multicast transmissions
#  you should remove the following four rules if you are affected by multicasting
$IPT -A INPUT -s 224.0.0.0/8 -d 0/0 -j DROP
$IPT -A INPUT -s 0/0 -d 224.0.0.0/8 -j DROP
$IPT -A OUTPUT -s 224.0.0.0/8 -d 0/0 -j DROP
$IPT -A OUTPUT -s 0/0 -d 224.0.0.0/8 -j DROP

# Block Traffic with Stuffed Routing
#  Early versions of PUMP - (the DHCP client application included in RH / Mandrake) require
#  inbound packets to be accepted from a source address of 255.255.255.255.  If you have issues
#  with DHCP clients on your local LAN - either update PUMP, or remove the first rule below)
$IPT -A INPUT -s 255.255.255.255 -j DROP
$IPT -A INPUT -d 0.0.0.0 -j DROP
$IPT -A OUTPUT -s 255.255.255.255 -j DROP
$IPT -A OUTPUT -d 0.0.0.0 -j DROP

$IPT -A INPUT -m state --state INVALID -j DROP # Block Traffic with Invalid Flags
$IPT -A INPUT -f -m limit --limit 10/minute -j LSI # Block Traffic w/ Excessive Fragmented Packets

# --------( Rules Configuration - Outbound Traffic )--------

$IPT -A OUTPUT -m state --state INVALID -j DROP # Block Traffic w/ Invalid Flags


# --------( Traffic Policy )--------

# Load the inbound traffic policy
source /etc/firestarter/inbound/setup
$IPT -A INPUT -i $IF -j INBOUND # Check Internet to firewall traffic
if [ "$NAT" = "on" ]; then
	$IPT -A INPUT -i $INIF -d $INIP -j INBOUND # Check LAN to firewall (private ip) traffic
	$IPT -A INPUT -i $INIF -d $IP -j INBOUND   # Check LAN to firewall (public ip) traffic
	if [ "$INBCAST" != "" ]; then
		$IPT -A INPUT -i $INIF -d $INBCAST -j INBOUND # Check LAN to firewall broadcast traffic
	fi
fi

# Load the outbound traffic policy
source /etc/firestarter/outbound/setup
$IPT -A OUTPUT -o $IF -j OUTBOUND # Check firewall to Internet traffic
if [ "$NAT" = "on" ]; then
	$IPT -A OUTPUT -o $INIF -j OUTBOUND  # Check firewall to LAN traffic
	$IPT -A FORWARD -i $INIF -j OUTBOUND # Check LAN to Internet traffic

	# Allow Internet to LAN response traffic
	$IPT -A FORWARD -p tcp -d $INNET -m state --state ESTABLISHED,RELATED -j ACCEPT
	$IPT -A FORWARD -p udp -d $INNET -m state --state ESTABLISHED,RELATED -j ACCEPT
fi

# --------( User Defined Post Script )--------

source /etc/firestarter/user-post


# --------( Unsupported Traffic Catch-All )--------

$IPT -A INPUT -j LOG_FILTER
$IPT -A INPUT -j LOG --log-level=$LOG_LEVEL --log-prefix "Unknown Input"
$IPT -A OUTPUT -j LOG_FILTER
$IPT -A OUTPUT -j LOG --log-level=$LOG_LEVEL --log-prefix "Unknown Output"
$IPT -A FORWARD -j LOG_FILTER
$IPT -A FORWARD -j LOG --log-level=$LOG_LEVEL --log-prefix "Unknown Forward"

return 0
