#!/bin/sh

SYSCTL="/sbin/sysctl -w" 
IPT="/sbin/iptables"
IPTS="/sbin/iptables-save"
IPTR="/sbin/iptables-restore"

# Internet Interface
INET_IFACE="eth1"
INET_ADDRESS="x.x.x.x"

# Local Interface Information
LOCAL_IFACE="eth0"
LOCAL_IP="192.168.1.3"
LOCAL_NET="192.168.1.0/24"
LOCAL_BCAST="192.168.1.255"

# Localhost Interface

LO_IFACE="lo"
LO_IP="127.0.0.1"

echo "Loading kernel modules ..."
/sbin/modprobe ip_tables

/sbin/modprobe ip_conntrack


# Reset Default Policies
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -t mangle -P PREROUTING ACCEPT
$IPT -t mangle -P OUTPUT ACCEPT

# Flush all rules
$IPT -F
$IPT -t nat -F
$IPT -t mangle -F

# Erase all non-default chains
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X

# Set Policies

$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP


echo "Create and populate custom rule chains ..."

# Create a chain to filter INVALID packets

$IPT -N bad_packets

# Create another chain to filter bad tcp packets

$IPT -N bad_tcp_packets

# Create separate chains for icmp, tcp (incoming and outgoing),
# and incoming udp packets.

$IPT -N icmp_packets

# Used for UDP packets inbound from the Internet
$IPT -N udp_inbound

# Used to block outbound UDP services from internal network
# Default to allow all
$IPT -N udp_outbound

# Used to allow inbound services if desired
# Default fail except for established sessions
$IPT -N tcp_inbound

# Used to block outbound services from internal network
# Default to allow all
$IPT -N tcp_outbound


# Drop packets received on the external interface
# claiming a source of the local network
$IPT -A bad_packets -p ALL -i $INET_IFACE -s $LOCAL_NET -j LOG \
    --log-prefix "fp=bad_packets:2 a=DROP "
$IPT -A bad_packets -p ALL -i $INET_IFACE -s $LOCAL_NET -j DROP

# Drop INVALID packets immediately
$IPT -A bad_packets -p ALL -m state --state INVALID -j LOG \
    --log-prefix "fp=bad_packets:1 a=DROP "

$IPT -A bad_packets -p ALL -m state --state INVALID -j DROP

# Then check the tcp packets for additional problems
$IPT -A bad_packets -p tcp -j bad_tcp_packets

# All good, so return
$IPT -A bad_packets -p ALL -j RETURN

$IPT -A bad_tcp_packets -p tcp -i $LOCAL_IFACE -j RETURN


$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
    --log-prefix "fp=bad_tcp_packets:1 a=DROP "
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j LOG \
    --log-prefix "fp=bad_tcp_packets:2 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP

$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j LOG \
    --log-prefix "fp=bad_tcp_packets:3 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP

$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG \
    --log-prefix "fp=bad_tcp_packets:4 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP

$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG \
    --log-prefix "fp=bad_tcp_packets:5 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j LOG \
    --log-prefix "fp=bad_tcp_packets:6 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG \
    --log-prefix "fp=bad_tcp_packets:7 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# All good, so return
$IPT -A bad_tcp_packets -p tcp -j RETURN


# Denial of service attack.
$IPT -A icmp_packets --fragment -p ICMP -j LOG \
    --log-prefix "fp=icmp_packets:1 a=DROP "
$IPT -A icmp_packets --fragment -p ICMP -j DROP


$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j DROP

# Time Exceeded
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT

# Not matched, so return so it will be logged
$IPT -A icmp_packets -p ICMP -j RETURN


$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 137 -j DROP
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 138 -j DROP
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 113 -j REJECT
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 53 -j ACCEPT
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 5353 -j ACCEPT
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 5353 -j ACCEPT
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 80 -j ACCEPT

# Not matched, so return for logging
$IPT -A udp_inbound -p UDP -j RETURN

# udp_outbound chain
# No match, so ACCEPT
$IPT -A udp_outbound -p UDP -s 0/0 -j ACCEPT

# long delays while connecting.  Also see the tcp_inbound rule.
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 113 -j REJECT

# Not matched, so return so it will be logged
$IPT -A tcp_inbound -p TCP -j RETURN

# tcp_outbound chain

echo "SSH Blocking.........."
$IPT -A INPUT -p tcp -s 192.168.1.210 -d 0/0 --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp -s 192.168.1.123 -d 0/0 --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp -s 192.168.1.37 -d 0/0 --dport 22 -j ACCEPT
$IPT -A FORWARD -i $LOCAL_IFACE -o $INET_IFACE -p tcp  -s 192.168.1.123 -d 0/0 --dport 22 -j ACCEPT
$IPT -A FORWARD -i $LOCAL_IFACE -o $INET_IFACE -p tcp  -s 192.168.1.37 -d 0/0 --dport 22 -j ACCEPT
$IPT -A FORWARD -i $LOCAL_IFACE -o $INET_IFACE -p tcp -s 192.168.1.210 -d 0/0 --dport 22 -j ACCEPT
$IPT -A FORWARD -i $LOCAL_IFACE -o $INET_IFACE -p tcp -s 192.168.1.0/24 -d 0/0 --dport 22 -j DROP
#$IPT -A OUTPUT -i $LOCAL_IFACE -o $INET_IFACE -p tcp  -s 192.168.1.38 -d 0/0 --dport 22 -j ACCEP

