--- 2.0/iptables	2013-02-22 15:07:04.000000000 -0700
+++ 2.1/iptables	2014-12-26 19:44:10.000000000 -0700
@@ -1,15 +1,37 @@
 #!/bin/sh
+#VERSION=2.1
+
 # iptables, by Technion
 # $Id: iptables,v 1.31 2002/08/01 04:50:25 technion Exp $
 # chkconfig: 2345 08 80
 # description: Script for setting IPTABLES rules
 # processname: iptables
 
-#VERSION=2
+# modified for use with a DirectAdmin server
 
-BLOCK_LIST=/root/blocked_ips.txt
+ALLOW_PING=1
 
+SSHD_PORT=22
+#sets ssshd port to the correct value, in case you forgot to change it and are using something else.
+if [ "${SSHD_PORT}" = "22" ] && [ -s /etc/ssh/sshd_config ] && [ `grep -c '^Port ' /etc/ssh/sshd_config` -gt 0 ]; then
+	SSHD_PORT=`grep '^Port ' /etc/ssh/sshd_config | cut -d\  -f2`
+	echo "sshd port set to ${SSHD_PORT}";
+fi
 
+DA_PORT=2222
+DA_PORT_2=0
+if [ "${DA_PORT}" = "2222" ] && [ "`/usr/local/directadmin/directadmin c | grep -c '^port='`" -gt 0 ]; then
+	DA_PORT=`/usr/local/directadmin/directadmin c | grep '^port=' | cut -d= -f2`
+fi
+if [ "${DA_PORT_2}" = "0" ] && [ "`/usr/local/directadmin/directadmin c | grep -c '^ssl_port='`" -gt 0 ]; then
+	DA_PORT_2=`/usr/local/directadmin/directadmin c | grep '^ssl_port=' | cut -d= -f2`
+fi
+
+BLOCK_LIST=/root/blocked_ips.txt
+EXEMPT_LIST=/root/exempt_ips.txt
+IP_WHITELIST=/usr/local/directadmin/data/admin/ip_whitelist
+BLOCK_CHAIN=blocked_ips
+ALLOW_CHAIN=allowed_ips
 
 # Is this script to be run on Red Hat Linux?  If not, set to "NO"
 REDHAT="YES"
@@ -149,6 +171,37 @@
 #Kill connections to the local interface from the outside world.
 $IPTABLES -A INPUT -d 127.0.0.0/8 -j REJECT
 
+
+ensure_chain()
+{
+	if [ "$1" = "" ]; then
+		echo "blank chain";
+		return;
+	fi
+
+	$IPTABLES -L ${1} 2>/dev/null;
+	CRET=$?
+	if [ "${CRET}" -eq 0 ]; then
+		$IPTABLES -F ${1}
+	else
+		$IPTABLES -N ${1}
+	fi
+	$IPTABLES -t filter -A INPUT -j ${1}
+}
+
+ensure_chain ${ALLOW_CHAIN}
+ensure_chain ${BLOCK_CHAIN}
+
+w()
+{
+	if [ "$1" = "" ]; then
+		echo "whitelisting blank value.";
+		return;
+	fi
+
+	$IPTABLES -A ${ALLOW_CHAIN} -s $1 -j ACCEPT
+}
+
 b()
 {
 	if [ "$1" = "" ]; then
@@ -156,12 +209,27 @@
 		return;
 	fi
 
-	$IPTABLES -A INPUT -s $1 -j DROP
+	$IPTABLES -A ${BLOCK_CHAIN} -s $1 -j DROP
 }
 
+if [ -s ${EXEMPT_LIST} ]; then
+	for i in `cat ${EXEMPT_LIST} | cut -d= -f1`; do
+	{
+		w $i
+	};
+	done;
+fi
+
+if [ -s ${IP_WHITELIST} ]; then
+	for i in `cat ${IP_WHITELIST} | cut -d= -f1`; do
+	{
+		w $i
+	};
+	done;
+fi
 
