#!/bin/sh
#  /etc/rc.d/rc.firewall

# %%%%%%%%%%%
# Modules %%%
# %%%%%%%%%%%

/sbin/depmod -a
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_MASQUERADE
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state

# %%%%%%%%%%%%
# Constants %%
# %%%%%%%%%%%%

IPTABLES="/sbin/iptables"

LOOPBACK_INTERFACE="lo"		        # loopback interface
LOCAL_INTERFACE_1="eth1"                # internal LAN interface
EXTERNAL_INTERFACE="eth0"		# external net interface
LOCALNET_1="10.1.1.0/24"                # private range
WWW_IP="10.1.1.3"			# WWW server
FTP_IP="10.1.1.3"			# FTP server
WIN_IP="10.1.1.2"			# Windows telnet client
MAIL_IP="10.1.1.4"			# MAIL server
DNS_IP="10.1.1.3"			# Inside DNS server
FIREWALL_IP="10.1.1.1"
PENGUIN_IP="10.1.1.6"			# Test mail server
CISCO_IP="10.1.1.7"

NAMESERVER_1="209.124.193.250"		# nameserver 1
NAMESERVER_2="209.124.203.12"		# nameserver 2
POPSERVER="mail.eatel.net"		# POP mail server
SMTPSERVER="mail.eatel.net"		# SMTP mail server
NEWSSERVER="news.eatel.net"		# NEWS server

LOOPBACK="127.0.0.1"                    # reserved loopback address range
CLASS_A="10.0.0.0/8"                    # class A private networks
CLASS_B="172.16.0.0/12"                 # class B private networks
CLASS_C="192.168.0.0/16"                # class C private networks
CLASS_D_MULTICAST="224.0.0.0/4"         # class D multicast addresses
CLASS_E_RESERVED_NET="240.0.0.0/5"      # class E reserved addresses
BROADCAST_SRC="0.0.0.0"                 # broadcast source address
BROADCAST_DEST="255.255.255.255"        # broadcast destination address
PRIVPORTS="0:1023"                      # well known, privileged port range
UNPRIVPORTS="1024:65535"                # unprivileged port range

NFS_PORT="2049"                         # (TCP/UDP) NFS
SOCKS_PORT="1080"                       # (TCP) Socks

# X Windows port allocation begins at 6000 and increments to 6063
# for each additional server running.
XWINDOW_PORTS="6000:6063"               # (TCP) X windows

# The SSH client starts at 1023 and works down to 513 for each
# additional simultaneous connection originating from a privileged port.
# Clients can optionally be configured to use only unprivileged
# ports.
SSH_PORTS="1022:65535"			# 2 allowed connection

# traceroute usually uses -s 32769:65535 -d 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"

# %%%%%%%%
# Flush %%
# %%%%%%%%

$IPTABLES -F
$IPTABLES -X
$IPTABLES -Z
$IPTABLES -t nat -F
$IPTABLES -t mangle -F

# %%%%%%%
# Drop %%
# %%%%%%%

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
# $IPTABLES -t nat -P POSTROUTING DROP
# $IPTABLES -t nat -P PREROUTING DROP
$IPTABLES --delete-chain
$IPTABLES -t nat --delete-chain

# %%%%%%%%%%
# System %%%
# %%%%%%%%%%

# Enable IPv4 packet forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Enable redirects
for f in /proc/sys/net/ipv4/conf/*/send_redirects; do
    echo 0 > $f
done

# For dynamic IP
echo 1 > /proc/sys/net/ipv4/ip_dynaddr

# Enable TCP SYN Cookie Protection
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Enable broadcast echo  Protection
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Enable bad error message  Protection
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

# Enable IP spoofing protection
# turn on Source Address Verification
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
    echo 1 > $f
done

# Disable ICMP Redirect Acceptance
for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do
    echo 0 > $f
done

# Disable Source Routed Packets
for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do
    echo 0 > $f
done

# Log Spoofed Packets, Source Routed Packets, Redirect Packets
for f in /proc/sys/net/ipv4/conf/*/log_martians; do
    echo 1 > $f
