#!/bin/sh

# Shell functions sourced from /etc/rc.status:
#      rc_check         check and set local and overall rc status
#      rc_status        check and set local and overall rc status
#      rc_status -v     ditto but be verbose in local rc status
#      rc_status -v -r  ditto and clear the local rc status
#      rc_failed        set local and overall rc status to failed
#      rc_failed <num>  set local and overall rc status to <num><num>
#      rc_reset         clear local rc status (overall remains)
#      rc_exit          exit appropriate to overall rc status

if [ -s /etc/rc.status ]; then
    . /etc/rc.status
    rc_reset="rc_reset"
    rc_failed="rc_failed"
    rc_exit="rc_exit"
    rc_status="rc_status"
    rc_status_verbose="rc_status -v"
else
    rc_exit="exit"
fi


# First reset status of this service
$rc_reset

if [ -x /sbin/iptables ]; then
    iptables=/sbin/iptables
elif [ -x /usr/sbin/iptables ]; then
    iptables=/usr/sbin/iptables
else
    echo -e "\nNo iptables command found"
    $rc_failed
    $rc_exit
fi

if [ -x /sbin/ip6tables ]; then
    ip6tables=/sbin/ip6tables
elif [ -x /usr/sbin/ip6tables ]; then
    ip6tables=/usr/sbin/ip6tables
else
    echo -e "\nNo ip6tables command found"
fi

# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running

case "$1" in
    start)
        echo -n "Loading Firewall rules"

        # disable source address verification
        echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter

        # enable FTP data connection tracking
        modprobe ip_conntrack_ftp

        # Add default rules to drop everything except local and established traffic
        # and log everything that is about to be dropped
        $iptables --flush &&
        $iptables --delete-chain &&
        $iptables --policy INPUT DROP &&
        $iptables --policy FORWARD DROP &&
        $iptables --policy OUTPUT ACCEPT &&
        $iptables --append INPUT -p 2 -j ACCEPT &&
        $iptables --append INPUT -p udp --dport 520 -j ACCEPT &&
        $iptables --append INPUT -p udp --dport 67 -j ACCEPT &&
        $iptables --append INPUT -i lo -j ACCEPT &&
        $iptables --append INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT &&
        $iptables --append INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 3/hour -j LOG --log-prefix "DROPPED PACKET:"

        if modprobe ipv6; then
            # Add default rules to drop everything except local and established traffic
            # and log everything that is about to be dropped
            $ip6tables --flush &&
            $ip6tables --delete-chain &&
            $ip6tables --policy INPUT ACCEPT &&
            $ip6tables --policy FORWARD ACCEPT &&
            $ip6tables --policy OUTPUT ACCEPT &&
            $ip6tables --append INPUT -i lo -j ACCEPT &&
            $ip6tables --append INPUT -p icmpv6 -j ACCEPT &&
            $ip6tables --append INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT &&
            $ip6tables --append INPUT -m limit --limit 3/hour -j LOG --log-prefix "DROPPED IPV6 PACKET:"
        fi

        if [ "$?" != "0" ]; then
            echo -e "\nUnable to execute all firewall commands"
            $rc_failed
        fi

        $rc_status_verbose
        ;;
    stop)
        echo -n "Flushing Firewall rules"

        $iptables --flush
        $iptables --delete-chain
        $iptables --policy INPUT ACCEPT
        $iptables --policy FORWARD ACCEPT
        $iptables --policy OUTPUT ACCEPT

        if modprobe ipv6; then
            # Add default rules to drop everything except local and established traffic
            # and log everything that is about to be dropped
            $ip6tables --flush
            $ip6tables --delete-chain
            $ip6tables --policy INPUT ACCEPT
            $ip6tables --policy FORWARD ACCEPT
            $ip6tables --policy OUTPUT ACCEPT
        fi

        $rc_status_verbose
        ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 1
        ;;
esac

$rc_exit

