Firewall script 2009 - iptables recent module - flood control - ssh port-knocking - broute force control ================================================================================ Public domain ******************************************************************************** #!/bin/bash #################################################################################################### # Configuration #################################################################################### #################################################################################################### INTIF=eth1 EXTIF=$(route -n | egrep '^0.0.0.0' | sed -e 's,.* ,,') ICMPHIT="10" TCPHIT="50" UDPHIT="70" DEBUG="YES" # Totaly Close IPs CLOSE="$CLOSE 83.170.42.34" CLOSE="$CLOSE 83.170.42.35" # Totaly Close Ports CLOSE_DPORT="$CLOSE_DPORT 135 139 445 " CLOSE_SPORT="$CLOSE_SPORT 135 139 445 " # Totaly Open IPs OPEN="$OPEN 83.170.42.50" OPEN="$OPEN 83.170.42.51" # Trusted External IPs TRUST="$TRUST 178.34.32.78" TRUST="$TRUST 153.27.71.39" # Local Servers LANSERVER="$LANSERVER 83.170.42.9" LANSERVER="$LANSERVER 83.170.42.10 # Local Networks LOCALNET="$LOCALNET 83.170.42.0/24" LOCALNET="$LOCALNET 80.85.71.0/24" # Static Routes route add -net 80.85.14.16/28 gw 80.85.14.11 route add -net 80.85.14.32/27 gw 80.85.14.11 #################################################################################################### # NAT ############################################################################################## #################################################################################################### # NAT table flush iptables -F -t nat iptables -t nat -A POSTROUTING -o eth0 -s 10.20.231.198 -j SNAT --to 83.170.42.9 #################################################################################################### # Functions ######################################################################################## #################################################################################################### load_modules() { /sbin/rmmod ipt_recent > /dev/null 2>&1 /sbin/modprobe ipt_recent ip_list_tot=2048 ip_pkt_list_tot=255 ip_list_hash_size=0 NAT_MODULES=$( find /lib/modules/$(uname -r)/kernel -name '*nat*' |\ grep 'netfilter' |\ sed -e 's,.*/,,' -e 's,\..*,,' ) CON_MODULES=$( find /lib/modules/$(uname -r)/kernel -name '*conntrack*' |\ grep 'netfilter' |\ sed -e 's,.*/,,' -e 's,\..*,,' ) for MODULE in $NAT_MODULES $CON_MODULES; do /sbin/modprobe $MODULE > /dev/null 2>&1 done } find_ext_ip() { IFCS=$(ifconfig | grep $EXTIF | awk '{print $1}') for IF in $IFCS; do IP=$(ifconfig $IF | grep "inet addr" | awk '{print $2}' | sed -e 's,.*:,,') LOCALNET="$LOCALNET $IP" done } start() { echo 'Starting Firewall...' load_modules iptables -F iptables -X iptables -Z iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Totally close for NET in $CLOSE; do iptables -A FORWARD -i $INTIF -s $NET -j DROP iptables -A FORWARD -i $EXTIF -d $NET -j DROP done # Totally close destination ports for PORT in $CLOSE_DPORT; do iptables -A FORWARD -i $INTIF -p tcp --dport $PORT -j DROP iptables -A FORWARD -i $INTIF -p udp --dport $PORT -j DROP iptables -A FORWARD -i $EXTIF -p tcp --dport $PORT -j DROP iptables -A FORWARD -i $EXTIF -p udp --dport $PORT -j DROP done # Totally close source ports for PORT in $CLOSE_SPORT; do iptables -A FORWARD -i $INTIF -p tcp --sport $PORT -j DROP iptables -A FORWARD -i $INTIF -p udp --sport $PORT -j DROP iptables -A FORWARD -i $EXTIF -p tcp --sport $PORT -j DROP iptables -A FORWARD -i $EXTIF -p udp --sport $PORT -j DROP done # Totally open for NET in $OPEN; do iptables -A FORWARD -s $NET -j ACCEPT iptables -A FORWARD -d $NET -j ACCEPT done # Trusted networks for NET in $TRUST; do iptables -A INPUT -i $EXTIF -s $NET -j ACCEPT iptables -A OUTPUT -o $EXTIF -d $NET -j ACCEPT iptables -A FORWARD -i $EXTIF -s $NET -j ACCEPT iptables -A FORWARD -o $EXTIF -d $NET -j ACCEPT done # Local Servers for SERVER in $LANSERVER; do iptables -A FORWARD -o $EXTIF -s $SERVER -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A FORWARD -i $EXTIF -d $SERVER -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i $INTIF -d $SERVER -j ACCEPT iptables -A FORWARD -i $INTIF -s $SERVER -j ACCEPT done # Source Check iptables -N SRC-CHK for NET in $LOCALNET; do iptables -A SRC-CHK -s $NET -j RETURN done if [ "$DEBUG" == "YES" ]; then iptables -A SRC-CHK -j LOG --log-prefix "SRC:CHK:" fi iptables -A SRC-CHK -j DROP # Destination Check iptables -N DST-CHK for NET in $LOCALNET; do iptables -A DST-CHK -d $NET -j RETURN done if [ "$DEBUG" == "YES" ]; then iptables -A DST-CHK -j LOG --log-prefix "DST:CHK:" fi iptables -A DST-CHK -j DROP ################ # INPUT/OUTPUT # ################ # Loopback access iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # ICMP access to firewall from internet if [ "$DEBUG" == "YES" ]; then iptables -A INPUT -i $EXTIF -p icmp --icmp-type echo-request \ -m recent --rcheck --rttl --hitcount 2 --seconds 1 --name ICMP-RECENT-OUTSIDE -j LOG --log-prefix "ICMP:ATK:" fi iptables -A INPUT -i $EXTIF -p icmp --icmp-type echo-request \ -m recent --rcheck --rttl --hitcount 2 --seconds 1 --name ICMP-RECENT-OUTSIDE -j DROP iptables -A INPUT -i $EXTIF -p icmp --icmp-type echo-request \ -m recent --set --name ICMP-RECENT-OUTSIDE -j ACCEPT # SSH access to firewall from internet with port knocking # SSH brute-force prevention from both sides iptables -N KNOCK1 iptables -N KNOCK2 iptables -N KNOCK3 iptables -N BRUTE iptables -A KNOCK1 -m recent --set --name SEENFIRST iptables -A KNOCK1 -m recent --remove --name KNOCKED iptables -A KNOCK1 -j DROP iptables -A KNOCK2 -m recent --rcheck --name SEENFIRST --seconds 5 -j KNOCK3 iptables -A KNOCK2 -m recent --remove --name SEENFIRST iptables -A KNOCK2 -j DROP iptables -A KNOCK3 -m recent --set --name KNOCKED iptables -A KNOCK3 -j DROP if [ "$DEBUG" == "YES" ]; then iptables -A BRUTE -p tcp --dport 22 -m state --state NEW \ -m recent --rcheck --seconds 60 --hitcount 2 --rttl --name SSH-OUTSIDE -j LOG --log-prefix "SSH:OUTSIDE:" fi iptables -A BRUTE -p tcp --dport 22 -m state --state NEW \ -m recent --rcheck --seconds 60 --hitcount 2 --rttl --name SSH-OUTSIDE -j DROP iptables -A BRUTE -p tcp --dport 22 -m state --state NEW \ -m recent --set --name SSH-OUTSIDE -j ACCEPT iptables -A INPUT -i $EXTIF -p tcp --dport 7006 -j KNOCK1 iptables -A INPUT -i $EXTIF -p tcp --dport 5003 -j KNOCK2 iptables -A INPUT -i $EXTIF -p tcp --dport 22 -m state --state NEW -m recent --seconds 10 --rcheck --name KNOCKED -j BRUTE iptables -A INPUT -i $EXTIF -p tcp --dport 22 -m state --state NEW -j DROP # SSH access to firewall for clients with brute-force prevention iptables -A INPUT -i $INTIF -p tcp --dport 22 -m state --state NEW -j BRUTE # Clients Access To Firewall iptables -A INPUT -i $INTIF -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT # Firewall Access To Internet iptables -A OUTPUT -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT # Firewall Access To Clients iptables -A OUTPUT -o $INTIF -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT ########### # FORWARD # ########### # Local access iptables -A FORWARD -i $EXTIF -j DST-CHK # packthayey ke betarafe cache server e local route mishavand # destination e internet darand na local # va pasokh haye in packet ha ba source e internet rooye lan # route mishavand #iptables -A FORWARD -o $INTIF -j DST-CHK #iptables -A FORWARD -i $INTIF -j SRC-CHK iptables -A FORWARD -i $INTIF -o $INTIF -j ACCEPT # ICMP flood control if [ "$DEBUG" == "YES" ]; then iptables -A FORWARD -i $INTIF -p icmp --icmp-type echo-request \ -m recent --rcheck --rttl --hitcount $ICMPHIT --seconds 1 --name ICMP-RECENT-FORWARD -j LOG --log-prefix "ICMP:FLOOD:" fi iptables -A FORWARD -i $INTIF -p icmp --icmp-type echo-request \ -m recent --rcheck --rttl --hitcount $ICMPHIT --seconds 1 --name ICMP-RECENT-FORWARD -j DROP iptables -A FORWARD -i $INTIF -p icmp --icmp-type echo-request \ -m recent --set --name ICMP-RECENT-FORWARD -j ACCEPT # TCP flood control if [ "$DEBUG" == "YES" ]; then iptables -A FORWARD -i $INTIF -p tcp -m state --state NEW \ -m recent --rcheck --rttl --hitcount $TCPHIT --seconds 1 --name TCP-RECENT-FORWARD -j LOG --log-prefix "TCP:FLOOD:" fi iptables -A FORWARD -i $INTIF -p tcp -m state --state NEW \ -m recent --rcheck --rttl --hitcount $TCPHIT --seconds 1 --name TCP-RECENT-FORWARD -j DROP iptables -A FORWARD -i $INTIF -p tcp -m state --state NEW \ -m recent --set --name TCP-RECENT-FORWARD -j ACCEPT # UDP flood control if [ "$DEBUG" == "YES" ]; then iptables -A FORWARD -i $INTIF -p udp -m state --state NEW \ -m recent --rcheck --rttl --hitcount $UDPHIT --seconds 1 --name UDP-RECENT-FORWARD -j LOG --log-prefix "UDP:FLOOD:" fi iptables -A FORWARD -i $INTIF -p udp -m state --state NEW \ -m recent --rcheck --rttl --hitcount $UDPHIT --seconds 1 --name UDP-RECENT-FORWARD -j DROP iptables -A FORWARD -i $INTIF -p udp -m state --state NEW \ -m recent --set --name UDP-RECENT-FORWARD -j ACCEPT # Clients access to internet iptables -A FORWARD -i $INTIF -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A FORWARD -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT # Chiz iptables -A FORWARD -p gre -j ACCEPT } stop() { echo 'Stoping Firewall...' iptables -F iptables -X iptables -Z iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT rmmod ipt_recent > /dev/null 2>&1 } #################################################################################################### # Main ############################################################################################# #################################################################################################### case "$1" in start) start ;; stop) stop ;; restart | reload) stop start ;; *) echo "Usage: $0 {start|stop|restart}" esac ******************************************************************************** _BY: Pejman Moghadam_ _TAG: firewall, iptables, bash-script, bash, port-knocking, recent_ _DATE: 2009-06-07 20:24:27_