#!/bin/sh

# Iptables Firewall script.
# the skeleton start script was created by levy.pl.
# the additional flush reset section is by Oskar Andreasson. 

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

#
# This script is set for ppp dialup $EXTERNAL and ftp,ssh,www,http 
# services to the $INTERNAL lan.
#
# To use this box as a gateway for a internal lan "masquerading" and
# "ip forwarding" have to be enabled in the NAT section on line 225.  
# Internal lan machines using the gateway will require Gateway and
# DNS addresses to be entered in their network setup. Usually the DNS 
# of the ISP is given.
#
# see bottom of rc.modules for Patrick Volkerdings advice on nat and 
# initializing of special modules.


######################
####   Variables   ###
######################
# Iptables Path. 
 IPTABLES="/usr/sbin/iptables"
#
#
# External Interface - ppp0, eth0
 EXTERNAL="ppp0"
#
# Internal Interfaces - eth0,eth1,eth2.
# INTERNAL0="eth0"
# INTERNAL1="eth1"
# INTERNAL2="eth2"

# Internal Subnets
# SUBNET0="192.168.0.0/24"
# SUBNET1="192.168.1.0/24"
# SUBNET2="192.168.2.0/24"


firewall_start() {
if [ -x $IPTABLES ]; then
echo -en "\\033[1;36m" "Starting iptables firewall."  "\\033[m" "\n"

# chain policies
# set default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD DROP  # Set to DROP if you're NOT doing NAT'ing!

# flush tables
$IPTABLES -F
$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -F -t mangle
$IPTABLES -X
$IPTABLES -F -t nat

# create DUMP table
$IPTABLES -N DUMP > /dev/null
$IPTABLES -F DUMP
$IPTABLES -A DUMP -p tcp -j LOG
$IPTABLES -A DUMP -p udp -j LOG
$IPTABLES -A DUMP -p tcp -j REJECT --reject-with tcp-reset
$IPTABLES -A DUMP -p udp -j REJECT --reject-with icmp-port-unreachable
$IPTABLES -A DUMP -j DROP

# Stateful table
$IPTABLES -N STATEFUL > /dev/null
$IPTABLES -F STATEFUL
$IPTABLES -I STATEFUL -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A STATEFUL -m state --state NEW -i ! $EXTERNAL -j ACCEPT
$IPTABLES -A STATEFUL -j DUMP

# loopback rules
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

# To allow anything coming from tunnels such as vtun access
#$IPTABLES -A INPUT -i tun0 -j ACCEPT
#$IPTABLES -A OUTPUT -o tun0 -j ACCEPT
#$IPTABLES -A INPUT -i tun1 -j ACCEPT
#$IPTABLES -A OUTPUT -o tun1 -j ACCEPT


# Allow ISP Remote connection address.
# $IPTABLES -A INPUT -i $EXTERNAL -s XXX.XXX.XXX.XXX/32 -j ACCEPT

# drop reserved addresses incoming (these are reserved addresses
# but may change soon
$IPTABLES -A INPUT -i $EXTERNAL -s 0.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 1.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 2.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 5.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 7.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 10.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 23.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 27.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 31.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 36.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 39.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 41.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 42.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 58.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 59.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 60.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 127.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 169.254.0.0/16 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 172.16.0.0/12 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 192.168.0.0/16 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 192.168.251.0/24 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 197.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 224.0.0.0/8 -j DUMP
$IPTABLES -A INPUT -i $EXTERNAL -s 240.0.0.0/8 -j DUMP


# allow/disallow certain inbound ICMP types (ping, traceroute..)
# set to accept if you want to use ping/traceroute.
$IPTABLES -A INPUT -i $EXTERNAL -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPTABLES -A INPUT -i $EXTERNAL -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A INPUT -i $EXTERNAL -p icmp --icmp-type echo-reply -j ACCEPT
$IPTABLES -A INPUT -i $EXTERNAL -p icmp --icmp-type echo-request -j ACCEPT

# kill off identd quick
$IPTABLES -A INPUT -p tcp -i $EXTERNAL --dport 113 -j REJECT --reject-with tcp-reset
#
#
############
## PORTS  ##
############
#
# the following is to open ports for ftp,ssh,www,bind. 
# Uncomment, name the interface and ports as required. 
#
# ftp
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL0 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL1 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL2 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -s $SUBNET0 --dport 21 -j ACCEPT
#$IPTABLES -A INPUT -p udp -s $SUBNET0 --dport 21 -j ACCEPT

# ssh
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL0 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL1 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL2 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -s $SUBNET0 --dport 22 -j ACCEPT
#$IPTABLES -A INPUT -p udp -s $SUBNET0 --dport 22 -j ACCEPT

# www
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL0 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL1 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL2 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -s $SUBNET0 --dport 80 -j ACCEPT
#$IPTABLES -A INPUT -p udp -s $SUBNET0 --dport 80 -j ACCEPT

# https
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL0 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL1 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL2 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -s $SUBNET0 --dport 443 -j ACCEPT
#$IPTABLES -A INPUT -p udp -s $SUBNET0 --dport 443 -j ACCEPT

# vtun
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL0 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL1 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL2 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -s $SUBNET0 --dport 5000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -s $SUBNET0 --dport 5000 -j ACCEPT

# some program that runs on port 8000...
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL0 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL1 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -i $INTERNAL2 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -s $SUBNET0 --dport 8000 -j ACCEPT
#$IPTABLES -A INPUT -p udp -s $SUBNET0 --dport 8000 -j ACCEPT
#
# Example of opening up port 666 for a local subnet
#$IPTABLES -A INPUT -p tcp -i $INTERNAL0 -s 192.168.0.0/24 --dport 666 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL1 -s 192.168.1.0/24 --dport 666 -j ACCEPT
#$IPTABLES -A INPUT -p tcp -i $INTERNAL2 -s 192.168.2.0/24 --dport 666 -j ACCEPT
#
# sample rule to block all outgoing smtp traffic
#$IPTABLES -A OUTPUT -p tcp -o $EXTERNAL --dport 25 -j REJECT --reject-with tcp-reset
#
#
#############
# End Ports #
#############
#
#
# Don't log route packets coming from routers - too much logging
$IPTABLES -A INPUT -p udp -i $EXTERNAL --dport 520 -j REJECT

# Don't log smb/windows sharing packets - too much logging
$IPTABLES -A INPUT -p tcp -i $EXTERNAL --dport 137:139 -j REJECT
$IPTABLES -A INPUT -p udp -i $EXTERNAL --dport 137:139 -j REJECT

###############################
# NAT 'ip masquerade' Gateway #
###############################

# The next two examples set up 'ip masquerading' and port forwarding. 
# The following two rules aren't needed if you're not a gateway for 
# a local LAN

# Set up NAT for lan network
#$IPTABLES -t nat -A POSTROUTING -i $INTERNAL1 -o $EXTERNAL -j MASQUERADE
#$IPTABLES -t nat -A POSTROUTING -s $SUBNET1 -o $EXTERNAL -j MASQUERADE

# Port Forwarding.
# turn on IP forwarding to route packets between interfaces
#echo "1" > /proc/sys/net/ipv4/ip_forward

# drop auth packets from EXTERNAL:113 
#$IPTABLES -A INPUT --protocol udp -i $EXTERNAL --source-port 113 -j DROP

# Route incoming EXTERNAL at www port 80, to 192.168.1.1:80
#$IPTABLES -t nat -A PREROUTING  -p tcp -i $EXTERNAL --dport 80 -j DNAT --to 192.168.1.1:80

# Route incoming EXTERNAL at ftp port 21, to 192.168.1.1:21
#$IPTABLES -t nat -A PREROUTING  -p tcp -i $EXTERNAL --dport 21 -j DNAT --to 192.168.1.18:21

# example (using NAT) firewall:1234 --> SUBNET 1:[80]
#$IPTABLES -t nat -A PREROUTING -p tcp --dport 1234 -j DNAT --to $SUBNET1:80

# push everything else to state table
$IPTABLES -A INPUT -j STATEFUL


##################
#     extra      #
##################



# CRITICAL:  Enable automatic IP defragmenting since it is disabled by default 
# in 2.2.x kernels. This used to be a compile-time option but the behavior was
# changed in 2.2.12
#
#echo "1" > /proc/sys/net/ipv4/ip_always_defrag


# Dynamic IP users:
#
#   If you get your IP address dynamically from SLIP, PPP, or DHCP, enable this following
#   option.  This enables dynamic-ip address hacking in IP MASQ, making the life 
#   with Diald and similar programs much easier.
#
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr


# Specify your Static IP address here.
# Enable the LooseUDP patch which some Internet-based games require
#
#  If you are trying to get an Internet game to work through your IP MASQ box,
#  and you have set it up to the best of your ability without it working, try
#  enabling this option (delete the "#" character).  This option is disabled
#  by default due to possible INTERNAL0 machine UDP port scanning
#  vunerabilities.
#
#echo "1" > /proc/sys/net/ipv4/ip_masq_udp_dloose


# Send out syncookies when the syn backlog queue of a socket 
# overflows. This is to prevent against the common 'syn flood attack'

#echo "1" >/proc/sys/net/ipv4/tcp_syncookies

#end firewall_start function
 fi
}



#firewall_flush function by Oskar Andreasson. 

firewall_flush() {
echo -en "flushing iptables." "\n"

# reset the default policies in the filter table.
#
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT

#
# reset the default policies in the nat table.
#
$IPTABLES -t nat -P PREROUTING ACCEPT
$IPTABLES -t nat -P POSTROUTING ACCEPT
$IPTABLES -t nat -P OUTPUT ACCEPT

#
# reset the default policies in the mangle table.
#
$IPTABLES -t mangle -P PREROUTING ACCEPT
$IPTABLES -t mangle -P OUTPUT ACCEPT

#
# flush all the rules in the filter and nat tables.
#
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
#
# erase all chains that's not default in filter and nat table.
#
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X


# end firewall_flush function.
}


# restart function.
firewall_restart(){
firewall_flush
sleep 1
firewall_start
}

# list function.
firewall_list() {
$IPTABLES -L
}


case "$1" in
'start')
firewall_start
;;
'flush')
firewall_flush
;;
'restart')
firewall_restart
;;
'list')
firewall_list
;;
*)
  echo -en "usage $0 start|flush|restart|list" "\n"
esac