-if [ -s $BLOCK_LIST ]; then
-	for i in `cat $BLOCK_LIST | cut -d= -f1`; do
+if [ -s ${BLOCK_LIST} ]; then
+	for i in `cat ${BLOCK_LIST} | cut -d= -f1`; do
 	{
 		b $i
 	};
@@ -169,18 +237,55 @@
 fi
 
 
+###########################################################################################################
+# Manual Blocking
+# example: to block 1.2.3.4
+# b 1.2.3.4
+#
+# example: to bloc 1.2.x.x  (entire range starting with 1.2.)
+# b 1.2.0.0/16
+#
+# example: whitelist 1.2.3.4
+# w 1.2.3.4
+#
+# because the ALLOW_CHAIN chain is loaded before the BLOCKED_CHAIN, the order of w vs b does not matter.
+# any IP in ALLOW_CHAIN will have priority over BLOCKED_CHAIN.
 
-#Manual Blocking
-#examples, block 1.2.3.4
+#w 1.2.3.4
 #b 1.2.3.4
 
-#blck 1.2.x.x  (entire range starting with 1.2.)
-#b 1.2.0.0/16
 
 
 
-#drop all ICMP
-$IPTABLES -A INPUT -p icmp -j DROP
+
+###########################################################################################################
+# Rate limiting funciton to open a rate limited port
+rate_limit()
+{
+	RPORT=$1
+	RLIM=$2
+	RBURST=$3
+
+	echo "rate limit port $RPORT limit of $RLIM with burst of $RBURST";
+
+	$IPTABLES -A INPUT -p tcp --dport $RPORT --syn -m limit --limit $RLIM --limit-burst $RBURST -j ACCEPT
+	$IPTABLES -A INPUT -p tcp --dport $RPORT --syn -j DROP
+	$IPTABLES -A INPUT -p tcp --dport $RPORT -j ACCEPT
+}
+
+###########################################################################################################
+# ICMP
+#
+
+if [ "${ALLOW_PING}" = "0" ]; then
+	#drop all ICMP (ping and traceroute)
+	$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j DROP
+	$IPTABLES -A OUTPUT -p icmp --icmp-type echo-reply -j DROP
+else
+	#allow all ICMP (ping and traceroute)
+	$IPTABLES -A INPUT -p icmp -j LOG --log-prefix "Recieved packet: ICMP "
+	$IPTABLES -A INPUT -p icmp -j ACCEPT
+fi
 
 ##Allow established connections
 #Unlike ipchains, we don't have to go through the business of allowing
@@ -188,53 +293,90 @@
 
 $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 
+##########################################################################################################
+
 #From here on, we're dealing with connection attempts.
 #The -m limit is a DoS protection on connects
 #First we allow a certain amount of connections per second
 #DROP the rest (so we don't DoS ourself with rejections)
 #We don't limit normal packets (!syn) by allowing the rest
 ##Basic services.  Uncomment to allow in.
+
+#########################
 # ftp-data
 $IPTABLES -A INPUT -p tcp  --dport 20 -j ACCEPT
+
+#########################
 # ftp
 $IPTABLES -A INPUT -p tcp  --dport 21 -j ACCEPT
-# ssh 
+
+#########################
+# sshd
 $IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT
-#telnet
-#$IPTABLES -A INPUT -p tcp --dport 23 -j ACCEPT
-#DirectAdmin
+# accept 22 anyway, plus anything else its actually set to
+if [ "${SSHD_PORT}" != "22" ]; then
+	$IPTABLES -A INPUT -p tcp --dport ${SSHD_PORT} -j ACCEPT
+fi
+
+#########################
+# Telnet
+# $IPTABLES -A INPUT -p tcp --dport 23 -j ACCEPT
+
+#########################
+# DirectAdmin
 $IPTABLES -A INPUT -p tcp --dport 2222 -j ACCEPT
+if [ "${DA_PORT}" != "2222" ]; then
+	$IPTABLES -A INPUT -p tcp --dport ${DA_PORT} -j ACCEPT
+fi
+if [ "${DA_PORT_2}" != "0" ]; then
+	$IPTABLES -A INPUT -p tcp --dport ${DA_PORT_2} -j ACCEPT
+fi
 
