#!/bin/sh
#
# Explanation of what this is about
#
# My internet connection is a modem on ppp0
# I have a number of mostly trusted computers on eth0 and eth1
# I have distinctly un-trusted computers on eth2 (trojanised boxes, for observation purposes)
#
# I want eth0 and eth1 to be able to access a number of services on the internet, on this host,
# and probably to a lesser extent, from eth0 to eth1 and vice-versa.
#
# I haven't decided exactly what I'm going to allow on eth2 yet.

EXT_IF=ppp0
IF1=eth0
IF2=eth1
IF3=eth2
LO_IF=lo

localtcp=22,53,80,139,443,800
localudp=53,137,138
services=21,22,23,25,53,79,80,110,119,143
servicesSSL=443,465,993,995
servicesIM=6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,1863,5050,5190

firewall_start() {

# Flush all rules and chains
	/usr/sbin/iptables -F
	/usr/sbin/iptables -X

#############################################
# INPUT chain rules.
# Incoming packets to local processes are tested against these rules.
#############################################
# Set policy of input chain to drop
	/usr/sbin/iptables -P INPUT DROP
# First accept traffic which is part of established connections. This is the majority of the input traffic.
	/usr/sbin/iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
	/usr/sbin/iptables -A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
# Accept all local loopback traffic
	/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
# Accept icmp echo replies
	/usr/sbin/iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
# Accept icmp echo requests from IF1, IF2
	/usr/sbin/iptables -A INPUT -p icmp --icmp-type echo-request -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A INPUT -p icmp --icmp-type echo-request -i $IF2 -j ACCEPT
# Bin some undesirable icmp types before accepting "related"
	/usr/sbin/iptables -A INPUT -p icmp -j DROP
# Related state matches icmp packets related to established conversations
	/usr/sbin/iptables -A INPUT -m state --state RELATED -j ACCEPT
# accept some attempted connections
	/usr/sbin/iptables -A INPUT -p tcp --syn -m multiport --dports $localtcp -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A INPUT -p udp -m multiport --dports $localudp -i $IF1 -j ACCEPT

	/usr/sbin/iptables -A INPUT -p tcp --syn -m multiport --dports $localtcp -i $IF2 -j ACCEPT
	/usr/sbin/iptables -A INPUT -p udp -m multiport --dports $localudp -i $IF2 -j ACCEPT

	/usr/sbin/iptables -A INPUT -p tcp --syn -m multiport --dports 22,53 -i $IF3 -j ACCEPT
	/usr/sbin/iptables -A INPUT -p udp -m multiport --dports 53 -i $IF1 -j ACCEPT

# Drop selected annoying things before logging
#	/usr/sbin/iptables -A INPUT arguments -j DROP	
# drop some X Windows broadcasts
	/usr/sbin/iptables -A INPUT -p udp --dport 6001 -j DROP	
# drop smb scans coming in from the internet
	/usr/sbin/iptables -A INPUT -p udp -m multiport --dports 137 -i $EXT_IF -j DROP	
#drop gnutella packets coming in too.
	/usr/sbin/iptables -A INPUT -p tcp -m multiport --dports 6346 -i $EXT_IF -j DROP	

	/usr/sbin/iptables -A INPUT -j LOG


#############################################
# FORWARD chain
# To control packet routing
#############################################
# Set policy of FORWARD chain to drop
	/usr/sbin/iptables -P FORWARD DROP
# First accept traffic which is part of established connections
# there goes the majority of the forward traffic.
	/usr/sbin/iptables -A FORWARD -p tcp -m state --state ESTABLISHED -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p udp -m state --state ESTABLISHED -j ACCEPT
# Accept icmp echo replies
	/usr/sbin/iptables -A FORWARD -p icmp --icmp-type echo-reply -j ACCEPT
# Aceept icmp echo requests from IF1, IF2
	/usr/sbin/iptables -A FORWARD -p icmp --icmp-type echo-request -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p icmp --icmp-type echo-request -i $IF2 -j ACCEPT
# Bin some undesirable icmp types before accepting "related"
	/usr/sbin/iptables -A FORWARD -p icmp -j DROP
# Related state matches icmp packets related to established conversations, and ftp data connections.
	/usr/sbin/iptables -A FORWARD -m state --state RELATED -j ACCEPT
# accept some attempted connections
# From IF1 (no discrimination about where its going at present):
	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports $services -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports $servicesSSL -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports $servicesIM -i $IF1 -j ACCEPT

	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports $services -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports $servicesSSL -i $IF1 -j ACCEPT

# From IF2:
	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports $services -i $IF2 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports $servicesSSL -i $IF2 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports $servicesIM -i $IF2 -j ACCEPT

	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports $services -i $IF1 -j ACCEPT
	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports $servicesSSL -i $IF1 -j ACCEPT

# From IF3:
# Don't allow anything at present.
#	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports 21,22,23,25,53,79,80,119,139,143,443,465,800,993,995 -i $IF3 -o ppp0 -j ACCEPT
#	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports 21,22,23,25,53,79,80,119,139,143,443,465,800,993,995 -i $IF3 -o ppp0 -j ACCEPT

#	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports 21,22,23,25,53,79,80,119,139,143,443,465,800,993,995 -i $IF3 -o $IF1 -j ACCEPT
#	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports 21,22,23,25,53,79,80,119,139,143,443,465,800,993,995 -i $IF3 -o $IF1 -j ACCEPT

#	/usr/sbin/iptables -A FORWARD -p tcp --syn -m multiport --dports 21,22,23,25,53,79,80,119,139,143,443,465,800,993,995 -i $IF3 -o $IF2 -j ACCEPT
#	/usr/sbin/iptables -A FORWARD -p udp -m multiport --dports 21,22,23,25,53,79,80,119,139,143,443,465,800,993,995 -i $IF3 -o $IF2 -j ACCEPT

# From ppp0:
#Nothing. I'm not forwarding things from ppp0, there'll be some redirects to do, but that's DNAT

# Drop selected annoying things before logging
#	/usr/sbin/iptables -A FORWARD arguments -j DROP	

	/usr/sbin/iptables -A FORWARD -j LOG


#############################################
#OUTPUT chain
# Locally generated packets.
#############################################
#Accept most things, if there's locally generated bad stuff, I've got serious problems
	/usr/sbin/iptables -P OUTPUT ACCEPT

#Completely mistrust any attemted IRC comms from the firewall.
#This will be seen as paranoia by some folks.
	/usr/sbin/iptables -A OUTPUT -p tcp -m multiport --dports 194,529,994,6667 -j DROP
	/usr/sbin/iptables -A OUTPUT -p udp -m multiport --dports 194,529,994,6667 -j DROP

#############################################
# NAT table rules
# man iptables excerpt "This table is consulted when a packet that creates a new connection is encountered."
#############################################
	/usr/sbin/iptables -t nat -P PREROUTING ACCEPT
	/usr/sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

#############################################
# And finally, start the forwarding.
#############################################
	echo "1" > /proc/sys/net/ipv4/ip_forward
	echo "Firewall Started"
}

firewall_stop() {
	/usr/sbin/iptables -F
	/usr/sbin/iptables -X
	echo "0" > /proc/sys/net/ipv4/ip_forward
	echo "Firewall Stopped"
}

firewall_restart() {
	firewall_stop
	sleep 1
	firewall_start
}



case "$1" in
'start')
	firewall_start
	;;
'stop')
	firewall_stop
	;;
'restart')
	firewall_restart
	;;
*)
	echo "usage $0 start|stop|restart"
esac
