September 25, 2020

How to prevent port scan in Linux

2 min read

There are existing anti-port scanning tools on the Internet, such as psad and portsentry, but I find the configuration a bit cumbersome, and the server does not want to install additional software. So I wrote a shell script to implement this function. The basic idea is to use the recent iptables to record the IP that scans more than 10 ports in 60 seconds, and use the inotify-tools tool to monitor the iptables log in real-time. Once a new ip record is written to the iptables log file, use iptables blocks the source IP and prevents port scanning.

iptables rule

Create a new script iptables.sh and execute this script.
IPT=”/sbin/iptables”
$IPT –delete-chain
$IPT –flush

#Default Policy
$IPT -P INPUT DROP
$IPT -P FORWARD DROP 
$IPT -P OUTPUT DROP

#INPUT Chain
$IPT -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp -m tcp –dport 80 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp –dport 22 -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
$IPT -A INPUT -p icmp -m icmp –icmp-type 11 -j ACCEPT
$IPT -A INPUT -p tcp –syn -m recent –name portscan –rcheck –seconds 60 –hitcount 10 -j LOG
$IPT -A INPUT -p tcp –syn -m recent –name portscan –set -j DROP
#OUTPUT Chain
$IPT -A OUTPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p udp -m udp –dport 53 -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A OUTPUT -p icmp -m icmp –icmp-type 8 -j ACCEPT
$IPT -A OUTPUT -p icmp -m icmp –icmp-type 11 -j ACCEPT

#iptables save
service iptables save
service iptables restart

iptables log location change

Edit /etc/syslog.conf and add:

kern.warning /var/log/iptables.log

Restart syslog

/etc/init.d/syslog restart

Prevent port scan in Linux

Install inotify tool

yum install inotify-tools

Save the following code into prevent_portscan.sh

btime=600

while true;do

while inotifywait -q -q -e modify /var/log/iptables.log;do

ip=`tail -1 /var/log/iptables.log | awk -F”[ =]” ‘{print $13}’ | grep ‘\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}’`

if test -z “`/sbin/iptables -nL | grep $ip`”;then

/sbin/iptables -I INPUT -s $ip -j DROP

{

sleep $btime && /sbin/iptables -D INPUT -s $ip -j DROP

} &

fi

done

done

Run the command to enable anti-port scanning

prevent_portscan.sh