#!/bin/sh
#
# APF 0.9.6 [apf@r-fx.org]
###
# Copyright (C) 1999-2004, R-fx Networks <proj@r-fx.org>
# Copyright (C) 2004, Ryan MacDonald <ryan@r-fx.org>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
###
#
CNF="/etc/apf/conf.apf"

if [ -f "$CNF" ] && [ ! "$CNF" == "" ]; then
   source $CNF
else
   head
   echo "\$CNF not found; aborting"
   exit 1
fi

if [ ! -f "$ip" ] && [ ! -f "$ifconfig" ]; then
	eout "{glob} $ip and $ifconfig not found; aborting"
	exit 1
fi

# check dev mode/set dev cronjob
devm

# load our iptables modules
modinit

# Delete user made chains. Flush and zero the chains.
flush 1

if [ ! "$IF" == "" ]; then
 for i in `echo $IF`; do
  VAL_IF=`/sbin/route -n | grep -w $i`
	if [ "$VAL_IF" == "" ]; then
		eout "{glob} could not verify that interface $IF is routed to a network, aborting."
		echo "could not verify that interface $IF is routed to a network, aborting."
		exit 1
	fi
 done
fi
if [ ! "$IFACE_TRUSTED" == "" ]; then
 for i in `echo $IFACE_TRUSTED`; do
  VAL_IFACE_TRUSTED=`/sbin/route -n | grep -w $i`
        if [ "$VAL_IFACE_TRUSTED" == "" ]; then
                eout "{glob} could not verify that interface $IFACE_TRUSTED is routed to a network, aborting."
		echo "could not verify that interface $IFACE_TRUSTED is routed to a network, aborting."
                exit 1
        fi
 done
fi

eout "{glob} determined (IN_IF) $IN_IF has address $NET"
eout "{glob} determined (OUT_IF) $OUT_IF has address $NET"

# Allow all traffic on the loopback interface
$IPT -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT
$IPT -A OUTPUT -o lo -s 0/0 -d 0/0 -j ACCEPT

# Allow all traffic on trusted interfaces
if [ ! "$IFACE_TRUSTED" == "" ]; then
for i in `echo $IFACE_TRUSTED | tr ',' ' '`; do
VAL_IF=`/sbin/ip addr list | grep -w $i`
if [ "$VAL_IF" == "" ]; then
        eout "{glob} unable to verify status of interface $i; assuming untrusted"
else
        eout "{glob} allow all to/from trusted interface $i"
        $IPT -A INPUT -i $i -s 0/0 -d 0/0 -j ACCEPT
        $IPT -A OUTPUT -o $i -s 0/0 -d 0/0 -j ACCEPT
fi
done
fi

# Create new trust-based global deny (GTD) convenience chain.
$IPT -N GTD
$IPT -A GTD -j DROP

# Create new trust-based global allow (GTA) convenience chain.
$IPT -N GTA
$IPT -A GTA -j ACCEPT

# Create new trust-based deny (TD) convenience chain.
$IPT -N TD
$IPT -A TD -j DROP

# Create new trust-based allow (TA) convenience chain.
$IPT -N TA
$IPT -A TA -j ACCEPT

# Create a new log and drop (LD) convenience chain.
$IPT -N LD
$IPT -A LD -j $LOG_TARGET --log-level=$LOG_LEVEL
$IPT -A LD -j DROP

# Create a new log and accept (LA) convenience chain.
$IPT -N LA
$IPT -A LA -j $LOG_TARGET --log-level=$LOG_LEVEL
$IPT -A LA -j ACCEPT

# Create TCP RESET & UDP PROHIBIT chains
$IPT -N RESET
$IPT -A RESET -p tcp -j REJECT --reject-with tcp-reset
$IPT -N PROHIBIT
$IPT -A PROHIBIT -j REJECT --reject-with icmp-host-prohibited

# Load our SYSCTL rules
. $INSTALL_PATH/sysctl.rules >> /dev/null 2>&1

# Load our PREROUTE rules
. $PRERT

# Block common nonroutable IP networks
if [ "$BLK_MCATNET" = "1" ]; then
	dnet $MCATNET
fi
if [ "$BLK_PRVNET" = "1" ]; then
	dnet $PRVNET
fi
if [ "$BLK_RESNET" = "1" ]; then
	if [ "$USE_RD" == "1" ]; then
		resnet_download
	fi
	dnet $RESNET
fi

# Load our Allow Hosts rules
glob_allow_download
glob_allow_hosts
allow_hosts

# Load our Blocked Traffic rules
. $INSTALL_PATH/bt.rules

if [ "$USE_AD" == "1" ]; then
eout "{glob} loading ad.rules"
. $ADR
fi

# Load our LOG rules
. $INSTALL_PATH/log.rules

# Virtual Adapters
. $INSTALL_PATH/vnet/main.vnet

# Clear any cport values
cl_cports
. $CNF

# Load our main TCP/UDP rules
if [ "$SET_VNET" == "1" ]; then
	VNET="$NET"
else
	VNET="0/0"
fi
. $INSTALL_PATH/main.rules

# Drop NEW tcp connections after this point
$IPT -A INPUT -i $IN_IF -p tcp ! --syn -m state --state NEW -j $DSTOP