###################################################
#MAIL SERVER

$IPT -A INPUT -p tcp -s 0/0 -d x.x.x.x/32 --destination-port 25 --syn -j ACCEPT
$IPT -A FORWARD -p tcp -s 0/0 -d x.x.x.y/32 --destination-port 25 --syn -j ACCEPT
#$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 25 -j DNAT --to 192.168.1.100:25
#$IPT -A FORWARD -p tcp -d 192.168.1.100 --dport 25 -j ACCEPT


$IPT -A INPUT  -p tcp  -s 0/0 --dport 22 -j DROP
$IPT -A INPUT  -p tcp  -s 0/0 --dport 3306 -j DROP
#$IPT -A FORWARD  -p tcp -d 0/0 -s 0/0 --dport 80 -j DROP
$IPT -A INPUT  -p tcp  -s 0/0 --dport 111 -j DROP
$IPT -A INPUT  -p tcp  -s 0/0 --dport 199 -j DROP
$IPT -A INPUT  -p tcp  -s 0/0 --dport 443 -j ACCEPT

# Block IRC
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 194 -j REJECT

# Block Outbound Telnet
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 23 -j REJECT

# Block SSH
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 22 -j REJECT

# Block Usenet Access
$IPT -A tcp_outbound -p TCP -s 0/0 --destination-port 119 -j REJECT

# No match, so ACCEPT
$IPT -A tcp_outbound -p TCP -s 0/0 -j ACCEPT

###############################################################################
#
# INPUT Chain
#

echo "Process INPUT chain ..."

# Allow all on localhost interface
$IPT -A INPUT -p ALL -i $LO_IFACE -j ACCEPT

# Drop bad packets
$IPT -A INPUT -p ALL -j bad_packets

$IPT -A INPUT -p ALL -d 224.0.0.1 -j DROP

# Rules for the private network (accessing gateway system itself)
$IPT -A INPUT -p ALL -i $LOCAL_IFACE -s $LOCAL_NET -j ACCEPT
$IPT -A INPUT -p ALL -i $LOCAL_IFACE -d $LOCAL_BCAST -j ACCEPT


# Inbound Internet Packet Rules

# Accept Established Connections
$IPT -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED \
     -j ACCEPT

# Route the rest to the appropriate user chain
$IPT -A INPUT -p TCP -i $INET_IFACE -j tcp_inbound
$IPT -A INPUT -p UDP -i $INET_IFACE -j udp_inbound
$IPT -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets

# broadcast protocols.
$IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP

# Log packets that still don't match
$IPT -A INPUT -j LOG --log-prefix "fp=INPUT:99 a=DROP "

###############################################################################
#
# FORWARD Chain
#

echo "Process FORWARD chain ..."

# Used if forwarding for a private network

# Drop bad packets
$IPT -A FORWARD -p ALL -j bad_packets

# Accept TCP packets we want to forward from internal sources
$IPT -A FORWARD -p tcp -i $LOCAL_IFACE -j tcp_outbound

# Accept UDP packets we want to forward from internal sources
$IPT -A FORWARD -p udp -i $LOCAL_IFACE -j udp_outbound

# If not blocked, accept any other packets from the internal interface
$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -j ACCEPT

# Deal with responses from the internet
$IPT -A FORWARD -i $INET_IFACE -m state --state ESTABLISHED,RELATED \
     -j ACCEPT

# Log packets that still don't match
$IPT -A FORWARD -j LOG --log-prefix "fp=FORWARD:99 a=DROP "


echo "Process OUTPUT chain ..."


$IPT -A OUTPUT -m state -p icmp --state INVALID -j DROP

# Localhost
$IPT -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO_IFACE -j ACCEPT

# To internal network
$IPT -A OUTPUT -p ALL -s $LOCAL_IP -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LOCAL_IFACE -j ACCEPT

# To internet
$IPT -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT

# Log packets that still don't match
$IPT -A OUTPUT -j LOG --log-prefix "fp=OUTPUT:99 a=DROP "


# POSTROUTING chain
#

$IPT -t nat -A POSTROUTING -o $INET_IFACE \
     -j SNAT --to-source $INET_ADDRESS
############################################################################
#Redirect all 80 port request to 8080 SQUID PROXY 
# DNAT port 80 request comming from LAN systems to squid 3128 ($SQUID_PORT) aka transparent proxy

#$IPT -t nat -A PREROUTING -p tcp -i eth1 --dport 80 -j REDIRECT --to-ports 8080
#$IPT -t nat -A POSTROUTING -o eth1 -s $LOCAL_NET -j MASQUERADE
#$IPT -A FORWARD -s $LOCAL_NET -d 192.168.1.3 -i eth1 -o eth0 -p tcp --dport 8080 -j ACCEPT
#$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080

$IPT -t nat -A PREROUTING -i eth0 -d 192.168.1.0/255.255.255.0 ACCEPT
$IPT -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080





