#!/bin/bash

IPTABLES=/sbin/iptables

# Enable FTP connection tracking
modprobe nf_conntrack_ftp

# Enable Internet connection sharing
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

# clear out existing rules and set policies
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -t filter -F

# Allow all traffic to the loopback device
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

# Create and flush internet chain
# This is used to authenticate users who have already signed up
$IPTABLES -N internet -t nat 2>/dev/null
$IPTABLES -F internet -t nat


# Create ipset for storing ip addresses of p2p users
# Set timeout to 60 seconds meaning their address will
# be cleared after 60 seconds of inactivity of p2p
#
# The current IP addresses in the IP Set can be monitored
# with the 'ipset -L' comand from the bash prompt
#
ipset -X p2p
ipset -N p2p iptree --timeout 60

# Accept all local traffic - **is this needed** ??
#iptables -t nat -A PREROUTING -i eth0 --destination 10.0.0.0/16 -j ACCEPT

# if the mark is zero it means that the packet does not belong to any existing connection
iptables -t mangle -A PREROUTING -i eth0 -m state --state NEW \
         -m statistic --mode nth --every 2 --packet 0 -j CONNMARK --set-mark 0x20000
iptables -t mangle -A PREROUTING -i eth0 -m state --state NEW \
         -m statistic --mode nth --every 2 --packet 1 -j CONNMARK --set-mark 0x10000

#iptables -t mangle -A OUTPUT -o ppp0 -m conntrack --ctstate NEW \
#         -m statistic --mode nth --every 2 --packet 0 -j CONNMARK --set-mark 0x20000
#iptables -t mangle -A OUTPUT -o ppp0 -m conntrack --ctstate NEW \
#         -m statistic --mode nth --every 2 --packet 1 -j CONNMARK --set-mark 0x10000

# get the mark on the packet that belongs to an existing connection
iptables -t mangle -A PREROUTING -i eth0 -j CONNMARK --restore-mark
iptables -t mangle -A FORWARD -o eth0 -j CONNMARK --restore-mark
#iptables -t mangle -A OUTPUT -o ppp0 -j CONNMARK --restore-mark
#iptables -t mangle -A INPUT -i ppp0 -j CONNMARK --restore-mark
#iptables -t mangle -A INPUT -i ppp0 -j LOG
#iptables -t mangle -A PREROUTING -i ppp0 -j CONNMARK --restore-mark
#iptables -t mangle -A PREROUTING -i eth1 -j CONNMARK --restore-mark

# Send all traffic via internet chain
# At the prerouting NAT stage this will DNAT them to the local
# webserver for them to signup if they aren't authorised
# Packets for unauthorised users are marked for dropping later
iptables -t nat -A PREROUTING -j internet

###### INTERNET CHAIN ##########
# Allow authorised hosts in, redirect all others to login webserver
# Add known users to the NAT table to stop their dest being rewritten
# Ignore MAC address with a * - these users are blocked
awk 'BEGIN { FS="\t"; } { if ($5 !~ /\*/) { system("iptables -t nat -A internet -m mac --mac-source "$5" -j RETURN"); } }' /var/lib/users
# MAC address not found. Mark the packet 99. Will be dropped later.
iptables -t nat -A internet -j MARK --set-mark 99
# Redirects web requests from Unauthorised users to logon Web Page
iptables -t nat -A internet -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
################################

# Drop invalid packets
iptables -t mangle -A PREROUTING -p tcp -i eth0 -m conntrack --ctstate INVALID -j DROP  # drop invalid connections

# Accept ping and ssh coming in to local server from any interface
iptables -t filter -A INPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -t filter -A INPUT -p ICMP --icmp-type 11 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Accept traffic to Squid, DNS and Apache from local network
# These will not be MARKed
iptables -t filter -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -p udp --dport 69 -j ACCEPT # TFTPD
# NFS port numbers. See http://wiki.debian.org/SecuringNFS
iptables -t filter -A INPUT -i eth0 -p udp --dport 111 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -p tcp --dport 111 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -p udp --dport 2049 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -p tcp --dport 2049 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -p udp --dport 32765:32769 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -p tcp --dport 32765:32769 -j ACCEPT
#iptables -t filter -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT


iptables -t filter -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
# But do not allow anything marked 99 as far as Squid
iptables -t filter -A INPUT -m mark --mark 99 -j DROP
iptables -t filter -A INPUT -i eth0 -p tcp --dport 3128 -j ACCEPT

# Drop any marked 99 packets. These are unauthorised users
iptables -t filter -A FORWARD -m mark --mark 99 -j DROP

# accept NTP time requests
# we allow these for any PC regardless of whether they are logged
# on to the network because the Internet Suite PCs use NTP to set
# their clocks BEFORE they are authorised to use the Internet
# These packets will not be MARKed
iptables -t filter -A FORWARD -p UDP --dport 123 -j ACCEPT

