• Skip to primary navigation
  • Skip to main content
sharadchhetri

sharadchhetri

Tutorials On Linux, Unix & Open Source

  • Home
  • Linux Commands
  • Resources
    • Learn Linux
  • My WordPress plugins

How to protect from port scanning and smurf attack in Linux Server by iptables

June 15, 2013 by Sharad Chhetri 21 Comments

In this post I will share the iptable script in which we will learn How to protect from port scanning and smurf attack in Linux Server.

Features Of Script :

(1) When a attacker try to port scan your server, first because of iptable attacker will not get any information which port is open. Second the Attacking IP address will be blacklisted for 24 Hour (You can change it in script) . Third , after that attacker will not able to open access anything for eg. even attacker will not see any website running on server via web browser, not able to ssh,telnet also. Means completely restricted.

(2) Protects from smurf attack

(3) Written with the help of IPTABLE hence no System Performance issue like CPU high,Memory usage etc. No third party tool is used

Note: You can add or remove port no. as per your requirement.

Description about Server where we will implement IPTABLE script:

Operating Syetem : CentOS 6.4 (applicable to Red hat and CentOS servers)
IP Address: 192.168.1.4

Now we will create the script

Step 1: Create a bash script with the name of iptablescript.sh

vi /root/iptablescript.sh

Step 2: Now paste the below given script contents in your bash script file iptablescript.sh

#!/bin/sh
#
#
# Script is for stoping Portscan and smurf attack

### first flush all the iptables Rules
iptables -F


# INPUT iptables Rules
# Accept loopback input
iptables -A INPUT -i lo -p all -j ACCEPT

# allow 3 way handshake
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

### DROPspoofing packets
iptables -A INPUT -s 10.0.0.0/8 -j DROP 
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 172.16.0.0/12 -j DROP
iptables -A INPUT -s 127.0.0.0/8 -j DROP
iptables -A INPUT -s 192.168.0.0/24 -j DROP

iptables -A INPUT -s 224.0.0.0/4 -j DROP
iptables -A INPUT -d 224.0.0.0/4 -j DROP
iptables -A INPUT -s 240.0.0.0/5 -j DROP
iptables -A INPUT -d 240.0.0.0/5 -j DROP
iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -d 0.0.0.0/8 -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
iptables -A INPUT -d 255.255.255.255 -j DROP

#for SMURF attack protection
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
iptables -A INPUT -p icmp -m icmp -m limit --limit 1/second -j ACCEPT

# Droping all invalid packets
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP

# flooding of RST packets, smurf attack Rejection
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

# Protecting portscans
# Attacking IP will be locked for 24 hours (3600 x 24 = 86400 Seconds)
iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP

# Remove attacking IP after 24 hours
iptables -A INPUT -m recent --name portscan --remove
iptables -A FORWARD -m recent --name portscan --remove

# These rules add scanners to the portscan list, and log the attempt.
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

# Allow the following ports through from outside
iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

# Allow ping means ICMP port is open (If you do not want ping replace ACCEPT with REJECT)
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# Lastly reject All INPUT traffic
iptables -A INPUT -j REJECT


################# Below are for OUTPUT iptables rules #############################################

## Allow loopback OUTPUT 
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow the following ports through from outside 
# SMTP = 25
# DNS =53
# HTTP = 80
# HTTPS = 443
# SSH = 22
### You can also add or remove port no. as per your requirement

iptables -A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT
iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 22 -j ACCEPT

# Allow pings
iptables -A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# Lastly Reject all Output traffic
iptables -A OUTPUT -j REJECT

## Reject Forwarding  traffic
iptables -A FORWARD -j REJECT

Step 3: Make the Read Write Execute permission only to root user. (For security)

 chmod 700 /root/iptablescript.sh
  chown root:root /root/iptablescript.sh

Step 4 : Now run the script

sh /root/iptablescript.sh 

or 

./root/iptablescript.sh

Step 6: Now check the IPTABLES rule with following command


iptables -nL

Now we will do testing from remote server to our server where we have implemented the iptable

Step 7: login into any system and try to do port scanning

nmap -sT Server-ip-address

eg.

nmap -sT 192.168.1.4

Step 8: The result should be now from your system like following types

