Adaptive firewall
Posted: Mon Jun 16, 2008 5:24 pm
Well, it's not a question, but a solution 
My firewall
If you feel like it will lead to a DoS, change the target of this line:
to (random or n-th match) + DROP
Also, for those who really hate to be probed - use TARPIT or MIRROR targets
My firewall
Code: Select all
#!/bin/bash
/sbin/modprobe ipt_recent ip_list_tot=1000
ipt="/usr/local/sbin/iptables"
ips="/usr/local/sbin/ipset"
for TABLE in filter nat mangle; do
$ipt -F -t $TABLE
$ipt -X -t $TABLE
$ipt -Z -t $TABLE
done
$ips -F
$ips -X
if [ "$1" == "stop" ]
then
echo
echo "Stopping firewall..."
echo
exit
fi
# White IP list
$ips -N WL iphash
$ips -A WL 127.0.0.1
$ips -A WL 90.90.0.1
# White nets list
$ips -N WLN nethash
$ips -A WLN 90.91.0.0/24
### ADAPTIVE TOTAL DROP ###
$ipt -A INPUT -m recent --name banned-hosts --update --seconds 36000 -j DROP
$ipt -N BANNED
$ipt -A BANNED -m limit --limit 1/s --limit-burst 1 -j LOG
$ipt -A BANNED -m recent --name banned-hosts --set -j RETURN
$ipt -N ADAPT
$ipt -A ADAPT -m limit --limit 1/s --limit-burst 1 -j LOG
$ipt -A ADAPT -m recent --hitcount 2 --name watch-hosts --update --seconds 180 -j BANNED
$ipt -A ADAPT -m recent --name watch-hosts --set -j RETURN
### MALFORMED PACKETS ###
# Smurf attack
$ipt -A INPUT -p icmp -d 0.0.0.255/0.0.0.255 -j DROP
# Invalid tcp packets
$ipt -A INPUT -p tcp --tcp-option 128 -j DROP
$ipt -A INPUT -p tcp --tcp-option 64 -j DROP
# Malformed xmas packets
$ipt -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# Malformed null packets
$ipt -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# New tcp connections must be SYN packets!
$ipt -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# others
$ipt -A INPUT -m state --state INVALID -j DROP
# Local IP filter
$ipt -t mangle -A PREROUTING -i eth+ -s 172.16.0.0/16 -j DROP
$ipt -t mangle -A PREROUTING -i eth+ -d 172.16.0.0/16 -j DROP
$ipt -t mangle -A PREROUTING -i eth+ -d 192.168.0.0/16 -j DROP
$ipt -t mangle -A PREROUTING -i eth+ -s 192.168.0.0/16 -j DROP
$ipt -t mangle -A PREROUTING -i eth+ -s 10.0.0.0/8 -j DROP
$ipt -t mangle -A PREROUTING -i eth+ -d 10.0.0.0/8 -j DROP
$ipt -t mangle -A PREROUTING -i ! lo -s 127.0.0.0/8 -j DROP
# Block timestamp
$ipt -A INPUT -p icmp --icmp-type timestamp-request -j DROP
$ipt -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP
# Always allow VPN users
$ipt -A INPUT -i ppp+ -j ACCEPT
$ipt -A OUTPUT -o ppp+ -j ACCEPT
# Always allow localhost
$ipt -A INPUT -i lo -j ACCEPT
# Port scan detection
$ipt -N PSD
$ipt -A INPUT -m recent --name PSD --update --seconds 60 -j DROP
$ipt -A INPUT -m psd --psd-weight-threshold 10 --psd-delay-threshold 200 -j PSD
$ipt -A PSD -m set --set WL src -j RETURN
$ipt -A PSD -m recent --name PSD --set -j ADAPT
$ipt -A PSD -j DROP
# Syn-flood protection
$ipt -N syn-flood
$ipt -A INPUT -p tcp --syn -j syn-flood
$ipt -A syn-flood -m set --set WL src -j RETURN
$ipt -A syn-flood -m recent --name syn-flood --update --seconds 60 -j DROP
$ipt -A syn-flood -m hashlimit --hashlimit 1/s --hashlimit-burst 50 --hashlimit-mode srcip --hashlimit-name syn-flood -j RETURN
$ipt -A syn-flood -m recent --name syn-flood --set -j ADAPT
$ipt -A syn-flood -j DROP
# Furtive port scanner
$ipt -N port-scan
$ipt -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j port-scan
$ipt -A port-scan -m recent --name port-scan --update --seconds 60 -j DROP
$ipt -A port-scan -m hashlimit --hashlimit 1/s --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name port-scan -j RETURN
$ipt -A port-scan -m recent --name port-scan --set -j ADAPT
$ipt -A port-scan -j DROP
# Ping of death
$ipt -N PoD
$ipt -A INPUT -p icmp --icmp-type echo-request -j PoD
$ipt -A PoD -m set --set WL src -j RETURN
$ipt -A PoD -m set --set WLN src -m limit --limit 50/s --limit-burst 60 -j RETURN
$ipt -A PoD -m recent --name PoD --update --seconds 60 -j DROP
$ipt -A PoD -m length --length 128: -m hashlimit --hashlimit 1/s --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-name PoD -j RETURN
$ipt -A PoD -m hashlimit --hashlimit 5/s --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-name PoD -j RETURN
$ipt -A PoD -m recent --name PoD --set -j ADAPT
$ipt -A PoD -j DROP
# Mail protection
$ipt -N MAIL
$ipt -A INPUT -p tcp --dport 25 --syn -j MAIL
$ipt -A INPUT -p tcp --dport 143 --syn -j MAIL
$ipt -A MAIL -m set --set WL src -j RETURN
$ipt -A MAIL -p tcp -m connlimit --connlimit-above 2 --connlimit-mask 32 -j REJECT
$ipt -A MAIL -m recent --hitcount 2 --name mail --update --seconds 60 -j DROP
$ipt -A MAIL -m recent --name mail --update --seconds 60 -j RETURN
$ipt -A MAIL -m recent --name mail --set -j ADAPT
# SSH bruteforce attack protection
$ipt -N SSH
$ipt -A INPUT -p tcp --dport 22 --syn -j SSH
$ipt -A SSH -m set --set WL src -j RETURN
$ipt -A SSH -p tcp -m recent --hitcount 2 --name SSH --update --seconds 60 -j DROP
$ipt -A SSH -p tcp -m recent --name SSH --update --seconds 60 -j RETURN
$ipt -A SSH -m recent --name SSH --set -j ADAPT
# FTP bruteforce attack protection
$ipt -N FTP
$ipt -A INPUT -p tcp --dport 21 --syn -j FTP
$ipt -A FTP -m set --set WL src -j RETURN
$ipt -A FTP -m set --set WLN src -j RETURN
$ipt -A FTP -p tcp -m recent --hitcount 2 --name FTP --update --seconds 60 -j DROP
$ipt -A FTP -p tcp -m recent --name FTP --update --seconds 60 -j RETURN
$ipt -A FTP -m recent --name FTP --set -j ADAPTCode: Select all
$ipt -A INPUT -m recent --name banned-hosts --update --seconds 36000 -j DROPAlso, for those who really hate to be probed - use TARPIT or MIRROR targets