#!/bin/bash

# ID: rc.fw.single_host Wed Feb 20 14:26:09 EST 2008 ground/X

# Based on:
# ID: /root/rc.fw Tue Sep 11 23:57:41 EDT 2007 ground/X
# Based on:
# ID: rc.tables Wed Feb 28 18:06:45 EST 2001 ground/X

# Basic restrictive firewall.
# The default policy is drop so you need to add a rule for any packets
# that you want to pass the firewall.
# Also any packet that is denied is logged by the kernel.
# Ported from ipchains to netfilter
# Now support basic sysvinit arguments start/stop

export PATH='/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin'

# These interfaces will allow full access.
# At least lo is required.
open_interfaces='lo plip0'

# Iptables binary. you may prefer a full path.
bin='/sbin/iptables'

# log incoming tcp connections that are dropped.
log_incoming='1'

# Log all packets denied-probably a bad idea.
log_dropped='0'

function kernel_support {
# Load kernel support
modprobe iptable_filter
modprobe ipt_LOG
modprobe nf_conntrack_ipv4
modprobe xt_state
modprobe xt_limit
modprobe xt_tcpudp
return 0
}
# End function.

function flush_fw {
# Flush old rules.
$bin -F
$bin -X
# Reset packet counters
$bin -Z
return 0
}
# End function.

function start_fw {
echo 'Starting stateful firewall.'
kernel_support
# Set default policies
$bin -P INPUT DROP
$bin -P OUTPUT ACCEPT
$bin -P FORWARD DROP

 # Allow all ICMP
$bin -A INPUT -p icmp -j ACCEPT
$bin -A OUTPUT -p icmp -j ACCEPT

# allow specified interfaces.
echo -n 'Full access iface: '
for current_iface in $open_interfaces
do
echo -n "$current_iface "
$bin -A INPUT -i $current_iface -j ACCEPT
$bin -A OUTPUT -o $current_iface -j ACCEPT
done
echo

# Allow return traffic from established connections.
$bin -A INPUT -m state --state ESTABLISHED -j ACCEPT
# Log incoming TCP connections.
if [ "$log_incoming" = '1' ]
then
$bin -A INPUT -p tcp --syn -j LOG \
--log-prefix drop_external_syn_ -m limit --limit 3m
fi

# allow dhcp return traffic on priv ports.
$bin -A INPUT -p udp --dport 67:68 -j ACCEPT

# Log any packets that don't match this stuff.
# This should always be at the very bottom.
if [ "$log_dropped" = '1' ]
then
echo 'Warning: logging all dropped packets.'
$bin -A INPUT -j LOG
$bin -A FORWARD -j LOG
$bin -A OUTPUT -j LOG
fi

# Ending setup.
# disable forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward
# No broadcast storms pls..
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# This helps against IP spoofing.
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
return 0
}
# End function.

function stop_fw {
flush_fw
# Set default policies
$bin -P INPUT ACCEPT
$bin -P OUTPUT ACCEPT
$bin -P FORWARD DROP
echo 'Stopped firewall.'
return 0
}
# End function.

if [ "$1" = 'start' ]
then
start_fw
elif [ "$1" = 'stop' ]
then
stop_fw
elif [ "$1" = 'reload' ]
then
stop_fw
start_fw
else
echo 'Error: start stop reload as arg.'
exit 1
fi
exit 0
