#! /bin/bash

# Iptables script written by Ken Gypen (Glider)
# It is based upon some great tutorials found in various places
# and of course the original iptables howto
#
#  http://www.netfilter.org/documentation/index.html#documentation-faq
#  http://gentoo-wiki.com/HOWTO_Iptables_for_newbies
#  http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables

#####################################
# General settings & Configurations #
#####################################

# Determine interfaces
EXTIF="eth0"
INTIF="eth1"
# Loop device/localhost
LPDIF="lo"
LPDIP="127.0.0.1"
LPDMSK="255.0.0.0"
LPDNET="$LPDIP/$LPDMSK"

# Internal servers IP (static)
SERVERNAME=10.0.1.200

# Text tools paths
IFC="/sbin/ifconfig"
G="/bin/grep"
SED="/bin/sed"
AWK="/usr/bin/awk"
ECHO="/bin/echo"
export LC_ALL="en"

# Setting up external interface environment variables
EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
EXTBC="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"
EXTMSK="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"
EXTNET="$EXTIP/$EXTMSK"

# Setting up internal interface environment variables
INTIP="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
INTBC="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"
INTMSK="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"
INTNET="$INTIP/$INTMSK"

# Load Kernel modules
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ip_nat

# Enable forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Enable NAT translation (MASQUERADE)
iptables -t nat -A POSTROUTING -o $EXTIF -j  MASQUERADE

############
# FIREWALL #
############
# Tighten timeouts etc
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl

# Flush all existing chains
CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`
for i in $CHAINS
do
	iptables -t $i -F
	iptables -t $i -Z
	iptables -t $i -X
done

# set default policy
#iptables -P INPUT DROP
#iptables -P OUTPUT DROP
#iptables -P FORWARD DROP

# Enable Anti DDOS & Block NEW without SYN
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
iptables -A INPUT -i $EXTIF -p tcp ! --syn -m state --state NEW -j DROP

# allow known connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Anti-spoofing rule
iptables -A INPUT -i $EXTIF -s $EXTIP -j DROP 
iptables -A INPUT -i $EXTIF -s 127.0.0.0/8 -j DROP 

# Block fragments and Xmas tree as well as SYN,FIN and SYN,RST
iptables -A INPUT -i $EXTIF -p ip -f  -j DROP 
iptables -A INPUT -i $EXTIF -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP 
iptables -A INPUT -i $EXTIF -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP 
iptables -A INPUT -i $EXTIF -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

#allow icmp
iptables -A INPUT -s $INTNET -p icmp -j ACCEPT

# Fix loopback settings
iptables -A INPUT -i lo -j ACCEPT

# Allow outgoing traffic from the firewall
iptables -A OUTPUT -m state --state NEW -j ACCEPT

# User initiated and related traffic 
iptables -A FORWARD  -m state --state RELATED,ESTABLISHED -j ACCEPT

# Internet access from subnets
iptables -A FORWARD -s $INTNET -m state --state NEW -j ACCEPT

####################################
# Open up ports for local services #
####################################
iptables -A INPUT -d $INTIP -p tcp --destination-port 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -d $INTIP -p tcp --destination-port 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -d $INTIP -p tcp --destination-port 67 -m state --state NEW -j ACCEPT
#iptables -A INPUT -d $INTIP -p tcp --destination-port 647,847 -m state --state NEW -j ACCEPT
iptables -A INPUT -d $EXTIP -p tcp --destination-port 22 -m state --state NEW -j ACCEPT

###################
# Port forwarding #
###################
function port_forward {
        iptables -A FORWARD --dst $4 -p tcp --dport $3 -j ACCEPT
        iptables -t nat -A PREROUTING --dst $2 -p tcp -i $1 --dport $3 -j DNAT --to-destination $4:$5
        iptables -t nat -A OUTPUT --dst $2 -p tcp --dport $3 -j DNAT --to-destination $4:$5
}

# USAGE:
#               |-----Info-----|------------------External--------------------|-------Internal-------|
# port_forward  <service>       <interface>             <IP>            <port> <IP>             <port>
# EXAMPLE:
# port_forward  Samba           $EXTINT     		$EXTIP		445    $SERVERNAME     	445
port_forward  	SSH	        $EXTINT     		$EXTIP		2222   $SERVERNAME      22

