# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

# my config starts here
# Copyright (C) 2010  Glen Pitt-Pladdy
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
#
#
# See: http://www.pitt-pladdy.com/blog/_20100123-184109_0000_OpenWrt_with_native_IPv6_on_DG834_v2_using_AAISP_/
echo "My firewall"

# turn on logging                                                    
# IMPORTANT: this can bring such a small device to it's knees with a sustained
# attack / portscanning and the resulting volume of logging.
LOGPACKETS=0

# important systems / people
PERSON1=***.***.***.***
PERSON2=***.***.***.***
COMPANY1=***.***.***.***
COMPANY2=***.***.***.***
SERVEREXT=***.***.***.***
LAN=***.***.***.***/**
SERVEREXT6=****:****:****:****:****::****
LAN6=****:****:****:****:****::/**


# non-routable networks (should not see these here)
PRIVATENETS="
	127.0.0.0/8
	10.0.0.0/8
	172.16.0.0/12
	192.168.0.0/16
	169.254.0.0/16
	224.0.0.0/4
	240.0.0.0/5
"
PRIVATENETS6="
	fc00::/7
"

# what icmp to allow (related to connections)
SAFEICMP="
	destination-unreachable
	time-exceeded
	echo-reply
"
SAFEICMP6="
	destination-unreachable
	packet-too-big
	time-exceeded
	echo-reply
"

# some people just don't deserve access to the internet
BLACKLIST="
	***.***.***.***
	***.***.***.***
	***.***.***.***
	***.***.***.***
"
BLACKLIST6="
"


# syntax IPv4:  ipaddress:port-port
# syntax IPv6:  ipaddress.port-port
#################### generic TCP ####################
# someting serving on port 42
TCP_ALLOWIN="$TCP_ALLOWIN $SERVEREXT:42"
TCP6_ALLOWIN="$TCP6_ALLOWIN $SERVEREXT6.42"
# .... repeat for other ports / servers as needed

#################### generic UDP ####################
# someting serving on port 42 to 4242
UDP_ALLOWIN="$UDP_ALLOWIN $SERVEREXT:42-4242"
UDP6_ALLOWIN="$UDP6_ALLOWIN $SERVEREXT6.42-4242"
# .... repeat for other ports / servers as needed



# set options
# you can put extra stuff and setup (eg. echoing to stuff in /proc) here

# flush and set defaults
iptables --flush INPUT
iptables --flush OUTPUT
iptables --flush FORWARD
ip6tables --flush INPUT
ip6tables --flush OUTPUT
ip6tables --flush FORWARD
iptables --policy INPUT DROP
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD DROP
ip6tables --policy INPUT DROP
ip6tables --policy OUTPUT ACCEPT
ip6tables --policy FORWARD DROP


# first since it's vital to keep this running
# allow ssh to us from trusted sources (lan only)
echo ssh internal
iptables --append INPUT --in-interface eth0 \
	--proto tcp --destination-port 22 --syn \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append INPUT --in-interface eth0 \
	--proto tcp --destination-port 22 --syn \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT

# allow http on lan for Cacti Server ($SERVEREXT) for monitoring
echo http
iptables --append INPUT --in-interface eth0 \
	--proto tcp --source $SERVEREXT --destination-port 80 \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append INPUT --in-interface eth0 \
	--proto tcp --source $SERVEREXT6 --destination-port 80 \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
	
# allow dns on lan
iptables --append INPUT --in-interface eth0 \
	--proto udp --source $LAN --destination-port 53 \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append INPUT --in-interface eth0 \
	--proto udp --source $LAN6 --destination-port 53 \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT

# allow dhcp on lan
echo dhcp
iptables --append INPUT --in-interface eth0 \
	--proto udp --source-port 68 --destination-port 67 \
	--jump ACCEPT
# allow ipv6 neighbour stuff
ip6tables --append INPUT --in-interface eth0 --proto icmpv6 \
	--icmpv6-type neighbour-solicitation --jump ACCEPT
ip6tables --append INPUT --in-interface eth0 --proto icmpv6 \
	--icmpv6-type neighbour-advertisement --jump ACCEPT

# allow local loopback
echo local
iptables --append INPUT --in-interface lo \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append INPUT --in-interface lo \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT

# allow established
echo established
iptables --append INPUT --match state --state ESTABLISHED,RELATED \
	--proto tcp --jump ACCEPT
ip6tables --append INPUT --match state --state ESTABLISHED,RELATED \
	--proto tcp --jump ACCEPT
iptables --append FORWARD --match state --state ESTABLISHED,RELATED \
	--proto tcp --jump ACCEPT
ip6tables --append FORWARD --match state --state ESTABLISHED,RELATED \
	--proto tcp --jump ACCEPT
iptables --append INPUT --match state --state ESTABLISHED,RELATED \
	--proto udp --jump ACCEPT
ip6tables --append INPUT --match state --state ESTABLISHED,RELATED \
	--proto udp --jump ACCEPT
iptables --append FORWARD --match state --state ESTABLISHED,RELATED \
	--proto udp --jump ACCEPT
ip6tables --append FORWARD --match state --state ESTABLISHED,RELATED \
	--proto udp --jump ACCEPT
for type in $SAFEICMP; do
	echo icmp $type
	iptables --append INPUT \
		--proto icmp --icmp-type $type \
		--match state --state ESTABLISHED,RELATED --jump ACCEPT
	iptables --append FORWARD \
		--proto icmp --icmp-type $type \
		--match state --state ESTABLISHED,RELATED --jump ACCEPT
done
for type in $SAFEICMP6; do
	echo icmp6 $type
	ip6tables --append INPUT \
		--proto icmpv6 --icmpv6-type $type \
		--match state --state ESTABLISHED,RELATED --jump ACCEPT
	ip6tables --append FORWARD \
		--proto icmpv6 --icmpv6-type $type \
		--match state --state ESTABLISHED,RELATED --jump ACCEPT
done

# block non-routables and blacklist
for ip in $PRIVATENETS $BLACKLIST; do
	echo block $ip
	if [ $LOGPACKETS -eq 1 ]; then
		echo '** logging enabled'
		iptables --append FORWARD --source $ip \
			--jump LOG --log-prefix "Firewall: FORWARD block: "
		iptables --append FORWARD --destination $ip \
			--jump LOG --log-prefix "Firewall: FORWARD block: "
		iptables --append INPUT --in-interface eth0 --source $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
		iptables --append INPUT --in-interface ppp0 --source $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
		iptables --append INPUT --in-interface eth0 --destination $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
		iptables --append INPUT --in-interface ppp0 --destination $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
	fi
	iptables --append FORWARD --source $ip --jump DROP
	iptables --append FORWARD --destination $ip --jump DROP
	iptables --append INPUT --in-interface eth0 --source $ip --jump DROP
	iptables --append INPUT --in-interface eth0 --source $ip --jump DROP
	iptables --append INPUT --in-interface eth0 --destination $ip --jump DROP
	iptables --append INPUT --in-interface eth0 --destination $ip --jump DROP
done
for ip in $PRIVATENETS6 $BLACKLIST6; do
	echo block6 $ip
	if [ $LOGPACKETS -eq 1 ]; then
		echo '** logging enabled'
		ip6tables --append FORWARD --source $ip \
			--jump LOG --log-prefix "Firewall: FORWARD block: "
		ip6tables --append FORWARD --destination $ip \
			--jump LOG --log-prefix "Firewall: FORWARD block: "
		ip6tables --append INPUT --in-interface eth0 --source $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
		ip6tables --append INPUT --in-interface ppp0 --source $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
		ip6tables --append INPUT --in-interface eth0 --destination $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
		ip6tables --append INPUT --in-interface ppp0 --destination $ip \
			--jump LOG --log-prefix "Firewall: INPUT block: "
	fi
	ip6tables --append FORWARD --source $ip --jump DROP
	ip6tables --append FORWARD --destination $ip --jump DROP
	ip6tables --append INPUT --in-interface eth0 --source $ip --jump DROP
	ip6tables --append INPUT --in-interface eth0 --source $ip --jump DROP
	ip6tables --append INPUT --in-interface eth0 --destination $ip --jump DROP
	ip6tables --append INPUT --in-interface eth0 --destination $ip --jump DROP
done

# allow outbound
echo outbound
iptables --append FORWARD --in-interface eth0 --out-interface ppp0 \
	--proto tcp --syn \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
iptables --append FORWARD --in-interface eth0 --out-interface ppp0 \
	--proto udp \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
iptables --append FORWARD --in-interface eth0 --out-interface ppp0 \
	--proto icmp \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append FORWARD --in-interface eth0 --out-interface ppp0 \
	--proto tcp --syn \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append FORWARD --in-interface eth0 --out-interface ppp0 \
	--proto udp \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append FORWARD --in-interface eth0 --out-interface ppp0 \
	--proto icmpv6 \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT


# generic TCP
for rule in $TCP_ALLOWIN; do
	ip=`echo $rule|sed 's/^\(.*\):.*$/\1/'`
	port=`echo $rule|sed 's/^.*:\(.*\)$/\1/'`
	port=`echo $port|sed 's/-/:/'`
	echo tcpip $ip
	echo tcpport $port
	iptables --append FORWARD --in-interface ppp0 --out-interface eth0 \
		--proto tcp --destination $ip --destination-port $port --syn \
		--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
done
for rule in $TCP6_ALLOWIN; do
	ip=`echo $rule|sed 's/^\(.*\)\..*$/\1/'`
	port=`echo $rule|sed 's/^.*\.\(.*\)$/\1/'`
	port=`echo $port|sed 's/-/:/'`
	echo tcpip6 $ip
	echo tcpport6 $port
	ip6tables --append FORWARD --in-interface ppp0 --out-interface eth0 \
		--proto tcp --destination $ip --destination-port $port --syn \
		--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
done

# generic UDP
for rule in $UDP_ALLOWIN; do
	ip=`echo $rule|sed 's/^\(.*\):.*$/\1/'`
	port=`echo $rule|sed 's/^.*:\(.*\)$/\1/'`
	port=`echo $port|sed 's/-/:/'`
	echo udpip6 $ip
	echo udpport6 $port
	iptables --append FORWARD --in-interface ppp0 --out-interface eth0 \
		--proto udp --destination $ip --destination-port $port \
		--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
done
for rule in $UDP6_ALLOWIN; do
	ip=`echo $rule|sed 's/^\(.*\)\..*$/\1/'`
	port=`echo $rule|sed 's/^.*\.\(.*\)$/\1/'`
	port=`echo $port|sed 's/-/:/'`
	echo udpip6 $ip
	echo udpport6 $port
	ip6tables --append FORWARD --in-interface ppp0 --out-interface eth0 \
		--proto udp --destination $ip --destination-port $port \
		--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
done

# allowed icmp (ping only)
echo icmp ping
iptables --append FORWARD --in-interface ppp0 --out-interface eth0 \
	--proto icmp --icmp-type echo-request \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append FORWARD --in-interface ppp0 --out-interface eth0 \
	--proto icmpv6 --icmpv6-type echo-request \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
iptables --append INPUT --in-interface eth0 \
	--proto icmp --icmp-type echo-request \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append INPUT --in-interface eth0 \
	--proto icmpv6 --icmpv6-type echo-request \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
iptables --append INPUT --in-interface ppp0 \
	--proto icmp --icmp-type echo-request \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
ip6tables --append INPUT --in-interface ppp0 \
	--proto icmpv6 --icmpv6-type echo-request \
	--match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT

# reject IDENT attempts - still a few about these days causing connections to stall
iptables --append FORWARD --in-interface ppp0 \
	--proto tcp --destination-port 113 --jump REJECT
ip6tables --append FORWARD --in-interface ppp0 \
	--proto tcp --destination-port 113 --jump REJECT

# log anything that falls through
if [ $LOGPACKETS -eq 1 ]; then
	echo '** logging enabled'
	iptables --append INPUT --jump LOG --log-prefix "Firewall: INPUT default: "
	ip6tables --append INPUT --jump LOG --log-prefix "Firewall: INPUT default: "
	iptables --append FORWARD --jump LOG --log-prefix "Firewall: FORWARD default: "
	ip6tables --append FORWARD --jump LOG --log-prefix "Firewall: FORWARD default: "
fi


# set options (post rules)
# Work around networks that don't do window scaling properly and stall
# yup - some major names in network equipment still need this!
echo 0 >/proc/sys/net/ipv4/tcp_window_scaling
# Work around networks getting badly out of window packets and stall
# yup - some major names in network equipment still need this!
echo 1 >/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal







