#!/bin/bash

# eth0 is connected to the internet.
# eth1 is connected to a private subnet.
INET_IFACE=eth0
PRIVATE_IFACE=eth1
LOCAL_IFACE=lo

SUBNET_PRIVATE=192.168.4.0/255.255.255.0
PRIVATE=192.168.4.5/255.255.255.0

# Loopback address
LOOP=127.0.0.1

# Delete old iptables rules
# and temporarily block all traffic.
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -F

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

# Allow local loopback from local interface and deny from any other interface
iptables -A INPUT -i $LOCAL_IFACE -s $LOOP -j ACCEPT
iptables -A INPUT -i $LOCAL_IFACE -d $LOOP -j ACCEPT

iptables -A INPUT -j LOG -i ! $LOCAL_IFACE -s $LOOP
iptables -A INPUT -j DROP -i ! $LOCAL_IFACE -s $LOOP

iptables -A OUTPUT -o $LOCAL_IFACE -j ACCEPT

# Allow packets from internal interfaces
iptables -A INPUT -i $PRIVATE_IFACE -s $SUBNET_PRIVATE -j ACCEPT
iptables -A FORWARD -i $PRIVATE_IFACE -s $SUBNET_PRIVATE -j ACCEPT
iptables -A OUTPUT -o $PRIVATE_IFACE -j ACCEPT

# Incoming pings
iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type any -j ACCEPT

# Allow services such as www and ssh (can be disabled)
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -p TCP --dport 3306 -j ACCEPT

# Allow incoming OpenVPN packets
# Duplicate the line below for each
# OpenVPN tunnel, changing --dport n
# to match the OpenVPN UDP port.
#
# In OpenVPN, the port number is
# controlled by the --port n option.
# If you put this option in the config
# file, you can remove the leading '--'
#
# If you taking the stateful firewall
# approach (see the OpenVPN HOWTO),
# then comment out the line below.

iptables -A INPUT -p tcp --dport 1194 -j ACCEPT
iptables -A FORWARD -p tcp --dport 1194 -i $INET_IFACE -o $PRIVATE_IFACE -j ACCEPT

# Allow packets from TUN/TAP devices.
# When OpenVPN is run in a secure mode,
# it will authenticate packets prior
# to their arriving on a tun or tap
# interface.  Therefore, it is not
# necessary to add any filters here,
# unless you want to restrict the
# type of packets which can flow over
# the tunnel.

iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT
iptables -A FORWARD -o tap+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT

# Check source address validity on packets going out to internet
iptables -A FORWARD -s ! $SUBNET_PRIVATE -i $PRIVATE_IFACE -o $INET_IFACE -j DROP

# Allow connection to the internet
iptables -A OUTPUT -o $INET_IFACE -j ACCEPT
#iptables -A FORWARD -o $INET_IFACE -j ACCEPT

# Keep state of connections from local machine and private subnets
iptables -A OUTPUT -m state --state NEW -o $INET_IFACE -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o $INET_IFACE -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Masquerade local subnet
iptables -t nat -A POSTROUTING -s $PRIVATE -o $INET_IFACE -j MASQUERADE

# Prevent external packets from using loopback addr
iptables -A INPUT -i $INET_IFACE -s $LOOP -j DROP
iptables -A FORWARD -i $INET_IFACE -s $LOOP -j DROP
iptables -A INPUT -i $INET_IFACE -d $LOOP -j DROP
iptables -A FORWARD -i $INET_IFACE -d $LOOP -j DROP

# Block anything coming from the Internet 
iptables -A FORWARD -i $INET_IFACE -j DROP
iptables -A INPUT -i $INET_IFACE -j DROP

# Block outgoing NetBios.
# This will not affect any NetBios
# traffic that flows over the VPN tunnel, but it will stop
# local windows machines from broadcasting themselves to
# the internet.
iptables -A FORWARD -p tcp --sport 137:139 -o $INET_IFACE -j DROP
iptables -A FORWARD -p udp --sport 137:139 -o $INET_IFACE -j DROP
iptables -A OUTPUT -p tcp --sport 137:139 -o $INET_IFACE -j DROP
iptables -A OUTPUT -p udp --sport 137:139 -o $INET_IFACE -j DROP

