# See www.andybev.com for full details of this script #!/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 setting $IPTABLES -P INPUT ACCEPT $IPTABLES -F INPUT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -F OUTPUT $IPTABLES -P FORWARD DROP $IPTABLES -F FORWARD $IPTABLES -t nat -F $IPTABLES -t mangle -F $IPTABLES -t filter -F # Create and flush internet chain # This is used to authenitcate 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 $IPTABLES -t nat -A PREROUTING -i eth0 --destination 10.0.0.0/16 -j ACCEPT # 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 # 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 incoming FROM Internet networks $IPTABLES -t filter -A INPUT -p icmp -i ppp0 --icmp-type 8 -j ACCEPT $IPTABLES -t filter -A INPUT -p ICMP -i ppp0 --icmp-type 11 -j ACCEPT $IPTABLES -t filter -A INPUT -i ppp0 -p tcp --dport 22 -j ACCEPT $IPTABLES -t filter -A INPUT -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t filter -A INPUT -i ppp0 -j DROP # accept NTP time requess # 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 $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 later # The lower the MARK the higher the priority # Default mark is marked at prerouting to catch both # internal and forwarded traffic destined for other machines $IPTABLES -t mangle -A PREROUTING -i ppp0 -j MARK --set-mark 40 # Accept any packets marked 99 here; they will be dropped later # If they are re-marked then they will be allowed through $IPTABLES -t mangle -A FORWARD -m mark --mark 99 -j ACCEPT # http / https $IPTABLES -t mangle -A FORWARD -p tcp --sport 80 -i ppp0 -j MARK --set-mark 30 $IPTABLES -t mangle -A FORWARD -p tcp --dport 80 -o ppp0 -j MARK --set-mark 30 $IPTABLES -t mangle -A FORWARD -p tcp --sport 443 -i ppp0 -j MARK --set-mark 30 $IPTABLES -t mangle -A FORWARD -p tcp --dport 443 -i eth0 -j MARK --set-mark 30 # SSH $IPTABLES -t mangle -A FORWARD -p tcp --sport 22 -i ppp0 -j MARK --set-mark 10 $IPTABLES -t mangle -A FORWARD -p tcp --dport 22 -o ppp0 -j MARK --set-mark 10 # local traffic $IPTABLES -t mangle -A POSTROUTING --source 10.0.0.1 -j MARK --set-mark 1 $IPTABLES -t mangle -A POSTROUTING --destination 10.0.0.1 -j MARK --set-mark 1 # http via squid $IPTABLES -t mangle -A POSTROUTING -p tcp --sport 3128 --source 10.0.0.1 -j MARK --set-mark 30 # DNS requests $IPTABLES -t mangle -A OUTPUT -m udp -p udp --dport 53 -j MARK --set-mark 10 $IPTABLES -t mangle -A OUTPUT -m tcp -p tcp --dport 53 -j MARK --set-mark 10 $IPTABLES -t mangle -A INPUT -m udp -p udp --sport 53 -j MARK --set-mark 10 $IPTABLES -t mangle -A INPUT -m tcp -p tcp --sport 53 -j MARK --set-mark 10 # mark large downloads from squid $IPTABLES -t mangle -A POSTROUTING -p tcp --sport 3128 --source 10.0.0.1 -m connbytes --connbytes 504857: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 40 # IMAP $IPTABLES -t mangle -A FORWARD -p tcp --sport 993 -i ppp0 -j MARK --set-mark 30 # imap $IPTABLES -t mangle -A FORWARD -p tcp --dport 993 -o ppp0 -j MARK --set-mark 30 # imap # Mark large downloads (> 500kb) $IPTABLES -t mangle -A FORWARD -m connbytes --connbytes 504857: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 40 # To speed up downloads while an upload is going on, put short ACK # packets in the interactive 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 10 # 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 60 $IPTABLES -t mangle -A FORWARD -i ppp0 -p tcp --sport 1024: \ -m set --set p2p dst -j MARK --set-mark 60 $IPTABLES -t mangle -A FORWARD -o ppp0 -p udp --dport 1024: \ -m set --set p2p src -j MARK --set-mark 60 $IPTABLES -t mangle -A FORWARD -i ppp0 -p udp --sport 1024: \ -m set --set p2p dst -j MARK --set-mark 60 # Now that we've got to the forward filter, drop all packets # marked 99 - these are unknown users. We can't drop them earlier # as there's no filter table $IPTABLES -t filter -A FORWARD -m mark --mark 99 -j DROP # Do the same for the INPUT chain so that they also can't get to squid # but allow them to the webserver to signup $IPTABLES -t filter -A INPUT -p tcp --dport 80 -j ACCEPT $IPTABLES -t filter -A INPUT -m mark --mark 99 -j DROP ###### 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 $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 ################################ # Force all traffic via web proxy to speed up some traffic $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128 # Bocks 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 INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t mangle -A OUTPUT -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