#!/bin/bash
#. /etc/rc.status
. /etc/rc.status.anon
rc_reset

# ANON firewall: all specified ports are opened
# The firewall is suitable for First, Middle and Last Mixes and
# an InfoService.

# INCOMING: SSH
SSH_PORT="22"

# INCOMING: all Mix types
MIX_HTTP_PORT="6544 3001"

# INCOMING: First Mix
MIX_HTTPS_PORT="443"

# INCOMING: Middle or Last Mix
PREVIOUS_MIX_IP=""

# INCOMING: InfoService
INFOSERVICE_PORTS="6543"


setAdditionalFilter()
# Activates and deactivates additional filters
# Arg_1 = [0|1] 0:deactivate; 1:activate
{
        # Drop ICMP echo-request messages sent to broadcast or multicast addresses
        echo $1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
        # Drop source routed packets
        echo $[1 ^ $1] > /proc/sys/net/ipv4/conf/all/accept_source_route
        # Enable TCP SYN cookie protection from SYN floods
        echo $1 > /proc/sys/net/ipv4/tcp_syncookies
        # Don't accept ICMP redirect messages
        echo $[1 ^ $1] > /proc/sys/net/ipv4/conf/all/accept_redirects
        # Don't send ICMP redirect messages
        echo $[1 ^ $1] > /proc/sys/net/ipv4/conf/all/send_redirects
        # Enable source address spoofing protection
        echo $1 > /proc/sys/net/ipv4/conf/all/rp_filter
        # Log packets with impossible source addresses
        echo $1 > /proc/sys/net/ipv4/conf/all/log_martians
}


case "$1" in
status)
	iptIn="`iptables -L | grep INPUT | grep ACCEPT`"
	iptOut="`iptables -L | grep OUTPUT | grep ACCEPT`"
	iptFor="`iptables -L | grep FORWARD | grep ACCEPT`"

	if [ "$iptIn" -a "$iptOut" -a "$iptFor" ]
	then
		iptIn="`iptables --list INPUT | grep -v INPUT | grep -v target`"
		iptOut="`iptables --list OUTPUT | grep -v OUTPUT | grep -v target`"
		iptFor="`iptables --list FORWARD | grep -v FORWARD | grep -v target`"

		if [ ! "$iptIn" -a ! "$iptOut" -a ! "$iptFor" ]
		then

			rc_failed 3 
		fi
	fi

        rc_status
        if [ $? -eq 0  ]
        then
                iptables -L
        fi


	rc_status -v
;;
restart)
	$0 stop
	$0 start
;;
stop)
	echo "Shutting down firewall..."
	setAdditionalFilter 0
	iptables -F
	iptables -P INPUT ACCEPT
	iptables -P OUTPUT ACCEPT
	iptables -P FORWARD ACCEPT
	rc_status -v
;;
start)
	echo "Starting firewall..."
	setAdditionalFilter 1

	# Set default policies
	iptables -P INPUT DROP
	iptables -P OUTPUT ACCEPT
	iptables -P FORWARD DROP

	iptables -A OUTPUT -j ACCEPT
	
	# Bypass all rules for the loopback device
	iptables -A INPUT -i lo -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
	# Previously initiated and accepted connections bypass rule checking
	iptables -A INPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
	# Allow ICMP ECHO REQUESTS
	iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

	# INCOMING tcp connections (services)
	for PORT in $INFOSERVICE_PORTS $SSH_PORT; do
		iptables -A INPUT -p tcp --syn --dport $PORT -m state --state NEW -j ACCEPT
	done
	if [ "$PREVIOUS_MIX_IP" ]; then
		iptables -A INPUT -p tcp --syn -s $PREVIOUS_MIX_IP --dport $MIX_HTTP_PORT -m state --state NEW -j ACCEPT
	else
		for PORT in $MIX_HTTP_PORT $MIX_HTTPS_PORT; do
			iptables -A INPUT -p tcp --syn --dport $PORT -m state --state NEW -j ACCEPT
		done
	fi
	
	# LOGGING	
	iptables -A INPUT -j LOG --log-prefix 'IN connection blocked.'
	iptables -A OUTPUT -j LOG --log-prefix 'OUT connection blocked.'
	iptables -A FORWARD -j LOG --log-prefix 'FORWARD connection blocked.'

	rc_status -v
;;

log)	
	cat /var/log/messages | grep "connection blocked"
;;
*)
	echo "Usage: $0 {start|stop|restart|status|log}"
	exit 1
;;

esac
rc_exit
