#!/bin/sh
#
# Configure network limitations for the host.
# 
# Enable or disable network filtering.  Call with 'auto' to enable or
# disable based on host netgroup membership.  Users that are member in
# the admin and nonetblk file group avoid the block when it is enabled
# for the host.
#
# Allow
# user root to get APT and other services working
# user ntp to synchronize the time
# user nagios to allow passing system minotoring information to
#   external collectors.
# user bind to get DNS server working
# user proxy to allow squid to fetch data from external sites
# user Debian-exim to be able to send email out and receive email in
# group nonetlim to allow privileged users to get their work done.

# Make sure iptables is in the PATH
PATH=/sbin:$PATH
export PATH

hostnetgroup=netblock-hosts

# Allow these system users and groups full access by default, if they
# exist on the machine.
privilegedusers="root Debian-exim bind ntp nagios proxy nslcd openldap xrdp www-data avahi dovecot statd daemon"
privilegedgroups="admins nonetblk"

# Allow everything into the loopback network
localnet="127.0.0.0/8"

# And every private network as well, these are (should not normally
# be) routed on the internet, and thus should be local to the site.
privatenet="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"

# Allow for more networks to be listed in /etc/default/update-netlimit
internalnet=""

. /lib/lsb/init-functions
if [ -f /etc/default/rcS ]; then
  . /etc/default/rcS
fi

if [ -f /etc/debian-edu/netblock ] ; then
    . /etc/debian-edu/netblock
fi

start_filtering() {
    if [ "$VERBOSE" != no ]; then
	log_begin_msg "Activating network block on this host"
    fi

    modprobe ip_tables
    modprobe iptable_filter

    filterfile=$(tempfile)

    # We are the only filter firewall that should be in operation,
    # so we flush all existing rules first.  ... add others after
    # this - or modify it
    echo "*filter" >> $filterfile

    #no traffic is not allowed by default
    echo ":INPUT ACCEPT" >> $filterfile
    echo ":FORWARD DROP" >> $filterfile
    echo ":OUTPUT DROP" >> $filterfile

    # FIXME This is an alternative drop rule to only drop some
    # FIXME ports.
    # Drop all packages for a given user
    #iptables -I OUTPUT -p tcp --dport 23:120 -m owner \
    #    --uid-owner your_login_name -j DROP

    # Drop all packages for a given group
    #iptables -I OUTPUT -p tcp --dport 23:120 -m owner \
    #    --gid-owner examlimits -j DROP

    #note the way these are ordered - the chains are processed the
    #way we add them and we want them to be processed as fast as
    #possible

    # Most traffic is with workstations ( NFS ...  and netapps->
    # has high priority ) > thin clients > localhost > proxy (
    # internet ) > DNS > other daemons > root user ( can wait for
    # a few nanoseconds --- this might save a few precious CPU
    # cycles ... but don't overdo it ;)

    for subnet in $localnet $privatenet $internalnet ; do
	echo "-A OUTPUT -d $subnet -j ACCEPT" >> $filterfile
    done

    for user in $privilegedusers ; do
	if getent passwd $user > /dev/null ; then
	    echo "-A OUTPUT -m owner --uid-owner $user -j ACCEPT" >> $filterfile
	fi
    done
    for group in $privilegedgroups ; do
	if getent group $group > /dev/null ; then
	    echo "-A OUTPUT -m owner --gid-owner $group -j ACCEPT" >> $filterfile
	fi
    done
    echo "COMMIT" >> $filterfile
    iptables-restore $filterfile
    rm $filterfile
    logger -t "debian-edu-update-netblock" "making sure netblock is enabled"
    [ "$VERBOSE" != no ] && log_end_msg 0 || return 0
}

stop_filtering() {
    if [ "$VERBOSE" != no ]; then
	log_begin_msg "Disabling network block on this host"
    fi
    iptables -P INPUT ACCEPT
    iptables -P OUTPUT ACCEPT
    iptables -P FORWARD ACCEPT
    iptables -F
    logger -t "debian-edu-update-netblock" "making sure netblock is disabled"
    [ "$VERBOSE" != no ] && log_end_msg 0 || return 0
}

auto_filtering() {
    hostname=$(uname -n)
    if innetgr -h "$hostname" $hostnetgroup ; then
	start_filtering
    else
	stop_filtering
    fi
}

case "$1" in
    auto)
	auto_filtering
	;;
    start)
	start_filtering
	;;
    stop)
	stop_filtering
        ;;
    *)
	echo "error: argument '$1' is not handled'"
	echo "error: supported arguments: auto start stop"
	;;
esac

exit 0