-# smtp  One per second limt -burst rate of ten
-$IPTABLES -A INPUT -p tcp --dport 25 --syn -m limit --limit 1/s \
-        --limit-burst 10 -j ACCEPT 
-$IPTABLES -A INPUT -p tcp --dport 25 --syn -j DROP 
-$IPTABLES -A INPUT -p tcp --dport 25 -j ACCEPT
-$IPTABLES -A INPUT -p tcp --dport 465 -j ACCEPT
-$IPTABLES -A INPUT -p tcp --dport 587 -j ACCEPT
+#########################
+# SMTP  10 per minute, -burst rate of 20
+rate_limit 25 10/m 20
+rate_limit 465 10/m 20
+#OR
+#$IPTABLES -A INPUT -p tcp --dport 25 -j ACCEPT
+#$IPTABLES -A INPUT -p tcp --dport 465 -j ACCEPT
 
+#dont rate limit port 587
+$IPTABLES -A INPUT -p tcp --dport 587 -j ACCEPT
 
+#########################
 # DNS   
 $IPTABLES -A INPUT -p tcp --dport 53 -j ACCEPT
 $IPTABLES -A INPUT -p udp --dport 53 -j ACCEPT
-# http 
+
+#########################
+# http / apache / nginx / https
 $IPTABLES -A INPUT -p tcp --dport 80 -j ACCEPT
-# POP-3
+$IPTABLES -A INPUT -p tcp --dport 443 -j ACCEPT
+
+#########################
+# POP3 / IMAP / POP3S / IMAPS
 $IPTABLES -A INPUT -p tcp --dport 110 -j ACCEPT
 $IPTABLES -A INPUT -p tcp --dport 995 -j ACCEPT
-# identd
-$IPTABLES -A INPUT -p tcp --dport 113 -j ACCEPT
-#imapd
 $IPTABLES -A INPUT -p tcp --dport 143 -j ACCEPT
 $IPTABLES -A INPUT -p tcp --dport 993 -j ACCEPT
-# https
-$IPTABLES -A INPUT -p tcp --dport 443 -j ACCEPT
+
+#########################
+# identd
+$IPTABLES -A INPUT -p tcp --dport 113 -j ACCEPT
+
+#########################
 # mysql
 $IPTABLES -A INPUT -p tcp --dport 3306 -j ACCEPT
 $IPTABLES -A INPUT -p udp --dport 3306 -j ACCEPT
 
-#
-##Some ports should be denied and logged.
+
+
+
+
+##########################################################################################################
+# Logging
+# Some ports should be denied and logged.
+
 $IPTABLES -A INPUT -p tcp --dport 1433 -m limit -j LOG \
                           --log-prefix "Firewalled packet: MSSQL " 
 
@@ -304,23 +446,27 @@
 
 
 
+##########################################################################################################
+##########################################################################################################
+# OUTPUT packets
 
-#OUTPUT packets:
-#Drop irc packets
+#########################
+# Drop IRC packets
 $IPTABLES -A OUTPUT -p tcp --destination-port 6660:6669 -j DROP
 $IPTABLES -A OUTPUT -p tcp --destination-port 7000 -j DROP
 
-#SMTP output, only allow mail to send remotely.
+#########################
+# SMTP output, only allow mail to send remotely.
 $IPTABLES -A OUTPUT -m owner --uid-owner mail -p tcp --dport 25 -j ACCEPT
 $IPTABLES -A OUTPUT -m owner --uid-owner root -p tcp --dport 25 -j ACCEPT
 $IPTABLES -A OUTPUT -p tcp -d 127.0.0.1 --dport 25 -j ACCEPT
 $IPTABLES -A OUTPUT -p tcp --dport 25 -j REJECT
 
-
-#Accept it anyway if it's only output
+#########################
+# Accept it anyway if it's only output
 $IPTABLES -A OUTPUT -j ACCEPT
 
-#Masquerade internal connections going out.
+# Masquerade internal connections going out.
 #$IPTABLES -A POSTROUTING -t nat -o $EXTERNALIF -j MASQUERADE
 
 