# Stop DoS attacks on DNS-BL
iptables -t filter -A FORWARD -i eth0 --destination 216.168.28.50 -j DROP

# Do not allow outgoing internet SMTP connections
# This is essential to stop the many viruses that sit on
# people's computers and attempt to send spam (using bandwidth up)
# This can be changed on a per user basis if required as per the example
iptables -t filter -A FORWARD -p tcp -i eth0 --dport 25 -m mac --mac-source 00:19:D1:02:1B:02 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 --dport 25 -j DROP


############ MARK traffic for shaping ###################

# Ignore '99' packets. This will be dropped later
iptables -t mangle -A FORWARD -m mark --mark 99 -j ACCEPT
# Set default mark for forwarded packets
iptables -t mangle -A FORWARD -j MARK --set-mark 0x40/0xFFFF

# MARK locally generated traffic as appropriate. This applies only to DNS requests
# Squid should be set to use the qos_flows parameter to mark non-cache hits
iptables -t mangle -A OUTPUT -m udp -p udp --dport 53 -o ppp0 \
	-j MARK --set-mark 0x10/0xFFFF
iptables -t mangle -A OUTPUT -m udp -p udp --dport 53 -o eth1 \
	-j MARK --set-mark 0x10/0xFFFF
# DNS replies to requests (local traffic)
iptables -t mangle -A OUTPUT -m udp -p udp --sport 53 -o eth0 \
	-j MARK --set-mark 0x10/0xFFFF

iptables -t mangle -A FORWARD -p tcp --sport 80 -i ppp0 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --sport 80 -i eth1 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 80 -o ppp0 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 80 -o eth1 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp -m mark --mark 30/0xFFFF \
	-m connbytes --connbytes 1048576: --connbytes-dir both \
	--connbytes-mode bytes -j MARK --set-mark 0x50/0xFFFF


#iptables -t mangle -A OUTPUT -p tcp -m mark --mark 30/0xFFFF \
#	-m connbytes --connbytes 1048576: --connbytes-dir both \
#	--connbytes-mode bytes -j MARK --set-mark 50/0xFFFF

# MARK forwarded traffic
# SSH
iptables -t mangle -A FORWARD -p tcp --sport 22 -i ppp0 \
	-j MARK --set-mark 0x10/0xFFFF
iptables -t mangle -A FORWARD -p tcp --sport 22 -i eth1 \
	-j MARK --set-mark 0x10/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 22 -o ppp0 \
	-j MARK --set-mark 0x10/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 22 -o eth1 \
	-j MARK --set-mark 0x10/0xFFFF
# IMAP
iptables -t mangle -A FORWARD -p tcp --sport 993 -i ppp0 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --sport 993 -i eth1 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 993 -o ppp0 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 993 -o eth1 \
	-j MARK --set-mark 0x30/0xFFFF
# HTTPS
iptables -t mangle -A FORWARD -p tcp --sport 443 -i ppp0 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --sport 443 -i eth1 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 443 -o ppp0 \
	-j MARK --set-mark 0x30/0xFFFF
iptables -t mangle -A FORWARD -p tcp --dport 443 -o eth1 \
	-j MARK --set-mark 0x30/0xFFFF
# Mark large downloads (> 500kb)
iptables -t mangle -A FORWARD -m connbytes --connbytes 1048576: \
	--connbytes-dir both --connbytes-mode bytes \
	-j MARK --set-mark 0x50/0xFFFF
# To speed up downloads while an upload is going on, put short ACK
# packets in their own class:
iptables -t mangle -A FORWARD -p tcp -m tcp \
	--tcp-flags FIN,SYN,RST,ACK ACK -m length --length :64 \
	-j MARK --set-mark 0x20/0xFFFF

# The next few lines pick out P2P packets
# These are characterised by lots of connections to high port numbers
# First look for the packets and log to IPSET p2p
# Detects traffic from users using >8 ports above 1024
# and adds the source address to the P2P list.
iptables -t mangle -A FORWARD -o ppp0 -p tcp --dport 1024: \
	-m connlimit --connlimit-above 8 -j SET --add-set p2p src 
# Detects traffic from users using >4 UDP ports above 1024
# and adds the source address to the P2P list.
iptables -t mangle -A FORWARD -o ppp0 -p udp --dport 1024: \
	-m connlimit --connlimit-above 4 -j SET --add-set p2p src 
# Detects traffic to users using >8 ports above 1024
# and adds the dst address (ie the user) to the P2P list.
iptables -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024: \
	-m connlimit --connlimit-above 8 -j SET --add-set p2p dst
# Detects traffic to users using >4 UDP ports above 1024
# and adds the dst address (ie the user) to the P2P list.
iptables -t mangle -A FORWARD -i ppp0 -p udp --sport 1024: \
	-m connlimit --connlimit-above 4 -j SET --add-set p2p dst
