#!/bin/sh
#iptable rule script

#Test whether we have a network
if [ ! -f /etc/sysconfig/network ] ; then
	exit 0
fi
#Code follows InternalRules and ExternalRules Functions
InternalRules () {

echo "Internal Interface Processing $i"
echo 'General Rule Set'
#iptables -A general-rule-set -i ! $INTERNAL_IF -m limit -j LOG --log-prefix "Bd pckt frm int ntwrk" --log-level 7
iptables -A general-rule-set -i $INTERNAL_IF -j ACCEPT

#echo 'Specific Rule Set'

#echo 'Forwarding Rules'

}

ExternalRules () {
echo "External Interface Processing $i"
echo 'General Rule Set'

iptables -A general-rule-set -i $EXTERNAL_IF -s 64.122.50.50 -j ACCEPT

iptables -A general-rule-set -m state --state NEW -i ! $EXTERNAL_IF -j ACCEPT
#iptables -A general-rule-set -i $EXTERNAL_IF -f -j LOG --log-prefix "Pckt fragments from extnwrk" --log-level 7
iptables -A general-rule-set -i $EXTERNAL_IF -f -j DROP
#iptables -A general-rule-set -i $EXTERNAL_IF -m limit -j LOG --log-prefix "Bd pckt frm extntwrk" --log-level 7

#Deny Private Class A, B, C, D Multicast, E Reserverd Net from ext internet
iptables -A general-rule-set -i $EXTERNAL_IF -s 10.0.0.0/8 -j DROP
iptables -A general-rule-set -i $EXTERNAL_IF -s 172.16.0.0/12 -j DROP
iptables -A general-rule-set -i $EXTERNAL_IF -s 192.168.0.0/16 -j DROP
iptables -A general-rule-set -i $EXTERNAL_IF -s 224.0.0.0/4 -j DROP
iptables -A general-rule-set -i $EXTERNAL_IF -s 240.0.0.0/5 -j DROP
#Refusing packets destined to the loopback interface protects against
#source quench, whereby a machine can be told to slow itself down by an
#icmp source quench to the loopback
iptables -A general-rule-set -i $EXTERNAL_IF -d 127.0.0.0/8 -j DROP
#Refuse broadcast address packets
iptables -A general-rule-set -i $EXTERNAL_IF -d $EXTERNAL_BCAST -j DROP

#Refuse new connections when they are exessive
iptables -A general-rule-set -i $EXTERNAL_IF -p tcp --destination-port ! 42:53 -m state --state NEW -m recent --set --name MANYTRIES
iptables -A general-rule-set -i $EXTERNAL_IF -p tcp  --destination-port ! 42:53 -m state --state NEW -m recent --rcheck --seconds 120 --hitcount 20 --rttl --name MANYTRIES -m limit --limit 5/h --limit-burst 5 -j LOG --log-prefix '>20NewCons/120s' --log-level 6
iptables -A general-rule-set -i $EXTERNAL_IF -p tcp  --destination-port ! 42:53 -m state --state NEW -m recent --update --seconds 120 --hitcount 20 --rttl --name MANYTRIES -j DROP


echo 'Specific Rule Set'

#AUTH Server Reject ident probes with a tcp reset. Some mail-servers
#won't accept mail if an ident probe is dropped instead of rejected
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport 113 -j REJECT --reject-with tcp-reset
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport smtp -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport smtp -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport ssh -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport ssh -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport www -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport www -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport imap -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport imap -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport pop3 -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport pop3 -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport imaps -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport imaps -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport pop3s -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport pop3s -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport smtps -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport domain -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport domain -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport nameserver -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport nameserver -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport ftp -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport ftp -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport ftp-data -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport ftp-data -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p tcp --dport 1024: -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --dport 1024: -j ACCEPT
#Next two rules are redundany since I opened up ports 1024+ for ftp anyway
#Next 3 rules for pptp server on this machine
#iptables -A specific-rule-set -i $EXTERNAL_IF -p TCP --dport 1723 -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p UDP --dport 1723 -j ACCEPT
#iptables -A specific-rule-set -i $EXTERNAL_IF -p 47  -j ACCEPT
#
#Rules for allowing ipsec IKE negotiations & ESP encryption+authorization & AH packet-level authorization
iptables -A specific-rule-set -i $EXTERNAL_IF -p udp --sport 500 --dport 500 -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p 50 -j ACCEPT
iptables -A specific-rule-set -i $EXTERNAL_IF -p 51 -j ACCEPT
iptables -I FORWARD -s 192.168.254.0/24 -j ACCEPT
iptables -I INPUT -s 192.168.254.0/24 -j ACCEPT
iptables -I FORWARD -s 192.168.1.0/24 -j ACCEPT
iptables -I INPUT -s 192.168.1.0/24 -j ACCEPT


#
#echo 'Syn-flood protection' #Already done above in Non-specific Interface section
#iptables -A INPUT -p tcp -d $EXTERNAL_IP --syn -m limit --limit 1/s -j general-rule-set
#echo 'Furtive port scanner' #Already done above in Non-specific Interface section
#iptables -A INPUT -p tcp -d $EXTERNAL_IP --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j general-rule-set

#echo 'Syn-flood protection' #Already done above in Non-specific Interface section
#iptables -A INPUT -p tcp -d $EXTERNAL_IP --syn -m limit --limit 1/s -j specific-rule-set
#echo 'Furtive port scanner' #Already done above in Non-specific Interface section
#iptables -A INPUT -p tcp -d $EXTERNAL_IP --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j specific-rule-set

echo 'Forwarding rules'
echo 'Forwarding and Masqing'
iptables -t nat -A POSTROUTING -o $EXTERNAL_IF -d ! 192.168.0.0/16 -j MASQUERADE

}