(a) Not getting any output from nmap
(b) Not able to do telnet to any port for eg. telnet Server-ip-address 22

After running nmap means port scan your ip-address is blacklisted.

You can find your system ip address in message logs in Server with the keyword called portscan.
So login back to your server and check the messages log in /var/log

Note : how to install nmap

In Red Hat and CentOS 

yum install nmap

In Debian and Ubuntu

apt-get install nmap

Share this:

  • Twitter
  • Facebook
  • More
  • Print
  • Email
  • LinkedIn
  • Reddit
  • Tumblr
  • Pinterest
  • Pocket
  • Telegram
  • WhatsApp
  • Mastodon

Related posts:

  1. Protect from SSL Drown Attack in AWS ELB, Apache and Nginx
  2. How to backup and restore iptables on Linux systems
  3. Protect from w00tw00t.at.blackhats.romanian.anti-sec
  4. Change the default port number of ssh server
  5. Protect ssh with Google Authenticator on Ubuntu 14.04 LTS
  6. Change telnet server port number on CentOS 7 / RHEL 7
  7. How to backup and restore iptables on CentOS 7 / RHEL 7
  8. Change mysql default port number in linux
  9. rsync over ssh port number on Linux/Unix system
  10. How to change smtp port number 25 in postfix

Filed Under: Linux, Tips And Tricks Tagged With: iptables

Reader Interactions