# Once a user is in the p2p IPSET, these rules mark their packets
# Any packets above 1024 are marked as the lowest priority
iptables -t mangle -A FORWARD -o ppp0 -p tcp --dport 1024: \
	-m set --set p2p src -j MARK --set-mark 0x666/0xFFFF
iptables -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024: \
	-m set --set p2p dst -j MARK --set-mark 0x666/0xFFFF
iptables -t mangle -A FORWARD -o ppp0 -p udp --dport 1024: \
	-m set --set p2p src -j MARK --set-mark 0x666/0xFFFF
iptables -t mangle -A FORWARD -i ppp0 -p udp --sport 1024: \
	-m set --set p2p dst -j MARK --set-mark 0x666/0xFFFF

iptables -t mangle -A FORWARD -o eth1 -p tcp --dport 1024: \
	-m connlimit --connlimit-above 8 -j SET --add-set p2p src 
# Detects traffic from users using >4 UDP ports above 1024
# and adds the source address to the P2P list.
iptables -t mangle -A FORWARD -o eth1 -p udp --dport 1024: \
	-m connlimit --connlimit-above 4 -j SET --add-set p2p src 
# Detects traffic to users using >8 ports above 1024
# and adds the dst address (ie the user) to the P2P list.
iptables -t mangle -A FORWARD -i eth1 -p tcp --sport 1024: \
	-m connlimit --connlimit-above 8 -j SET --add-set p2p dst
# Detects traffic to users using >4 UDP ports above 1024
# and adds the dst address (ie the user) to the P2P list.
iptables -t mangle -A FORWARD -i eth1 -p udp --sport 1024: \
	-m connlimit --connlimit-above 4 -j SET --add-set p2p dst
# Once a user is in the p2p IPSET, these rules mark their packets
# Any packets above 1024 are marked as the lowest priority
iptables -t mangle -A FORWARD -o eth1 -p tcp --dport 1024: \
	-m set --set p2p src -j MARK --set-mark 0x666/0xFFFF
iptables -t mangle -A FORWARD -i eth1 -p tcp --sport 1024: \
	-m set --set p2p dst -j MARK --set-mark 0x666/0xFFFF
iptables -t mangle -A FORWARD -o eth1 -p udp --dport 1024: \
	-m set --set p2p src -j MARK --set-mark 0x666/0xFFFF
iptables -t mangle -A FORWARD -i eth1 -p udp --sport 1024: \
	-m set --set p2p dst -j MARK --set-mark 0x666/0xFFFF

# Force all traffic via web proxy to speed up some traffic
#iptables -t nat -A PREROUTING -i eth0 -p tcp \
#	--dport 80 ! -d 10.0.0.1 -j REDIRECT --to-port 3128

# Blocks outgoing traffic from local host on unused ports.
# Allow known ports out
iptables -t mangle -A OUTPUT -p tcp --dport 80 -o ppp0 -j ACCEPT  # Accept web proxy traffic
iptables -t mangle -A OUTPUT -p tcp --dport 25 -o ppp0 -j ACCEPT # Accept outgoing mail 
iptables -t mangle -A OUTPUT -p tcp --dport 21 -o ppp0 -j ACCEPT # Accept outgoing ftp
iptables -t mangle -A OUTPUT -p tcp --dport 22 -o ppp0 -j ACCEPT # Accept outgoing ssh
iptables -t mangle -A OUTPUT -p tcp --dport 25 -o ppp0 -j ACCEPT # Accept outgoing mail
iptables -t mangle -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t mangle -A OUTPUT -o ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t mangle -A OUTPUT -p icmp -o ppp0 --icmp-type 8 -j ACCEPT #Accept ping commamnds
iptables -t mangle -A OUTPUT -p ICMP -o ppp0 --icmp-type 11 -j ACCEPT #Accept ping commands
iptables -t mangle -A OUTPUT -m udp -p udp --dport 53 -j ACCEPT   # DNS
iptables -t mangle -A OUTPUT -o ppp0 -j DROP # Drops all other outputs from the local machine


# Enable Internet connection sharing
$IPTABLES -A FORWARD -i ppp0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i eth0 -o ppp0 -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
$IPTABLES -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.10.2


ifconfig eth1 192.168.10.2 up
ip route flush table T1
ip route add table T1 default dev ppp0 via 89.145.254.75
ip route flush table T2
ip route add table T2 default dev eth1 via 192.168.10.1

ip rule del from all fwmark 0x10000/0xF0000 2>/dev/null
ip rule del from all fwmark 0x20000/0xF0000 2>/dev/null

ip rule add fwmark 0x10000/0xF0000 table T1
ip rule add fwmark 0x20000/0xF0000 table T2

ip route flush cache

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