done

# %%%%%%%%%%%%%%
# DHCP client %%
# %%%%%%%%%%%%%%

# Read DHCP info
 if [ -f /etc/dhcpc/dhcpcd-$EXTERNAL_INTERFACE.info ];then
    . /etc/dhcpc/dhcpcd-$EXTERNAL_INTERFACE.info
    DHCP_SERVER=$DHCPSID
    IPADDR=$IPADDR
    HOST=$HOSTNAME
    DOMAIN=$DOMAIN
#    MAILSERVER="mail.$DOMAIN"
#    NEWSSERVER="news.$DOMAIN"
 fi

 echo "DHCP INFO..."
 echo "Host Name: $HOST"
 echo "Domain Name: $DOMAIN"
 echo "HOST IP: $IPADDR"
 echo "DHCP SERVER IP: $DHCP_SERVER"
#  echo "Mail Server: $MAILSERVER"
#  echo "News Server: $NEWSSERVER"

 DHCP_SERVER="0/0"

# allow dhcp server (67) to connect to dhcp client (68)
# Note: the DHCP server is the only externel source of broadcast
# messages we should see, ever.

 $IPTABLES  -A INPUT -i $EXTERNAL_INTERFACE -p udp  \
	-s $DHCP_SERVER --sport 67 \
        -d $IPADDR --dport 68 -j ACCEPT

 $IPTABLES  -A OUTPUT -o $EXTERNAL_INTERFACE -p udp  \
        -s $IPADDR --sport 68 \
        -d $DHCP_SERVER --dport 67 -j ACCEPT

 $IPTABLES  -A INPUT  -i $EXTERNAL_INTERFACE -p udp  \
        -s $DHCP_SERVER --sport 67 \
        -d $BROADCAST_DEST --dport 68 -j ACCEPT

 $IPTABLES  -A OUTPUT -o $EXTERNAL_INTERFACE -p udp  \
        -s $BROADCAST_SRC --sport 68 \
        -d $DHCP_SERVER --dport 67 -j ACCEPT

# Get renumbered

 $IPTABLES  -A INPUT  -i $EXTERNAL_INTERFACE -p udp  \
        -s $BROADCAST_SRC --sport 67 \
        -d $BROADCAST_DEST --dport 68 -j ACCEPT

 $IPTABLES  -A OUTPUT -o $EXTERNAL_INTERFACE -p udp  \
        -s $BROADCAST_SRC --sport 68 \
         -d $BROADCAST_DEST --dport 67 -j ACCEPT

# As a result of the above, we're supposed to change our IP 
# address with this message, which is addressed to our new 
# address before the dhcp client has received the update.

 $IPTABLES  -A INPUT -i $EXTERNAL_INTERFACE -p udp  \
        -s $DHCP_SERVER --sport 67 \
        --dport 68 -j ACCEPT

 $IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp  \
       --sport 67 \
        -d $IPADDR --dport 68 -j DROP 


# %%%%%%%%%%%%%%%
# Postrouting %%%
# %%%%%%%%%%%%%%%

# NAT RULE FOR LAN
$IPTABLES -t nat -A POSTROUTING -o $EXTERNAL_INTERFACE -j MASQUERADE

# %%%%%%%%%%%%%
# Prerouting %%
# %%%%%%%%%%%%%

# Drop bad packets
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $IPADDR -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_A -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_B -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_C -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $BROADCAST_DEST -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -d $BROADCAST_SRC -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_D_MULTICAST -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_E_RESERVED_NET -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 127.0.0.0/8 -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 169.254.0.0/16 -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 192.0.2.0/24 -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 224.0.0.0/3 -j DROP

# Stealth Scans and TCP State Flags