Comments

  1. wIzZa says

    August 9, 2017 at 10:15 pm

    Great script thanks!

    Line:
    iptables -A INPUT -p icmp -m icmp -m limit –limit 1/second -j ACCEPT

    Results in an error:
    iptables v1.4.21: icmp: option “–icmp-type” must be specified

    It should be:
    iptables -A INPUT –protocol icmp –match icmp –icmp-type 8 –match limit –limit 1/second –jump ACCEPT

    Reply
  2. David says

    March 16, 2017 at 11:26 am

    Hi there,

    Thanks for this.

    Unfortunately, Smurf Attack is still possible (tested with hping3).

    Any idea how to mitigate it?

    Reply
    • Sharad Chhetri says

      March 17, 2017 at 4:46 pm

      Hi David,

      Thank you for replying with feedback. Currently I am not using hping3, it would be great if you could provide me its result.
      In which Operaring System version are you applying the iptable. I also need iptable version number.

      Regards
      Sharad

      Reply
  3. phil says

    October 12, 2016 at 6:16 am

    how could I add an exception IP (our admin) to that script so we are not locked out
    I often do telnet to check if a port is responding

    thanks

    Reply
  4. Flo says

    August 2, 2016 at 3:01 pm

    root@ubuntu:~# ./iptablescript.sh
    iptables v1.6.0: icmp: option “–icmp-type” must be specified

    Try `iptables -h’ or ‘iptables –help’ for more information.

    Reply
    • Rick says

      December 29, 2016 at 8:40 am

      I am also getting this.

      Reply
  5. Clifford Trueman says

    April 7, 2016 at 4:28 pm

    Really great write up, Could I ask you to clarify why

    iptables -A INPUT -m recent –name portscan –rcheck –seconds 86400 -j DROP

    is required before

    iptables -A INPUT -p tcp -m tcp –dport 139 -m recent –name portscan –set -j DROP

    Shouldn’t the latter be enough?

    Reply
    • sharad chhetri says

      April 8, 2016 at 4:07 pm

      Hello Clifford,

      You can shuffle but it should be within DROP sections. To understand, I suggest to try the things practically. Do testing things in test machine ๐Ÿ™‚

      All the best.

      Regards
      Sharad

      Reply
  6. Aryan Parker says

    June 15, 2015 at 3:42 pm

    HI. I ran your script in my Linux Mint cinnamon . I am behind an office proxy network, and when I ran your script, it gave me the following error-
    iptables v1.4.21: icmp: option “–icmp-type” must be specified
    Try `iptables -h’ or ‘iptables –help’ for more information.
    Also I was unable to access the internet then. So I changed the iptables -A OUTPUT -j REJECT to iptables -A OUTPUT -j ACCEPT .
    so 1) what should I do to remove the above error.
    2) Being on a proxy network, are there any changes that I should make in the script
    3) After running your script too, other users were able to do a port scan on my system. How should I fix it ?
    Thanks

    Reply
    • sharadchhetri says

      June 16, 2015 at 2:37 am

      Hi Aryan,

      As the error specified , “–icmp-type” .
      Most probably there is typo or special character is added with iptables.
      I rerun the script and it is working for me. Curious to know , if typo is fixed and the script is working for you.

      Regards
      Sharad

      Reply
      • Andrey Oskin says

        October 8, 2015 at 8:50 pm

        It seems to be the problem with iptables version. I am running this script on Ubuntu 14.04, iptables v1.4.21 and have the same error. Problematic line:

        iptables -A INPUT -p icmp -m icmp -m limit –limit 1/second -j ACCEPT

        and error is saying that –icmp-type must be specified (and now it’s not)

        Reply
  7. nick4ever says

    April 6, 2015 at 6:26 pm

    HI Sharad Chhetri,

    Very thank you for sharing this wonderful script. Can I ask you this if not bother you. My scenario is:

    -I got 2 interfaces: eth0 (Internal network – LAN) and ppp0 (External – Real IP – pppoe gateway)
    -I made rules that bridge 2 interfaces and everything work fine, my LAN network works well, also the gateway. However, my issue is I could not connect to WAN IP (External IP from ppp0 interface) from LAN network,

    here is my script

    #!/bin/sh

    LAN=”eth0″
    WAN=”ppp0″

    echo “Flushing rules”
    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    iptables -t mangle -F
    iptables -t mangle -X
    echo “Done”

    iptables -P INPUT DROP
    iptables -P OUTPUT ACCEPT
    iptables -P FORWARD ACCEPT

    ## Allow loopback OUTPUT
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
    iptables -A OUTPUT -m state –state ESTABLISHED,RELATED -j ACCEPT

    iptables -A INPUT -i $WAN -m state –state ESTABLISHED,RELATED -j ACCEPT

    ### DROPspoofing packets
    iptables -A INPUT -s 10.0.0.0/8 -j DROP
    iptables -A INPUT -s 169.254.0.0/16 -j DROP
    iptables -A INPUT -s 172.16.0.0/12 -j DROP
    iptables -A INPUT -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -s 192.168.0.0/24 -j DROP

    iptables -A INPUT -s 224.0.0.0/4 -j DROP
    iptables -A INPUT -d 224.0.0.0/4 -j DROP
    iptables -A INPUT -s 240.0.0.0/5 -j DROP
    iptables -A INPUT -d 240.0.0.0/5 -j DROP
    iptables -A INPUT -s 0.0.0.0/8 -j DROP
    iptables -A INPUT -d 0.0.0.0/8 -j DROP
    iptables -A INPUT -d 239.255.255.0/24 -j DROP
    iptables -A INPUT -d 255.255.255.255 -j DROP

    #for SMURF attack protection
    iptables -A INPUT -p icmp -m icmp –icmp-type address-mask-request -j DROP
    iptables -A INPUT -p icmp -m icmp –icmp-type timestamp-request -j DROP
    iptables -A INPUT -p icmp -m icmp -m limit –limit 1/second -j ACCEPT

    # Droping all invalid packets
    iptables -A INPUT -m state –state INVALID -j DROP
    iptables -A FORWARD -m state –state INVALID -j DROP
    iptables -A OUTPUT -m state –state INVALID -j DROP

    # flooding of RST packets, smurf attack Rejection
    iptables -A INPUT -p tcp -m tcp –tcp-flags RST RST -m limit –limit 2/second –limit-burst 2 -j ACCEPT

    # Protecting portscans
    # Attacking IP will be locked for 15 minutes ( 60 x 15 = 900 Seconds)
    iptables -A INPUT -m recent –name portscan –rcheck –seconds 900 -j DROP
    iptables -A FORWARD -m recent –name portscan –rcheck –seconds 900 -j DROP

    # Remove attacking IP after 15 minutes
    iptables -A INPUT -m recent –name portscan –remove
    iptables -A FORWARD -m recent –name portscan –remove

    # These rules add scanners to the portscan list, and log the attempt.
    iptables -A INPUT -p tcp -m tcp –dport 139 -m recent –name portscan –set -j LOG –log-prefix “portscan:”
    iptables -A INPUT -p tcp -m tcp –dport 139 -m recent –name portscan –set -j DROP

    iptables -A FORWARD -p tcp -m tcp –dport 139 -m recent –name portscan –set -j LOG –log-prefix “portscan:”
    iptables -A FORWARD -p tcp -m tcp –dport 139 -m recent –name portscan –set -j DROP

    # Allow ping means ICMP port is open (If you do not want ping replace ACCEPT with REJECT)
    iptables -A INPUT -p icmp -m icmp –icmp-type 8 -j REJECT

    # SYN-Flooding Protection
    iptables -N syn-flood
    iptables -A INPUT -i $WAN -p tcp –syn -j syn-flood
    iptables -A syn-flood -m limit –limit 1/s –limit-burst 4 -j RETURN
    iptables -A syn-flood -j DROP

    # Make sure that new TCP connections are SYN packets
    iptables -A INPUT -i $WAN -p tcp ! –syn -m state –state NEW -j DROP

    #iptables -A INPUT -j DROP
    iptables -A INPUT -j REJECT

    #
    iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
    iptables -A FORWARD -i $LAN -j ACCEPT

    iptables -A INPUT -i $LAN -j ACCEPT

    echo “Opening SSH port…”
    iptables -A INPUT -p tcp –dport 8888 -j ACCEPT
    iptables -A INPUT -p tcp –dport 22 -j ACCEPT
    echo “Opening HTTP port…”
    iptables -A INPUT -p tcp –dport 80 -j ACCEPT
    echo “Opening RDP port…”
    iptables -A INPUT -p tcp –dport 3389 -j ACCEPT

    iptables -t nat -A PREROUTING -i $WAN -p tcp –dport 22 -j DNAT –to 192.168.10.55:22
    iptables -t nat -A PREROUTING -i $WAN -p tcp –dport 80 -j DNAT –to 192.168.10.55:80
    iptables -t nat -A PREROUTING -i $WAN -p tcp –dport 3389 -j DNAT –to 192.168.10.5:3389

    service iptables save
    service iptables restart
    iptables-save > rules

    Reply
    • sharad chhetri says

      April 7, 2015 at 3:49 am

      Hello Nick,

      Allow DNS port in script and try again.Also check /etc/resolv.conf if the DNS ip is correctly given.

      Regards
      Sharad

      Reply
  8. Gianni says

    February 10, 2015 at 11:19 am

    Thanks you Sharad for your post and your script, work very well. For Claudia: she must run your script and after iptables-save and service iptalbes restart. Don’t make a copy of the script in the iptables file.

    Reply
    • sharad chhetri says

      February 11, 2015 at 2:40 am

      Welcome Gianni,

      That is very useful feedback.

      Regards
      Sharad

      Reply
  9. Mark Espinoza says

    November 16, 2014 at 4:17 pm

    Thank you for posting this kind of stuff, saved me a lot of work. Much appreciated.

    Reply
    • sharad chhetri says

      November 17, 2014 at 6:45 pm

      Welcome Mark,

      Regards
      Sharad

      Reply
  10. Claudia says

    May 17, 2014 at 5:59 pm

    My VPS runs Centos 5.10. I’ve installed it correctly, but when I run the script I get a host of errors in ssh.

    [1] command not found [line 5, also lines 8,9, and thereafter whenever the line is empty]

    [2] iptables: no chain/ target/ match by that name

    [3] ‘ptables v1.3.5: Invalid target name ACCEPT [also with DROP, REJECT]

    [4] try iptables -h or iptables –help for more information

    Please advise. Thanks!

    Reply
    • sharad chhetri says

      May 18, 2014 at 2:52 am

      Hello Claudia,

      As per question, it seems the CentOS 5.10 has different iptables version . In this case we have to check the available options with IPTABLE command. The script has been last tested in CentOS 6.5 .

      Regards
      Sharad

      Reply
Newer Comments »

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Copyright © 2023 ยท
The material in this site cannot be republished either online or offline, without our permission.
Proudly Blogging From Bharat.

  • Contact
  • About Me
  • My WordPress plugins
  • Privacy Policy