#!/bin/bash

# ID: rc.tables-3 Tue Mar  6 23:39:04 EST 2007 ground/X

# Second generation masq firewall.
# written fresh for iptables
# Now uses stateful connection tracking.

# Some configuration variables.
lan_iface='eth0' # local interface
wan_iface='eth1' #Internet interface
private_pool='192.168.0.0/16' # private network space you are using
# networks for which we serve as gateway. must be inside private_pool.
# You may specify one ip/masq or multiple networks seperated by a space.
masq_nets='192.168.1.0/24 192.168.34.0/24'
log_forwards='1' # log when we accept connect through firewall
log_dropped_external='1' # log dropped external connections from the internet.
bin='/usr/local/sbin/iptables' # iptables binary
#bin='./ipt_debug' # uncomment for testing only.
 
# Generic functions used later in the script.
function port_fwd {
# Used to forward a port to an internal machine.
# Usage proto external_port internal_ip optional_internal_port 
# optional_limit_masq
# If internal port is omitted it defaults to the same as external port.
local fwd_dport
local forward_cmdline="$bin -t nat -A PREROUTING -i  $wan_iface -p $1 \
-d 0.0.0.0/0 --dport $2"
if [ "$5" = '' ]
then
forward_cmdline="$forward_cmdline -s ! $private_pool"
 else
forward_cmdline="$forward_cmdline -s $5"
fi
if [ "$4" = '' ]
then
forward_cmdline="$forward_cmdline -j DNAT --to $3"
else
forward_cmdline="$forward_cmdline -j DNAT --to $3:$4"
fi
$forward_cmdline

if [ "$4" = '' ]
then
fwd_dport="$2"
else
fwd_dport="$4"
fi
if [ "$1" = 'tcp' -a \
"$log_forwards" = '1' ]
then
$bin -A FORWARD -p $1 -i $wan_iface -o $lan_iface -s ! $private_pool \
-d $3/32 --dport $fwd_dport --syn -j LOG \
--log-prefix accept_fwd_$2_ -m limit --limit 3m
fi
$bin -A FORWARD -p $1 -i $wan_iface -o $lan_iface -s ! $private_pool \
-d $3/32 --dport $fwd_dport -j ACCEPT
return 0
}
# End function.
function block_smtp {
# Usage ip/masq
# blocks a range of addresses from the smtp server.
$bin -A FORWARD -p tcp -i $wan_iface -s $1 --dport 25 -j LOG \
--log-prefix drop_smtp_hunt_ -m limit --limit 3m
$bin -A FORWARD -p tcp -i $wan_iface -s $1 --dport 25 -j DROP
return 0
}
# End function.
function blacklist {
# completely blacklists a network by ip masq
# Usage: ip/masq optional_quiet_flag_q
if [ "$2" != 'q' ]
then
$bin -A FORWARD -s $1 -j LOG \
--log-prefix drop_blacklist_ -m limit --limit 3m
$bin -A FORWARD -d $1 -j LOG \
--log-prefix drop_blacklist_ -m limit --limit 3m
fi
$bin -A FORWARD -s $1 -j DROP
$bin -A FORWARD -d $1 -j DROP
return 0
}
# End function.
function accept_local {
# Accept a local service from the outside world.
# Usage protocol local_port optional_limit_masq
if [ "$3" = '' ]
then
$bin -A INPUT -i $wan_iface -p $1 -s ! $private_pool \
--dport $2 -j ACCEPT
else
$bin -A INPUT -i $wan_iface -p $1 -s $3 \
--dport $2 -j ACCEPT
fi
return 0
}
# End function.

# Flush old rules.
$bin -F
$bin -X
$bin -t nat -F
$bin -t nat -X
# Reset packet counters
$bin -Z

# Set default policy
$bin -P INPUT ACCEPT
$bin -P OUTPUT ACCEPT
$bin -P FORWARD DROP

# NAT table
# default line to mask
# Note nat is only done if we are going outside the private pool
for current_net in $masq_nets
do
$bin -t nat -A POSTROUTING -s $current_net -d ! $private_pool \
-o $wan_iface -j MASQUERADE
done

# filtering table-input
# allow specific local services.
#accept_local tcp 22
# drop incoming using the stateful firewall.
# Note that this will not allow related connections EG those created by 
# DCC if you are using the helper module.  You must use:
# ESTABLISHED,RELATED
$bin -A INPUT -i $wan_iface -m state --state ESTABLISHED -j ACCEPT
if [ "$log_dropped_external" = '1' ]
then
$bin -A INPUT -p tcp -i $wan_iface --syn -j LOG \
--log-prefix drop_external_syn_ -m limit --limit 3m
fi
$bin -A INPUT -i $wan_iface -j DROP

# Filtering table-forwarding
# no private addresses from the big bad world at all.
$bin -A FORWARD -i $wan_iface -s $private_pool -j LOG \
--log-prefix drop_prvaddr_eth1_ -m limit --limit 3m
$bin -A FORWARD -i $wan_iface -s $private_pool -j DROP

# no intra network routing here.
# Logging of these packets is disabled for now.
#$bin -A FORWARD -s $private_pool -d $private_pool -j LOG \
#--log-prefix drop_intra_route_eth0_ -m limit --limit 3m
$bin -A FORWARD -s $private_pool -d $private_pool -j DROP
#$bin -A FORWARD -i $lan_iface -o $lan_iface -j LOG \
#--log-prefix drop_intra_route_eth0_ -m limit --limit 3m
$bin -A FORWARD -i $lan_iface -o $lan_iface -j DROP

# block certain hosts.
# xlite connects to this on htp port with out permission
blacklist 64.69.76.0/24 q
# I think this is the insightbb security scanner.
blacklist 12.220.185.0/24
# allow specific insight smtp
#$bin -A FORWARD -i $wan_iface -p tcp -s 74.128.0.71/32 --dport 25 -j ACCEPT
#$bin -A FORWARD -i $wan_iface -p tcp -s 74.128.0.63/32 --dport 25 -j ACCEPT
# block insight ip blocks from smtp
# Info from arin.net whois server
# Last updated 20070418
#block_smtp 12.24.233.64/26
#block_smtp 12.147.60.192/26
#block_smtp 216.217.24.128/27
#block_smtp 74.128.0.0/12
#block_smtp 208.246.95.128/27

# port forwardings
#port_fwd tcp 25 192.168.1.4 25
#port_fwd tcp 2560 192.168.34.9 22
#port_fwd tcp 3001 192.168.1.4
#port_fwd tcp 3667 192.168.34.9 6667
#echolink
#port_fwd udp 5190:5199 192.168.34.14
# example of a range forward.
port_fwd tcp 15000:15020 192.168.34.9

# Allow forward of masked traffic.
# note a simple masquerade is not enough since we set are fwd policy to drop
for current_net in $masq_nets
do
$bin -A FORWARD -i $lan_iface -o $wan_iface -s $current_net \
-d ! $private_pool -j ACCEPT
$bin -A FORWARD -i $wan_iface -o $lan_iface -s ! $private_pool \
-d $current_net -m state --state ESTABLISHED -j ACCEPT
done

# Ending setup.
# enable forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# No broadcast storms pls..
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# This helps against IP spoofing.
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
date > /root/fw.resetdate