#Code starts here main()

echo 'Setting firewall rules'
#Following is not needed for iptables. Was for ipchains
#echo 'Load Masqing modules'
#for i in $(/bin/ls -1 /lib/modules/$(/bin/uname -r)/kernel/net/ipv4/netfilter/*) ; \
#do
#echo loading module $i
#/sbin/insmod $i
#done

echo 'Load Network Address Translation Modules'
/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp

echo 'Setting up firewall rules'

#Old manual settings for internal and external IP information
#		EXTERNAL_IP="24.106.59.179"
#		EXTERNAL_MASK="24.106.59.176/28"
#		EXTERNAL_BCAST="24.106.59.191"
#		INTERNAL_IP="192.168.2.113"
#		INTERNAL_MASK="192.168.2.0/24"
#		INTERNAL_BCAST="192.168.2.255"
#	INTERNAL_IF="eth0"
#	EXTERNAL_IF="eth1"

#Example of how to do port redirects
#PORT_SMTP_EXTERNAL="25"
#PORT_SMTP_INTERNAL="25"
#SERVICE_SMTP_EXTERNAL=24.106.59.179
#SERVICE_SMTP_INTERNAL=192.168.0.1

# find all the interfaces besides loopback.
# ignore aliases, alternative configurations, and editor backup files
CurDir=`pwd`
cd /etc/sysconfig/network-scripts
interfaces=`ls ifcfg* | LANG=C egrep -v '(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)' |\
            LANG=C egrep -v '(~|\.bak)$' | \
            LANG=C egrep 'ifcfg-[A-Za-z0-9_-]+$' | \
            sed 's/^ifcfg-//g'`


echo 'Flushing old rules, deleting chains, and clearing counters'


iptables --flush
iptables -t nat --flush
iptables -X 
iptables -Z

echo 'Disable response to broadcasts. Prevent smuft amplifier abuse'
echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

echo 'Dont accept source routed packets. Prevents traffic pretending to come from'
echo 'inside but which is routed to outside'
for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 > $f; done

echo 'Dont accept ICMP redirects. These can be used to alter the routing tables'
for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 > $f; done

echo 'Enable bad error message protection'
echo 1 >/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

echo 'Enable Port Forwarding'
echo 1 > /proc/sys/net/ipv4/ip_forward

#Turn on reverse path filtering. Prevents packets that come in on one NIC
#from leaving on another NIC. This helps prevent ip-spoofing. This will
#cause problems with asymmetrical routing (by definition) or if you
#are a non-routing host, having several IP addresses on different NICs.
#for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done

