Dismiss Notice

Welcome To SNBForums

SNBForums is a community for anyone who wants to learn about or discuss the latest in wireless routers, network storage and the ins and outs of building and maintaining a small network.

If you'd like to post a question, simply register and have at it!

While you're at it, please check out SmallNetBuilder for product reviews and our famous Router Charts, Ranker and plenty more!

How to Dynamically Ban Malicious IP's using IPSet (Firewall Addition)

Discussion in 'Asuswrt-Merlin' started by Adamm, Apr 16, 2014.

  1. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    UPDATED 10/03/2015

    Currently this script is only supported for ARM based routers (AC56U/AC68U) as they run a different version of IPTables


    Below you will find a script that automates the process of banning/whitelisting IP's you desire. The main reason for this script was to automaticly and permanently ban IP's that show up in the routers syslog under the prefix "DROP *".

    In simple terms what this script does is add a few extra IPTables rules so rather then just rejecting the request and letting it continue to portscan etc, the malicious IP in question will be forwarded to an IPSet also created by this script. IPSet is a kernel module that efficiently can block hundreds of thousands of IP's without any performance degreadion.

    INSTALLATION;

    CODE REMOVED AND POSTED IN REPLY BELOW

    Rember to "chmod +x" files after creating them so they can be executed.


    To confirm this has worked, reboot your router and you should see "Firewall: [IP Banning Started] ... ... ..." present at the bottom of your routers syslog.

    USAGE;

    Usage of this script is fairly straight forward and each function is separated and described in the file provided. Each command can be executed from SSH using the syntax "firewall *commandhere*"

    WHITELISTING;

    By default, 192.168.1.0/24 & the value of "nvram get lan_ipaddr"/24 will be whitelisted to prevent accidentally locking yourself out from the routers GUI. Please note if you wish to whitelist other IP's the script currently is defaulted to only accept blocks of /24 from a specified file location when using the "firewall whitelist" command.

    OTHER FUNCTIONS;


    Other features of this script include being able to ban IP ranges of entire countries which is useful to ban countries with lots of malicious spam IP's. Using the "firewall country" command you can specify specific countries by inputting their two letter abbreviation and by using the "firewall bancountry" command you will ban the pre-determined countries from personal experience (pk cn in jp ru sa)


    I am open to any suggestions for modifying this script as this version is specifically for the community as there have been lots of requests for this type of functionality. Please note this script will only work on RMerlin based firmwares with JFFS enabled. Hope others can put it to good use :cool:
     
    Last edited: Mar 10, 2015
    ryzhov_al likes this.
  2. thelonelycoder

    thelonelycoder Very Senior Member

    Joined:
    Jan 23, 2014
    Messages:
    1,952
    Location:
    Confœderatio Helvetica
    That evolved quickly and nicely! Thank you.
    I use differing LAN settings and others may too.
    I would have to download the sript manually first and install it that way.
    To help others you could insert a direct download link or post the content of the files in your first post.
     
  3. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    EDIT;

    Until I get my VPS up and running again here is a raw copy of the files;

    /jffs/scripts/firewall

    Code:
    #!/bin/sh
    #################################################################################################
    ## - 25/12/2014 ---        RT-AC66U/RT-AC56U/RT-AC68U Firewall Addition v2.5 -          #
    ###################################################################################################################
    ###                    ----- Make Sure To Edit The Following Files -----              #
    ### /jffs/scripts/firewall-start                     <-- Sets up cronjob/iptables rules          #
    ### /jffs/scripts/firewall                     <-- Blacklists IP's From /jffs/scripts/ipset.txt #
    ### /jffs/scripts/ipset.txt                     <-- Banned IP List/IPSet Rules              #
    ###################################################################################################################
    
    ##############################
    #####Commands / Variables#####
    ##############################
    UNBANSINGLE="unban"          # <-- Remove Single IP From Blacklist
    UNBANALL="unbanall"          # <-- Unbans All IPs In Blacklist
    REMOVEBANS="removeall"       # <-- Remove All Entries From Blacklist
    SAVEIPSET="save"             # <-- Save Blacklists to /jffs/scripts/ipset.txt
    BANSINGLE="ban"              # <-- Adds Entry To Blacklist
    BANCOUNTRYSINGLE="country"   # <-- Adds entire country to blacklist
    BANCOUNTRYLIST="bancountry"  # <-- Bans specified countries in this file
    WHITELIST="whitelist"        # <-- Add IPs from path to Whitelist
    NEWLIST="new"                 # <-- Create new IPSet Blacklist
    DUMPCFE="dumpcfe"              # <-- Dumps current CFE to /jffs/scripts/cfe.dump
    UPDATECFE="updatecfe"         # <-- Flash CFE from /jffs/scripts/cfe.flash (reset nvram afterwards)
    ##############################
    
    start_time=`date +%s`
    cat /jffs/scripts/firewall | head -28
    
    #####################################################################################################################################
    # - Unban / Unbanall / Removeall / Save / Ban / Country / Bancountry / Whitelist / Hideme / Findme/ DumpCFE / UpdateCFE  / Backup - #
    #####################################################################################################################################
    
    if [ X"$@" = X"$UNBANSINGLE" ]
    then
        echo "Input IP Address To Unban"
        read unbannedip
        logger -t Firewall "[Unbanning And Removing $unbannedip From Blacklist] ... ... ..."
        ipset  -D Blacklist $unbannedip
        echo "`sed /$unbannedip/d /jffs/scripts/ipset.txt`" > /jffs/scripts/ipset.txt
        echo "$unbannedip Is Now Unbanned"
    
    elif [ X"$@" = X"$UNBANALL" ]
    then
        echo "[Unbanning All IP's] ... ... ..."
        logger -t Firewall "[Unbanning All IP's] ... ... ..."
        ipset --flush Blacklist
        ipset --flush BlockedCountries
    
    elif [ X"$@" = X"$REMOVEBANS" ]
    then
        nvram set Blacklist=`expr \`ipset -L Blacklist | wc -l\` - 6`
        echo "[Deleting All `echo \`nvram get Blacklist\`` Entries From Blacklist] ... ... ..."
        logger -t Firewall "[Deleting All `echo \`nvram get Blacklist\`` Entries From Blacklist] ... ... ..."
        ipset --flush Blacklist
        ipset --flush BlockedCountries
        ipset --save > /jffs/scripts/ipset.txt
    
    elif [ X"$@" = X"$SAVEIPSET" ]
    then
        echo "[Saving Blacklists] ... ... ..."
        ipset --save > /jffs/scripts/ipset.txt
        echo "`sed '/crond: USER admin/d' /tmp/syslog.log`" > /tmp/syslog.log
    
    elif [ X"$@" = X"$BANSINGLE" ]
    then
        echo "Input IP Address"
        read bannedip
        logger -t Firewall "[Adding $bannedip To Blacklist] ... ... ..."
        ipset -q -A Blacklist $bannedip
        echo "$bannedip Is Now Banned"
    
    elif [ X"$@" = X"$BANCOUNTRYSINGLE" ]
    then
        echo "Input Country Abbreviation"
        read country
        for IP in $(wget -q -O - http://www.ipdeny.com/ipblocks/data/countries/$country.zone)
        do
        ipset -q -A BlockedCountries $IP
        done
    
    elif [ X"$@" = X"$BANCOUNTRYLIST" ]
    then
        echo "[Banning Spam Countries] ... ... ..."
        for country in pk cn in jp ru sa
        do
            for IP in $(wget -q -O - http://www.ipdeny.com/ipblocks/data/countries/$country.zone)
               do
            ipset -q -A BlockedCountries $IP
        done
        done
    
    elif [ X"$@" = X"$WHITELIST" ]
    then
        echo "Input file location"
        read WHITELISTFILE
        for IP in `cat $WHITELISTFILE`
        do
        ipset -q -A Whitelist $IP
        echo $IP
        done
        ipset --save > /jffs/scripts/ipset.txt
    
    elif [ X"$@" = X"$NEWLIST" ]
    then
        echo "Does The Blacklist Need To Be Downloaded? yes/no"
        read ENABLEDOWNLOAD
            if [ X"$ENABLEDOWNLOAD" = X"yes" ]; then
                echo "Input URL For IPSet Blacklist"
                read DOWNLOADURL
                wget -O /jffs/scripts/ipset2.txt $DOWNLOADURL
            fi
        echo "Input New Set Name"
        read SETNAME
        sed -i "s/Blacklist/$SETNAME/g" /jffs/scripts/ipset2.txt
        ipset -q -R  < /jffs/scripts/ipset2.txt
        echo "Successfully Added New Set"
    
    
    elif [ X"$@" = X"$DUMPCFE" ] && [ X"`nvram get model`" = X"RT-AC68U" ]
    then
        echo "Dumping CFE"
        logger -t Firewall "[Dumping CFE] ... ... ..."
        OLDCFE="`strings /dev/mtd0 | grep model` - `strings /dev/mtd0 | grep bl_v` - `strings /dev/mtd0 | grep 0:ccode` - `strings /dev/mtd0 | grep et0macaddr` - `strings /dev/mtd0 | grep 0:macaddr` - `strings /dev/mtd0 | grep 1:macaddr` - `strings /dev/mtd0 | grep secret_code`"
        cat /dev/mtd0 > /jffs/scripts/cfe.dump
        echo "Sucessfully Dumped CFE - $OLDCFE"
        logger -t Firewall "Sucessfully Dumped CFE - $OLDCFE"
    
    elif [ X"$@" = X"$UPDATECFE" ] && [ X"`nvram get model`" = X"RT-AC68U" ]
    then
        echo "Flashing new CFE"
        logger -t Firewall "[Flashing new CFE] ... ... ..."
        OLDCFE="`strings /dev/mtd0 | grep et0macaddr`  `strings /dev/mtd0 | grep 0:macaddr`  `strings /dev/mtd0 | grep 1:macaddr`  `strings /dev/mtd0 | grep secret_code`"
        NEWCFE="`strings /jffs/scripts/cfe.flash | grep et0macaddr`  `strings /jffs/scripts/cfe.flash | grep 0:macaddr`  `strings /jffs/scripts/cfe.flash | grep 1:macaddr`  `strings /jffs/scripts/cfe.flash | grep secret_code`"
            if [ X"`echo $OLDCFE`" = X"`echo $NEWCFE`" ]; then
                echo "Correct Values Detected"
                /jffs/scripts/mtd-write cfe.flash boot && status="Successfully flashed new CFE. `strings /dev/mtd0 | grep bl_v`   `strings /dev/mtd0 | grep 0:ccode`   $NEWCFE"  || status="Failed flashing new CFE"
                logger -t Firewall "$status ... ... ..."
                echo "$status"
            else
                echo "Values Missing From New CFE - Make Sure Values Are Hex'd In" && status="Values Missing From New CFE - Make Sure Values Are Hex'd In"
                echo "Old CFE - $OLDCFE"
                echo "New CFE - $NEWCFE"
                logger -t Firewall "$status ... ... ..."
            fi
    
    else
            if [ X"`nvram get fw_enable_x`" = X"1" ]
            then
                echo "Correct Settings Detected."
            else
                echo "Enabled SPI Firewall"
                nvram set fw_enable_x=1
                nvram commit
            fi
    
            if [ X"`nvram get fw_log_x`" = X"drop" ]
            then
                echo "Correct Settings Detected"
            else
                echo "Enabled Firewall Logging"
                nvram set fw_log_x=drop
                nvram commit
            fi
    
            if [ X"`nvram get clkfreq`" != X"1200,800" ] && [ X"`nvram get model`" = X"RT-AC68U" ]
            then
                echo "Enabled Overclock - Current Clock `nvram get clkfreq`"
                nvram set clkfreq=1200,800
                nvram commit
            else
                echo "Correct Settings Detected."
            fi
    
    
        echo "`sed '/IP Banning Started/d' /tmp/syslog.log`" > /tmp/syslog.log
        echo "[IP Banning Started] ... ... ..."
        logger -t Firewall "[IP Banning Started] ... ... ..."
        ipset -q -R  < /jffs/scripts/ipset.txt
        ipset -q -N Whitelist nethash
        ipset -q -N Blacklist iphash
        ipset -q -N BlockedCountries nethash
        iptables -D logdrop -m state --state NEW -j LOG --log-prefix "DROP " --log-tcp-sequence --log-tcp-options --log-ip-options  > /dev/null 2>&1
        iptables -D INPUT -m set --match-set Whitelist src -j ACCEPT
        iptables -D INPUT -m set --match-set Blacklist src -j DROP
        iptables -D INPUT -m set --match-set BlockedCountries src -j DROP
        iptables -D logdrop -m state --state NEW -j SET --add-set Blacklist src
        iptables -I INPUT -m set --match-set Blacklist src -j DROP
        iptables -I INPUT -m set --match-set BlockedCountries src -j DROP
        iptables -I INPUT -m set --match-set Whitelist src -j ACCEPT
        iptables -I logdrop -m state --state NEW -j SET --add-set Blacklist src
        ipset -q -A Whitelist 192.168.1.0/24
        ipset -q -A Whitelist 192.3.148.0/24
        ipset -q -A Whitelist `nvram get lan_ipaddr`/24
        echo "`sed '/DROP IN=/d' /tmp/syslog.log`" > /tmp/syslog.log
        echo "`sed '/DROP IN=/d' /tmp/syslog.log-1`" > /tmp/syslog.log-1
    
    fi
    
    ###############
    # - Logging - #
    ###############
    OLDAMOUNT=`nvram get Blacklist`
    nvram set Blacklist=`expr \`ipset -L Blacklist | wc -l\` - 6`
    NEWAMOUNT=`nvram get Blacklist`
    nvram set BlacklistTotal=`expr \`ipset -L | wc -l\` - 26`
    start_time=$(expr `date +%s` - $start_time)
    echo "[Complete] $NEWAMOUNT IPs currently banned. `expr $NEWAMOUNT - $OLDAMOUNT` New IP's Banned. `nvram get BlacklistTotal` Banned Overall [`echo $start_time`s]"
    logger -t Firewall "[Complete] $NEWAMOUNT IPs currently banned. `expr $NEWAMOUNT - $OLDAMOUNT` New IP's Banned. `nvram get BlacklistTotal` Banned Overall [`echo $start_time`s]"
    /jffs/scripts/firewall-start

    Code:
    #!/bin/sh
    
    echo "0 * * * * /jffs/scripts/firewall save" > /var/spool/cron/crontabs/admin
    [ -n "`pidof crond`" ] && killall -q crond
    
    sleep 5
    crond
    sh /jffs/scripts/firewall
    
    Rember to "chmod +x" files after creating them so they can be executed.
     
    Last edited: Mar 10, 2015
  4. jernau

    jernau Occasional Visitor

    Joined:
    May 30, 2013
    Messages:
    41
    Unfortunately this script doesn't work for me, I just get loads of errors stating that the --match-set argument is not available in the version of iptables installed;

    iptables v1.3.8: Unknown arg `--match-set'

    I'm running 374.41 Beta 1

    Also the firewall.sh script as downloaded appears to be in DOS format i.e. includes windows linefeeds (^M) so wouldn't run until I ran dos2unix on another machine against the file.
     
  5. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    Thanks for pointing that out, for some reason my encoding settings seem to hate me and constantly change back (lol). Fixed and tested it to make sure it works.
     
  6. shooter40sw

    shooter40sw Senior Member

    Joined:
    Mar 3, 2013
    Messages:
    221
    Hi guys, I already have donwload manager installed, and no planes de uninstall it, or install entware, also have active ssh brute force prevention on the admin page, can I use this script?, I also use a "wierd" :D LAN setup! x.x.x.x/27 thanks
     
  7. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    Yes this will also work with DLM installed, the requirement is so that optware is installed which happens during the DLM setup process.

    This script also should not interfere with any settings so go wild. The script also automatically detects your lan setup on start-up and whitelist's it (using the lan_ipaddr var)

    Hope this helps.
     
  8. jernau

    jernau Occasional Visitor

    Joined:
    May 30, 2013
    Messages:
    41
    Does this script only work on certain Merlin versions as I mentioned before I keep getting the following error when running the script;

    iptables v1.3.8: Unknown arg `--match-set'
     
  9. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    What router are you running and which firmware? Your IPTables is out of date compared to the latest release which the script is based on.

    [email protected]:/tmp/home/root# iptables -V
    iptables v1.4.14

    [email protected]:/tmp/home/root# ipset -V
    ipset v4.5, protocol version 4.
    Kernel module protocol version 4.


    Edit; Okay so just realized the AC66U for whatever reason is based on an older IPTables version. For now support is limited to the AC56U and AC68U. Sorry about that.
     
    Last edited: Apr 16, 2014
  10. octopus

    octopus Very Senior Member

    Joined:
    Jul 17, 2012
    Messages:
    805
    Use: -m set --match-set
     
    Last edited: Nov 7, 2016
  11. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    I will eventually make the script dynamically adjust the IPTables syntax based on the router model, currently the N56U/AC66U/AC68U all run different versions of IPTables and IPSet which makes things painful as I'm maintaining 3 different scripts that do the same thing. I'll get around to it sooner or later.
     
  12. wbennett77

    wbennett77 Regular Contributor

    Joined:
    Jan 5, 2014
    Messages:
    151
    Location:
    Canada
    Hey Adamm,

    Thanks for sharing your work with us. I am using your script and being this is the first time I have ever used SSH and I have one question. I just upgraded the firmare to Merlins final .41 and I wanted to know if this area gets overwritten during the upgrade. I don't see the "starting ...." but I do see this:
    Apr 19 09:45:52 Firewall: [Complete] 0 IPs currently banned. 0 New IP's Banned.
    I am assuming that this means that it didn't get overwritten but being a rookie in this area just need to know for sure.

    Cheers!
     
  13. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    Looks like its working fine, if you see anything like that in the syslog you can confirm its been executed.
     
  14. wbennett77

    wbennett77 Regular Contributor

    Joined:
    Jan 5, 2014
    Messages:
    151
    Location:
    Canada
    Thanks Adamm!
     
  15. idolza

    idolza New Around Here

    Joined:
    Apr 6, 2014
    Messages:
    3
    @Adamm thank you so much.

    Managed to get it working and its been doing its work for me :

    Apr 21 15:11:38 Firewall: [IP Banning Started] ... ... ...
    Apr 21 15:11:39 Firewall: [Complete] 159 IPs currently banned. 2 New IP's Banned.

    Having teenagers on the network, who aren't as careful - this also helps along with all the other measures I've put in place.
     
  16. wbennett77

    wbennett77 Regular Contributor

    Joined:
    Jan 5, 2014
    Messages:
    151
    Location:
    Canada
    That's a lot of banned IPs. Did you add anything to the defaults such as additional countries?
    Cheers!

    Sent from my Galaxy S4 using Tapatalk
     
  17. sinshiva

    sinshiva Very Senior Member

    Joined:
    Nov 8, 2013
    Messages:
    1,030
    Location:
    FL
    sometimes JFFS is overwritten during upgrades so it would definitely be wise to backup from time to time.
     
  18. wbennett77

    wbennett77 Regular Contributor

    Joined:
    Jan 5, 2014
    Messages:
    151
    Location:
    Canada
    One possibly strange question (rookie) but do I have to leave SSH enabled on the router for this to run correctly? The reason I ask is because as soon as I enable SSH the router log showed this but nothing before being enabled:
    Maybe it's just a coincidence?

    Cheers!
     
  19. Adamm

    Adamm Senior Member

    Joined:
    Mar 26, 2013
    Messages:
    303
    I believe your question was answered on IRC but for convience of others, no SSH being enabled is not a requirement but it is required to install the script (that or Telnet).

    And for clarification, the "firewall-start" script is how the firewall addition is initiated on boot (or firewall restart), along with setting up two conjobs that save the IP list and back it up.


    For others to see the scripts effectiveness, here's my firewalls results after a week.

     
    Last edited: Apr 22, 2014
  20. wbennett77

    wbennett77 Regular Contributor

    Joined:
    Jan 5, 2014
    Messages:
    151
    Location:
    Canada
    Good morning,

    Yes, after writing here I went directly to IRC and got the answer I was looking for.

    A couple other things.....how do I get an update as to how many ip's have currently been banned and where would I go to get a country list that works with your script.

    Thanks again!

    Cheers!
     

Share This Page