#!/bin/sh

# Command Paths
iptables='/sbin/iptables'
modprobe='/sbin/modprobe'

# NetFilter Modules
# some of these are unnecessary but i'm not sure which :/ -- pabs
MODULES="ip_nat ip_nat_ftp ip_nat_irc                                      \
         ipt_MARK ipt_TOS ipt_limit ipt_ttl ipt_tos ipt_filter ipt_unclean \
         iptable_nat iptable_filter iptable_unclean"



# Upstream Network Settings
UPSTREAM=63.80.4.17		# Upstream router for default route
UPETH=eth0			# Interface for upstream
UPIP=63.80.4.21		# IP addy on upstream network
INTNET=192.168.3.0/24		# Internal network

# Internal Network Settings (this doesn't currently do jack mama for me)
INTETH=eth1			# Internal interface
INTIP=192.168.3.1		# IP addy on internal network

# CIPE Network Settings
TUNETH=cipcb0       # interface
TUNIP=192.168.2.2   # IP

# Ports allowed on the firewall - MAX OF 15!!
# If you go over 15, the rule will fail and nothing will be open. :)
GWTCPPORTS=22,25,80,110,113,143,27960
GWUDPPORTS=27960

# Ports allowed outbound from the firewall - MAX OF 15!!
# If you go over 15, the rule will fail and nothing will be allowed out. :)
# GWOUT rules temporarily disabled -- pabs
GWOUT=20,21,22,25,80,110,113,143 

# -----------------------------------------------------
# Run necessary modprobes
# -----------------------------------------------------
$modprobe `echo $MODULES`

# -----------------------------------------------------
# Clean up netfilter
$iptables -v -F 
$iptables -v -F -t nat
$iptables -v -F -t mangle
$iptables -v -F -t filter

$iptables -P INPUT DROP
# modified to allow anything outbound (pabs)
$iptables -P OUTPUT ACCEPT
$iptables -P FORWARD DROP

$iptables -L -n | grep '^Chain' | grep -v INPUT | grep -v FORWARD | grep -v OUTPUT |
while [ 1 ]; do
  if [ -z "$line" ]; then break; fi
  CHAIN=`echo $line | cut -f2 -d' '`
  $iptables -X $CHAIN
done

# -----------------------------------------------------
# Set up netfilter chains

# ------------------------------------------
# Log and drop chain
echo Creating Log and Drop Chain
$iptables -X LDROP
$iptables -N LDROP
$iptables -A LDROP --proto tcp -j LOG --log-level info --log-prefix "TCP Drop " -m limit --limit 5/second
$iptables -A LDROP --proto udp -j LOG --log-level info --log-prefix "UDP Drop " -m limit --limit 5/second
$iptables -A LDROP --proto icmp -j LOG --log-level info --log-prefix "icmp Drop " -m limit --limit 5/second
$iptables -A LDROP --proto gre -j LOG --log-level info --log-prefix "GRE Drop " -m limit --limit 5/second
$iptables -A LDROP -f -j LOG --log-level emerg --log-prefix "FRAG Drop " -m limit --limit 5/second
$iptables -A LDROP -j DROP

# ------------------------------------------
# Monitor chain
$iptables -X WATCH
$iptables -N WATCH
$iptables -A WATCH -j LOG --log-level warn --log-prefix "ACCEPT "
$iptables -A WATCH -j ACCEPT

# ------------------------------------------
# ICMP Chain
echo Creating ICMP Chain
$iptables -X ICMP
$iptables -N ICMP
$iptables -A ICMP -p icmp --icmp-type echo-reply                   -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type destination-unreachable      -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type   network-unreachable        -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type   host-unreachable           -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type   protocol-unreachable       -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type   port-unreachable           -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type   fragmentation-needed       -j LDROP 
$iptables -A ICMP -p icmp --icmp-type   source-route-failed        -j WATCH 
$iptables -A ICMP -p icmp --icmp-type   network-unknown            -j WATCH
$iptables -A ICMP -p icmp --icmp-type   host-unknown               -j WATCH
$iptables -A ICMP -p icmp --icmp-type   network-prohibited         -j WATCH 
$iptables -A ICMP -p icmp --icmp-type   host-prohibited            -j WATCH
$iptables -A ICMP -p icmp --icmp-type   TOS-network-unreachable    -j WATCH
$iptables -A ICMP -p icmp --icmp-type   TOS-host-unreachable       -j WATCH
$iptables -A ICMP -p icmp --icmp-type   communication-prohibited   -j WATCH 
$iptables -A ICMP -p icmp --icmp-type   host-precedence-violation  -j LDROP   
$iptables -A ICMP -p icmp --icmp-type   precedence-cutoff          -j LDROP   
$iptables -A ICMP -p icmp --icmp-type source-quench                -j LDROP   
$iptables -A ICMP -p icmp --icmp-type redirect                     -j LDROP   
$iptables -A ICMP -p icmp --icmp-type   network-redirect           -j LDROP   
$iptables -A ICMP -p icmp --icmp-type   host-redirect              -j LDROP   
$iptables -A ICMP -p icmp --icmp-type   TOS-network-redirect       -j LDROP   
$iptables -A ICMP -p icmp --icmp-type   TOS-host-redirect          -j LDROP   
$iptables -A ICMP -p icmp --icmp-type echo-request                 -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type router-advertisement         -j LDROP   
$iptables -A ICMP -p icmp --icmp-type router-solicitation          -j LDROP   
$iptables -A ICMP -p icmp --icmp-type time-exceeded                -j ACCEPT
$iptables -A ICMP -p icmp --icmp-type   ttl-zero-during-transit    -j ACCEPT 
$iptables -A ICMP -p icmp --icmp-type   ttl-zero-during-reassembly -j ACCEPT 
$iptables -A ICMP -p icmp --icmp-type parameter-problem            -j WATCH 
$iptables -A ICMP -p icmp --icmp-type   ip-header-bad              -j WATCH 
$iptables -A ICMP -p icmp --icmp-type   required-option-missing    -j WATCH 
$iptables -A ICMP -p icmp --icmp-type timestamp-request            -j LDROP   
$iptables -A ICMP -p icmp --icmp-type timestamp-reply              -j LDROP   
$iptables -A ICMP -p icmp --icmp-type address-mask-request         -j LDROP   
$iptables -A ICMP -p icmp --icmp-type address-mask-reply           -j LDROP   
$iptables -A ICMP -p icmp -j LDROP   

