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