#!/bin/bash
#
# @(#)fastwall-on.sh 1.0.0 15/07/2008 Copyright 2008 Robert M. Stockmann
#                                                    stock@stokkie.net
#
# This firewall is based on the philosophy of
#
# "Hardening a Linux Server in 10 Minutes"
# http://rudd-o.com/archives/2006/02/27/hardening-a-linux-server-in-10-minutes/
#
# It computes from the shorewall rules and 'netstat -ltunp' the TCP 
# and UDP ports which need to be closed on the NETWORKS which aren't 
# local. This may seem like a hack, but it sure makes life easier 
# with getting some complicated application working. It's in 
# particular handy if your Linux PC is NOT the router but only doing 
# the fire-walling.
# 
# Mode of operation :
# Figure out which udp and tcp ports need to be opened for public 
# Internet use, like HTTP port 80 or SMTP port 25. Make sure these 
# udp and tcp ports are listed inside /etc/shorewall/rules.drakx .. : 
# example :
#
# [mail:root]:(~)# cat /etc/shorewall/rules.drakx 
# ACCEPT  net     fw      udp     53,110,1194     -
# ACCEPT  net     fw      tcp     80,443,53,22,20,21,25,109,110,143,110   -
# [mail:root]:(~)# 
#
# Next run fastwall-on.sh after which you check from the Internet
# with nmap if the desired result is obtained :
# nmap -v -sT -O <gw.example.com>
#

IPTABLES=/sbin/iptables
RULES=/etc/shorewall/rules.drakx

TCPACCEPT=`cat $RULES | grep tcp | awk '{print $5}' | sed 's/,/ /g'`
UDPACCEPT=`cat $RULES | grep udp | awk '{print $5}' | sed 's/,/ /g'`
TCPLISTEN=`netstat -ltunp | grep "^tcp" | awk '{print $4}' |\
		awk -F":" '{print $2}' | sed '/^$/d' | uniq | sort -n`
UDPLISTEN=`netstat -ltunp | grep "^udp" | awk '{print $4}' |\
		awk -F":" '{print $2}' | sed '/^$/d' | uniq | sort -n`
LOCALNET="127.0.0.1 192.168.2.0/24"

# 
# Compute TCP ACCEPT
#
for tcp in $TCPLISTEN
do
	FOO=`echo "$TCPACCEPT" | grep "$tcp"`
	if [ "$FOO" == "" ]; then
	   for net in $LOCALNET
	   do
		$IPTABLES -A INPUT --protocol tcp \
			--destination-port $tcp -s $net -j ACCEPT	
	   done
	fi
done

# 
# Compute UDP ACCEPT
#
for udp in $UDPLISTEN
do
	FOO=`echo "$UDPACCEPT" | grep "$udp"`
	if [ "$FOO" == "" ]; then
	   for net in $LOCALNET
	   do
		$IPTABLES -A INPUT --protocol udp \
			--destination-port $udp -s $net -j ACCEPT	
	   done
	fi
done

# 
# Compute TCP REJECT
#
for tcp in $TCPLISTEN
do
	FOO=`echo "$TCPACCEPT" | grep "$tcp"`
	if [ "$FOO" == "" ]; then
		$IPTABLES -A INPUT --protocol tcp \
			--destination-port $tcp -j REJECT
	fi
done

# 
# Compute UDP REJECT
#
for udp in $UDPLISTEN
do
	FOO=`echo "$UDPACCEPT" | grep "$udp"`
	if [ "$FOO" == "" ]; then
		$IPTABLES -A INPUT --protocol udp \
			--destination-port $udp -j REJECT
	fi
done

exit 0