# All of the bits are cleared
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags ALL NONE -j DROP 
# SYN and FIN are both set
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags SYN,FIN SYN,FIN -j DROP 
# SYN and RST are both set
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags SYN,RST SYN,RST -j DROP 
# FIN and RST are both set
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags FIN,RST FIN,RST -j DROP 
# FIN is the only bit set, without the expected accompanying ACK
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags ACK,FIN FIN -j DROP 
# PSH is the only bit set, without the expected accompanying ACK
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags ACK,PSH PSH -j DROP 
# URG is the only bit set, without the expected accompanying ACK
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
	--tcp-flags ACK,URG URG -j DROP 

# Blacklist 
if [ -f /etc/rc.d/rc.firewall.blocked ]; then
    . /etc/rc.d/rc.firewall.blocked
fi

# NAT
# Create syn-flood chain for detecting
# Denial of Service attacks
$IPTABLES -t nat -N syn-flood

# Limit 12 connections per second (burst to 24)
$IPTABLES -t nat -A syn-flood -m limit --limit 12/s \
  --limit-burst 24 -j DROP
$IPTABLES -t nat -A syn-flood -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "SYN-FLOOD! "

# DNAT - HTTP - Port 80
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $UNPRIVPORTS --dport 80 -j DNAT \
	--to-destination $WWW_IP:80
# DNAT - HTTPS - Port 443
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $UNPRIVPORTS --dport 443 -j DNAT \
	--to-destination $MAIL_IP:443
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $UNPRIVPORTS --dport 25 -j DNAT \
	--to-destination $MAIL_IP:25
# DNAT - POP3S
 $IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $UNPRIVPORTS --dport 995 -j DNAT \
	--to-destination $MAIL_IP:995
# DNAT - SSH
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $SSH_PORTS --dport 22 -j DNAT \
	--to-destination $WWW_IP:22
# DNAT - IMAPS
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $UNPRIVPORTS --dport 993 -j DNAT \
	--to-destination $MAIL_IP:993
# DNAT - LDAPS
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
	-s 0/0 --sport $UNPRIVPORTS --dport 636 -j DNAT \
	--to-destination $MAIL_IP:636

# %%%%%%%%%
# Input %%%
# %%%%%%%%%

$IPTABLES -A INPUT -p TCP -i $EXTERNAL_INTERFACE -d $IPADDR -j DROP
$IPTABLES -A INPUT -p ICMP -i $EXTERNAL_INTERFACE -d $IPADDR -j DROP
$IPTABLES -A INPUT -p UDP --dport 53 --sport $UNPRIVPORTS -j ACCEPT

# LAN
$IPTABLES -A INPUT -i $LOCAL_INTERFACE_1 -s $LOCALNET_1 -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LOOPBACK_INTERFACE -j ACCEPT
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "IN DROP! "

# %%%%%%%%%
# Output %%
# %%%%%%%%%

$IPTABLES -A OUTPUT -p ALL -s $LOOPBACK -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $IPADDR -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LOCALNET_1 -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -m state --state ESTABLISHED,RELATED \
	-j ACCEPT
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "OUT DROP! "

# %%%%%%%%%%
# Forward %%
# %%%%%%%%%%


$IPTABLES -N fwtcpOK
$IPTABLES -A fwtcpOK -p TCP -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A fwtcpOK -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "FW DROP TCP: "
$IPTABLES -A fwtcpOK -p TCP -j DROP

$IPTABLES -N estfwtcpOK
$IPTABLES -A estfwtcpOK -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A estfwtcpOK -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "FW DROP TCP: "
$IPTABLES -A estfwtcpOK -p TCP -j DROP