# Data,Stat,Highport fixes
# probably more useless rules here than need to be
# and likewise not very well sorted but it works.
#
# Standard established/related connections
$IPT -A INPUT -i $IN_IF -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i $IN_IF -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o $OUT_IF -p tcp --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o $OUT_IF -p udp --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT

# DNS
if [ -f "/etc/resolv.conf" ] && [ "$RESV_DNS" == "1" ]; then
LDNS=`cat /etc/resolv.conf  | grep -v "#" | grep -w nameserver | awk '{print$2}' | grep -v 127.0.0.1`
  if [ ! "$LDNS" == "" ]; then
	for i in `echo $LDNS`; do
	eout "{glob} resolv dns discovery for $i"
	$IPT -A INPUT -i $IN_IF -p udp -s $i --sport 53 --dport 1023:65535 -j ACCEPT
	$IPT -A INPUT -i $IN_IF -p tcp -s $i --sport 53 --dport 1023:65535 -j ACCEPT
	if [ "$RESV_DNS_DROP" == "1" ]; then
		$IPT -A INPUT -i $IN_IF -p tcp -s 0/0 --sport 53 --dport 1023:65535 -j $DSTOP
                $IPT -A INPUT -i $IN_IF -p udp -s 0/0 --sport 53 --dport 1023:65535 -j $DSTOP
	fi
	done
  fi
else
	$IPT -A INPUT -i $IN_IF -p udp --sport 53 --dport 1023:65535 -j ACCEPT
	$IPT -A INPUT -i $IN_IF -p tcp --sport 53 --dport 1023:65535 -j ACCEPT
fi
# FTP
$IPT -A INPUT -i $IN_IF -p tcp --sport 1023:65535 --dport 21 -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i $IN_IF -p tcp -m multiport --dport 21,20 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i $IN_IF -p udp -m multiport --dport 21,20 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o $OUT_IF -p tcp --dport 1023:65535 --sport 21 -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o $OUT_IF -p tcp -m multiport --dport 21,20 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o $OUT_IF -p udp -m multiport --dport 21,20 -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH
$IPT -A INPUT -i $IN_IF -p tcp --sport 22 --dport 513:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i $IN_IF -p tcp --sport 1024:65535 --dport 22 --syn -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i $IN_IF -p udp --dport 22 -m state --state ESTABLISHED -j ACCEPT

# Traceroute
if [ "$TCR_PASS" == "1" ]; then
	$IPT -A INPUT -i $IN_IF -p udp -m state --state NEW --dport $TCR_PORTS -j ACCEPT
        $IPT -A OUTPUT -o $OUT_IF -p udp -m state --state NEW --dport $TCR_PORTS -j ACCEPT
fi


if [ "$LOG_DROP" == "1" ]; then
# Default TCP/UDP INPUT log chain
        if [ "$LOG_EXT" == "1" ]; then
	 $IPT -A INPUT -p tcp -m limit --limit $LOG_RATE/minute -i $IN_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** IN_TCP DROP ** " --log-tcp-options --log-ip-options
 	 $IPT -A INPUT -p udp -m limit --limit $LOG_RATE/minute -i $IN_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** IN_UDP DROP ** " --log-ip-options
	else
         $IPT -A INPUT -p tcp -m limit --limit $LOG_RATE/minute -i $IN_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** IN_TCP DROP ** "
         $IPT -A INPUT -p udp -m limit --limit $LOG_RATE/minute -i $IN_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** IN_UDP DROP ** "
	fi
fi

if [ "$LOG_DROP" == "1" ] && [ "$EGF" == "1" ]; then
# Default TCP/UDP OUTPUT log chain
	if [ "$LOG_EXT" == "1" ]; then
	 $IPT -A OUTPUT -p tcp -m limit --limit $LOG_RATE/minute -o $OUT_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** OUT_TCP DROP ** " --log-tcp-options --log-ip-options
	 $IPT -A OUTPUT -p udp -m limit --limit $LOG_RATE/minute -o $OUT_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** OUT_UDP DROP ** " --log-ip-options
	else
         $IPT -A OUTPUT -p tcp -m limit --limit $LOG_RATE/minute -o $OUT_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** OUT_TCP DROP ** "
         $IPT -A OUTPUT -p udp -m limit --limit $LOG_RATE/minute -o $OUT_IF -j $LOG_TARGET --log-level=$LOG_LEVEL --log-prefix "** OUT_UDP DROP ** "
	fi
fi


# Load our POSTROUTE rules
. $POSTRT

# Default Output Policies
if [ ! "$EGF" == "1" ] || [ "$EGF" == "" ]; then
        $IPT -A OUTPUT -j ACCEPT
        eout "{glob} default (egress) output accept"
elif [ "$EGF" == "1" ]; then
	$IPT -A OUTPUT -p tcp -j $TCP_STOP
	$IPT -A OUTPUT -p udp -j $UDP_STOP
        $IPT -A OUTPUT -p all -j $DSTOP
        eout "{glob} default (egress) output drop"
fi

# Default Input Policies
eout "{glob} default (ingress) input drop"
$IPT -A INPUT -p tcp -j $TCP_STOP
$IPT -A INPUT -p udp -j $UDP_STOP
$IPT -A INPUT -p all -j $DSTOP