# ------------------------------------------
# Check for untrusted networks and LDROP them
echo Creating Untrusted Networks Chain
$iptables -X untrusted_check
$iptables -N untrusted_check
$iptables -A untrusted_check -i $UPETH -s 10.0.0.0/8 -j LDROP # we do not route unrouteable junk
$iptables -A untrusted_check -i $UPETH -s 172.16.0.0/12 -j LDROP # we do not route unrouteable junk

$iptables -A untrusted_check -i $UPETH -s 192.168.0.0/16 -j LDROP # we do not route unrouteable junk
$iptables -A untrusted_check -s 127.0.0.0/8 -i lo -j ACCEPT # Localhost can talk to itself
$iptables -A untrusted_check -s 127.0.0.0/8 -o lo -j ACCEPT # Localhost can talk to itself
$iptables -A untrusted_check -s 127.0.0.0/8 -j LDROP # we do not route unrouteable junk

$iptables -A untrusted_check -s $INTNET -i $UPETH -j LDROP # Ignore my own coming off incorrect interfaces

# ------------------------------------------
# Local rules
# gw ------------------

# Local in table
echo Creating local_in Chain
$iptables -X local_in
$iptables -N local_in

# This opens ssh and ident inbound to the firewall box
$iptables -A local_in --match multiport -p tcp --dport $GWTCPPORTS -j ACCEPT
$iptables -A local_in --match multiport -p udp --dport $GWUDPPORTS -j ACCEPT

$iptables -A local_in -p udp --dport 33434:33523 -j ACCEPT # For traceroute

# Allow localhost traffic
$iptables -A local_in -i lo -s $UPIP/32 -j ACCEPT
$iptables -A local_in -i lo -s $INTIP/32 -j ACCEPT

# Allow all CIPE tunnel traffic
$iptables -A INPUT -i $TUNETH -s $TUNIP/32 -j ACCEPT
$iptables -A INPUT -i $TUNETH -s $TUNIP/32 -j ACCEPT

# Local out table
echo Creating local_out Chain
$iptables -X local_out
$iptables -N local_out

$iptables -A local_out --match multiport -p tcp --dport $GWOUT -j ACCEPT
# Allow outbound DNS requests
$iptables -A local_out --match multiport -p udp --dport 53 -j ACCEPT

$iptables -A local_out -p udp --dport 33434:33523 -j ACCEPT # traceroute

# Allow localhost traffic
$iptables -A local_out -o lo -d 127.0.0.1/32 -j ACCEPT
$iptables -A local_out -o lo -d $UPIP/32 -j ACCEPT
$iptables -A local_out -o lo -d $INTIP/32 -j ACCEPT
$iptables -A local_out -o lo -d $TUNIP/32 -j ACCEPT

# catch-alls
# $iptables -A local_in -j LDROP
# we want to allow all outbound right now -- pabs
$iptables -A local_out -j ACCEPT

# ------------------------------------------
# forwarding rules
$iptables -X outbound
$iptables -N outbound

# Allow internal machines out
$iptables -A outbound -s $INTNET -i $INTETH -j ACCEPT

# catch alls
$iptables -A outbound -j LDROP

# -----------------------------------------------------
# Set up netfilter rules

# masq everything going out the cable modem and the ppp interface
$iptables -t nat -A POSTROUTING -o $UPETH -j SNAT --to $UPIP

# -------------------------------------------------------
# Start
# Check for invalid folks

# Check ICMP
echo Adding ICMP Checks
$iptables -A INPUT -p icmp -j ICMP
$iptables -A FORWARD -p icmp -j ICMP
$iptables -A OUTPUT -p icmp -j ICMP

# Generic accept everything that has already been set up
echo Allowing Existing Connections
$iptables -A INPUT --match state --state ESTABLISHED,RELATED --jump ACCEPT
$iptables -A FORWARD --match state --state ESTABLISHED,RELATED --jump ACCEPT
$iptables -A OUTPUT --match state --state ESTABLISHED,RELATED --jump ACCEPT

# Pass everything through the untrusted_check
echo Setting up untrusted_check
$iptables -A INPUT -j untrusted_check
$iptables -A FORWARD -j untrusted_check
$iptables -A OUTPUT -j untrusted_check

# Jump to our inbound table
$iptables -A INPUT --jump local_in

# Outbound connections
$iptables -A FORWARD -i $INTETH -s $INTNET --jump outbound

# Jump to the local out table
$iptables -A OUTPUT --jump local_out

# catch alls
echo "Setting up 'Catch Alls'"
$iptables -A INPUT -j LDROP
$iptables -A FORWARD -j LDROP
$iptables -A OUTPUT -j LDROP

# -----------------------------------------------------
# Start forwarding
echo Starting Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward


