#!/bin/bash

# define a firewall using iptables
# by Lance Kinley
#
# these rules are for allowing basic internet services in and out
# while forwarding internal LAN traffic destined for the internet

HOST=<host ip> # ie. 10.0.1.254
NETWORK=<network ip> # ie. 10.0.1.0
LAN=192.168.0.0/16 # internal private LAN to NAT/MASQ
EXTNIC=eth1
PRIVNIC1=eth0

# flush everything
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

# set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# forwarding state check chain
iptables -N f_state_chk
iptables -A f_state_chk -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A f_state_chk -m state --state NEW -i ! $EXTNIC -j ACCEPT
iptables -A f_state_chk -j DROP

# refuse class a private from external interface
iptables -A INPUT -i $EXTNIC -s 10.0.0.0/8 -j DROP
iptables -A OUTPUT -o $EXTNIC -d 10.0.0.0/8 -j DROP
# refuse class b private from external interface
iptables -A INPUT -i $EXTNIC -s 172.16.0.0/12 -j DROP
iptables -A OUTPUT -o $EXTNIC -d 172.16.0.0/12 -j DROP
# refuse class c private from external interface
iptables -A INPUT -i $EXTNIC -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i $EXTNIC -s 192.168.0.0/16 -j LOG
iptables -A OUTPUT -o $EXTNIC -d 192.168.0.0/16 -j DROP
# refuse class d multicast from external interface
iptables -A INPUT -i $EXTNIC -s 224.0.0.0/4 -j DROP
iptables -A OUTPUT -o $EXTNIC -d 224.0.0.0/4 -j DROP
# refuse class e reserved from external interface
iptables -A INPUT -i $EXTNIC -s 240.0.0.0/5 -j DROP
iptables -A OUTPUT -o $EXTNIC -d 240.0.0.0/5 -j DROP
# refuse localhost from external interface
iptables -A INPUT -i $EXTNIC -s 127.0.0.0/8 -j DROP
iptables -A OUTPUT -o $EXTNIC -d 127.0.0.0/8 -j DROP

# refuse spoofed ext pkts pretending to be from the int addr
iptables -A INPUT -i $EXTNIC -s $HOST -j DROP
iptables -A INPUT -i $EXTNIC -s $HOST -j LOG

# refuse malformed broadcast pkts
iptables -A INPUT -i $EXTNIC -s 255.255.255.255 -j DROP
iptables -A INPUT -i $EXTNIC -d 0.0.0.0 -j DROP

# allow all connections from private networks
iptables -A INPUT -i $PRIVNIC1 -j ACCEPT
iptables -A OUTPUT -o $PRIVNIC1 -j ACCEPT

# forwarding rules using f_state_chk
iptables -A FORWARD -j f_state_chk

# allow all loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# NAT LAN traffic to the internet
# if your internet IP is dynamic, use the MASQUERADE line
# if your IP is static, use the SNAT line
#iptables -t nat -A POSTROUTING -o $EXTNIC -s $LAN -j MASQUERADE
iptables -t nat -A POSTROUTING -o $EXTNIC -s $LAN -j SNAT --to $HOST

# ICMP section
# allow source quench (type 4) messages
iptables -A INPUT -i $EXTNIC -d $HOST -p icmp --icmp-type source-quench -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type source-quench -j ACCEPT
# allow parm problem (type 12) messages
iptables -A INPUT -i $EXTNIC -d $HOST -p icmp --icmp-type parameter-problem -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type parameter-problem  -j ACCEPT
# allow dest unreachable (type 3) messages
iptables -A INPUT -i $EXTNIC -d $HOST -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type destination-unreachable -j ACCEPT
# allow time exceeded (type 11) messages
iptables -A INPUT -i $EXTNIC -d $HOST -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type time-exceeded -j ACCEPT
# allow icmp message subtype codes
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type fragmentation-needed -j ACCEPT
# allow outgoing pings
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p icmp --icmp-type echo-reply -j ACCEPT
# allow incoming pings
iptables -A INPUT -i $EXTNIC -d $HOST -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p icmp --icmp-type echo-reply -j ACCEPT
# block all smurf attacks
iptables -A INPUT -i $EXTNIC -d 255.255.255.255 -p icmp -j DROP
iptables -A OUTPUT -o $EXTNIC -d 255.255.255.255 -p icmp -j REJECT
iptables -A INPUT -i $EXTNIC -d 255.255.255.0 -p icmp -j DROP
iptables -A OUTPUT -o $EXTNIC -d 255.255.255.0 -p icmp -j REJECT
iptables -A INPUT -i $EXTNIC -d $NETWORK -p icmp -j DROP
iptables -A OUTPUT -o $EXTNIC -d $NETWORK -p icmp -j REJECT

# allow traceroutes
iptables -A OUTPUT -o $EXTNIC -s $HOST -p udp --sport 32769: --dport 33434:33523 -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p udp --sport 33434:33523 --dport 32769: -j ACCEPT

# refuse addrs defined as reserved by IANA
iptables -A INPUT -i $EXTNIC -s 1.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 2.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 5.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 7.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 23.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 27.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 31.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 37.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 41.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 42.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 58.0.0.0/7 -j DROP
iptables -A INPUT -i $EXTNIC -s 60.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 69.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 70.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 71.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 72.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 73.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 74.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 75.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 76.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 77.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 78.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 79.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 82.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 83.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 84.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 85.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 86.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 87.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 88.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 89.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 90.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 91.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 92.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 93.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 94.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 95.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 96.0.0.0/4 -j DROP
iptables -A INPUT -i $EXTNIC -s 112.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 113.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 114.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 115.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 116.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 117.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 118.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 119.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 120.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 121.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 122.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 123.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 124.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 125.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 126.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 197.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTNIC -s 220.0.0.0/6 -j DROP

# block nfs udp connections
iptables -A INPUT -i $EXTNIC -d $HOST -p udp --dport nfs -j DROP
# block nfs tcp connections
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --syn --dport nfs -j DROP
iptables -A OUTPUT -o $EXTNIC -p tcp --syn --dport nfs -j DROP

# Ports allowed

# ftp 
## outgoing ftp
### outgoing ftp requests
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport ftp -j ACCEPT
iptables -A INPUT -i $EXTNIC  -d $HOST -p tcp ! --syn --sport ftp --dport 1024: -j ACCEPT
### data channel
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --dport 1024: --sport ftp-data -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --sport 1024: --dport ftp-data -j ACCEPT
### passive mode
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport 1024: -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp ! --syn --dport 1024: --sport 1024: -j ACCEPT

# ssh
## allow client access to remote servers
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport ssh -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp ! --syn --dport 1024: --sport ssh -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 513:1023 --dport ssh -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp ! --syn --dport 513:1023 --sport ssh -j ACCEPT
## allow remote client access to local server
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --sport 1024: --dport ssh -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --dport 1024: --sport ssh -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --sport 513:1023 --dport ssh -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --dport 513:1023 --sport ssh -j ACCEPT

# mail
## accept connections from remote servers
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --sport 1024: --dport smtp -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --sport smtp --dport 1024: -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --sport 1024: --dport smtp -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --sport smtp --dport 1024: -j ACCEPT
## send to remote smtp server
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport smtp -j ACCEPT
iptables -A INPUT  -i $EXTNIC -d $HOST -p tcp ! --syn --sport smtp --dport 1024: -j ACCEPT

# dns
## allow client lookups on other servers
iptables -A OUTPUT -o $EXTNIC -s $HOST -p udp --sport 1024: --dport domain -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p udp --sport domain --dport 1024: -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport domain -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp ! --syn --sport domain --dport 1024: -j ACCEPT
## allow peer-to-peer lookups
iptables -A INPUT -i $EXTNIC -d $HOST -p udp --sport domain --dport domain -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p udp --sport domain --dport domain -j ACCEPT
## allow remote lookups to local server
iptables -A INPUT -i $EXTNIC -d $HOST -p udp --sport 1024: --dport domain -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p udp --sport domain --dport 1024: -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --sport 1024: --dport domain -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --sport domain --dport 1024: -j ACCEPT

# http
## incoming http
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --sport 1024: --dport http -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --sport http --dport 1024: -j ACCEPT
## outgoing http
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport http -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp ! --syn --sport http --dport 1024: -j ACCEPT

# nntp (news)
## outgoing only
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport nntp -j ACCEPT
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp ! --syn --sport nntp --dport 1024: -j ACCEPT

# https
## outgoing only
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport https -j ACCEPT
iptables -A INPUT  -i $EXTNIC -d $HOST -p tcp ! --syn --sport https --dport 1024: -j ACCEPT

# realplayer
## outgoing only
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp --sport 1024: --dport rtsp -j ACCEPT
iptables -A INPUT  -i $EXTNIC -d $HOST -p tcp ! --syn --sport rtsp --dport 1024: -j ACCEPT

# imaps
## incoming only
iptables -A INPUT  -i $EXTNIC -d $HOST -p tcp --sport 1024: --dport imaps -j ACCEPT
iptables -A OUTPUT -o $EXTNIC -s $HOST -p tcp ! --syn --dport 1024: --sport imaps -j ACCEPT

# log any input that doesn't match a rule
iptables -A INPUT -i $EXTNIC -d $HOST -p udp --dport 0:1023 -j LOG
iptables -A INPUT -i $EXTNIC -d $HOST -p tcp --dport 0:1023 -j LOG