$IPTABLES -N fwtcpi
$IPTABLES -A fwtcpi -p TCP --dport 80 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 22 --sport $SSH_PORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 25 --sport $SSH_PORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 110 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 119 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 443 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 636 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 993 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 995 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS  --sport $UNPRIVPORTS -j estfwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS  --sport $PRIVPORTS -j estfwtcpOK
$IPTABLES -A fwtcpi -p TCP -d $WIN_IP --dport $UNPRIVPORTS --sport 23 -j fwtcpOK 
$IPTABLES -A fwtcpi -p TCP --dport $SSH_PORTS --sport 22 -j fwtcpOK 
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS \
	-s $POPSERVER --sport 110 -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS \
	-s $NEWSSERVER --sport 119 -j fwtcpOK  

$IPTABLES -N fwicmpin
# destination unreachable: used by traceroute
$IPTABLES -A fwicmpin -p ICMP --icmp-type 3 -j ACCEPT
# source quench
$IPTABLES -A fwicmpin -p ICMP --icmp-type 4 -j ACCEPT
# time exceeded: used by traceroute
$IPTABLES -A fwicmpin -p ICMP --icmp-type 11 -j ACCEPT
# parameter problem
$IPTABLES -A fwicmpin -p ICMP --icmp-type 12 -j ACCEPT
$IPTABLES -A fwicmpin -p ICMP -m state --state ESTABLISHED,RELATED \
	-j ACCEPT
$IPTABLES -A fwicmpin -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "FW DROP ICMP: "
$IPTABLES -A fwicmpin -p ICMP -j DROP

$IPTABLES -N fwudpin
$IPTABLES -A fwudpin -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A fwudpin -p UDP --dport 53 --sport $UNPRIVPORTS -j  ACCEPT
$IPTABLES -A fwudpin -p UDP --sport 53 --dport $UNPRIVPORTS -j  ACCEPT
$IPTABLES -A fwudpin -m limit --limit 3/minute --limit-burst 3 \
	-j LOG --log-level DEBUG --log-prefix "FW DROP UDP: "
$IPTABLES -A fwudpin -p UDP -j DROP

$IPTABLES -A FORWARD -p TCP  -o $EXTERNAL_INTERFACE \
	-s $MAIL_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP  -o $EXTERNAL_INTERFACE \
	-s $WWW_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP  -o $EXTERNAL_INTERFACE \
	-s $PENGUIN_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP  -o $EXTERNAL_INTERFACE \
	-s $WIN_IP -j ACCEPT

$IPTABLES -A FORWARD -p TCP  -i $EXTERNAL_INTERFACE \
	-d $LOCALNET_1 -j fwtcpi
$IPTABLES -A FORWARD -p ICMP -o $EXTERNAL_INTERFACE \
	-s $LOCALNET_1 -j ACCEPT
$IPTABLES -A FORWARD -p ICMP -i $EXTERNAL_INTERFACE \
	-d $LOCALNET_1 -j fwicmpin
$IPTABLES -A FORWARD -p UDP -o $EXTERNAL_INTERFACE \
	-s $LOCALNET_1 -j ACCEPT
$IPTABLES -A FORWARD -p UDP -i $EXTERNAL_INTERFACE \
	-d $LOCALNET_1 -j fwudpin
$IPTABLES -A FORWARD -p UDP -i $EXTERNAL_INTERFACE \

# %%%%%% # Log %% # %%%%%%

# TCP
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -p tcp -j LOG \
	--log-prefix "LOG TCP-IN: "
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -p tcp -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp -j LOG \
	--log-prefix "LOG TCP-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp -j DROP
# ICMP
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -p icmp -j LOG \
	--log-prefix "LOG ICMP-IN: "
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -p icmp -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp -j LOG \
	--log-prefix "LOG ICMP-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp -j DROP
# UDP
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -p udp -j LOG \
	--log-prefix "LOG UDP-IN: "
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -p udp -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp -j LOG \
	--log-prefix "LOG UDP-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp -j DROP
# Paranoid
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -j LOG \
	--log-prefix "LOG PROTOCOL-X-IN: "
$IPTABLES -A INPUT  -i $EXTERNAL_INTERFACE -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -j LOG \
	--log-prefix "LOG PROTO-X-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -j DROP

exit 0