#Log spoofed packets, source routed packets, redirect packets
#for f in /proc/sys/net/ipv4/conf/*/log_martians; do echo 1 > $f; done
#Don't log spoofed packets since not going to do anything about it
#and it clutters up the screen with messages
echo 'Disable logging of spoofed packets (Packets from wrong network)'
for f in /proc/sys/net/ipv4/conf/*/log_martians; do echo 0 > $f; done



echo 'Set policies'

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

#Don't block loopback interface
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

echo 'Defined chains'
iptables -N general-rule-set
iptables -N specific-rule-set
iptables -N syn-flood 
iptables -N port-scan 

echo 'Interface Non-specific rules'
iptables -A general-rule-set -m state --state ESTABLISHED,RELATED -j ACCEPT
#Syn-flood protection. RETURN returns control to previous rule chain
iptables -A syn-flood -p tcp --syn -m limit --limit 1/s --limit-burst 4 -j RETURN
iptables -A syn-flood -j DROP
#Furtive port scanner
iptables -A port-scan -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j RETURN
iptables -A port-scan -j DROP
#attach timeouts above to rule-set
iptables -A specific-rule-set -p tcp --syn -j syn-flood
iptables -A specific-rule-set -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j port-scan


for i in $interfaces; do
	IP_ADDR=""
	IP_MASK=""
	IP_BCAST=""
	eval $(fgrep "DEVICE"= ifcfg-$i)
	if [ -z "$DEVICE" ] ; then DEVICE="$i"; fi
	echo "Processing file ifcfg-$i"
	IP_ADDR=`/sbin/ifconfig $i| awk -v RS=' ' -F : '/addr/ {print $2}'`
	IP_ADDR=`echo $IP_ADDR|awk '{print $1}'`
	if [ -z "$IP_ADDR" ] ; then #If no active address then get from ifcfg
	  eval $(fgrep "IPADDR"= ifcfg-$i)
	  if [ -n "$IPADDR" ] ; then
		echo "Interface $i down. getting ip $IPADDR from file"
		IP_ADDR=$IPADDR
	  fi
	  eval $(fgrep "NETMASK"= ifcfg-$i)
	  if [ -n "$NETMASK" ] ; then
		echo "Getting Netmask $NETMASK from file"
		IP_MASK=$NETMASK
	  fi
	  eval $(fgrep "BROADCAST"= ifcfg-$i)
	  if [ -n "$BROADCAST" ] ; then
		echo "Getting Broadcast ip $BROADCAST from file"
		IP_BCAST=$BROADCAST
	  fi
	else
	  IP_MASK=`/sbin/ifconfig $i | awk -v RS=' ' -F : '/Mask/ {print $2}'` 
       	  #if [ -z "$IP_MASK" ] ; then continue; fi #if no address, skip
	  IP_BCAST=`/sbin/ifconfig $i | awk -v RS=' ' -F : '/Bcast/ {print $2}'` 
	fi
	if [ -n "`echo ' '$IP_ADDR|grep ' 10.'`" \
		-o -n "`echo ' '$IP_ADDR|grep ' 172.16.'`" \
		-o -n "`echo ' '$IP_ADDR|grep ' 192.168.'`" \
		-o -n "`echo ' '$IP_ADDR|grep ' 224.'`" \
		-o -n "`echo ' '$IP_ADDR|grep ' 240.'`" ] ; then
		INTERNAL_IF=$i
		INTERNAL_IP=$IP_ADDR
		INTERNAL_MASK=$IP_MASK
		INTERNAL_BCAST=$IP_BCAST
		InternalRules
	else
		EXTERNAL_IF=$i
		EXTERNAL_IP=$IP_ADDR
		EXTERNAL_MASK=$IP_MASK
		EXTERNAL_BCAST=$IP_BCAST
		ExternalRules
	fi 

done
echo "Internal IF:   "$INTERNAL_IF
echo "Internal IP:   "$INTERNAL_IP
echo "Internal Mask: "$INTERNAL_MASK
echo "Internal BCast:"$INTERNAL_BCAST
echo "External IF:   "$EXTERNAL_IF
echo "External IP:   "$EXTERNAL_IP
echo "External Mask: "$EXTERNAL_MASK
echo "External BCast:"$EXTERNAL_BCAST


echo 'Finished Port Rule Sets'
echo 'Attach Rule Sets to INPUT Chain'
iptables -A INPUT -j general-rule-set
iptables -A INPUT -j specific-rule-set

echo 'Attach Rule sets to FORWARD Chain'
#iptables -I FORWARD -p tcp -d ! mailserver.syben.com --dport smtp -j DROP
#iptables -I FORWARD -p tcp -d ! mailserver.syben.com --dport rsmtp -j DROP
#iptables -I FORWARD -p udp -d ! mailserver.syben.com --dport smtp -j DROP
#iptables -I FORWARD -p udp -d ! mailserver.syben.com --dport rsmtp -j DROP
#iptables -I FORWARD -p tcp --dport lmtp -j DROP
#iptables -I FORWARD -p udp --dport lmtp -j DROP
#iptables -I FORWARD -p tcp --dport nntp -j DROP
#iptables -I FORWARD -p udp --dport nntp -j DROP

iptables -A FORWARD -j general-rule-set
iptables -A FORWARD -j specific-rule-set
#I didn't bother to control output
#iptables -A OUTPUT -j general-rule-set
#iptables -A OUTPUT -j specific-rule-set

#echo 'Redirect external port to internal service'
#iptables -t nat -A PREROUTING -p tcp -d $SERVICE_SMTP_EXTERNAL --dport $PORT_SMTP_EXTERNAL \
#-j DNAT  --to $SERVICE_SMTP_INTERNAL_:$PORT_SMTP_INTERNAL 
#Note: $INTERNAL_IP will be set to the last internal address processed in FOR loop.
#iptables -t nat -A POSTROUTING -p tcp -d $SERVICE_SMTP_INTERNAL -j SNAT --to $INTERNAL_IP 


cd $CurDir
exit 0
