What's new

Help Needed: Firewall Script *Fixed!*

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Schuby

Occasional Visitor
I modified @Adamm 's script (http://www.snbforums.com/threads/ho...ious-ips-using-ipset-firewall-addition.16798/) and with the help of @Maude I was able to use iptables to forward ports to my web server and still have blacklisted users banned as needed.

In regards to the original script, I removed the 'dynamic' portion of it (i.e. searching for 'DROP' packets in the firewall log and auto-banning them) as well as added a 'checkban' feature to see if a provided IP address is either banned or not banned. Furthermore I used 'ShellCheck' to cleanup code and bring it up to shell standards.

Here is the full edit: FIXED script:

Code:
#!/bin/sh

#################################################################################################
############################## 06/02/2016 - Firewall Addition v3.1 ##############################
#################################################################################################
########################----- 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 i.e. ./Firewall.sh unban 123.45.6.7
UNBANALL="unbanall"          # <-- Unbans All IPs In Blacklist i.e. ./Firewall.sh unbanall
REMOVEBANS="removeall"       # <-- Remove All Entries From Blacklist i.e. ./Firewall.sh removeall
SAVEIPSET="save"             # <-- Save Blacklists to /jffs/scripts/ipset.txt i.e. ./Firewall.sh save
BANSINGLE="ban"              # <-- Adds Entry To Blacklist i.e. ./Firewall.sh ban 123.45.6.7
BANCOUNTRYSINGLE="country"   # <-- Adds entire country to blacklist i.e. ./Firewall.sh country ca
BANCOUNTRYLIST="bancountry"  # <-- Bans specified countries in this file i.e. ./Firewall.sh bancountry
WHITELIST="whitelist"        # <-- Add IPs from path to Whitelist i.e. ./Firewall.sh whitelist /jffs/scripts/whitelist.txt
NEWLIST="new"                # <-- Create new IPSet Blacklist i.e. ./Firewall.sh new
CHECKBAN="check"             # <-- Check if an IP is banned. i.e. ./Firewall.sh check 123.45.6.7
##############################

start_time=$(date +%s)

if [ "$1" = "$UNBANSINGLE" ]
    then
        logger -t Firewall "[Unbanning And Removing $2 From Blacklist] ... ... ..."
        ipset  -D Blacklist "$2"
        printf "%s" "$(sed "/$2/d" /jffs/scripts/ipset.txt > unbantmpfile && mv unbantmpfile ipset.txt)"
        echo "$2 Is Now Unbanned"
elif [ "1" = "$UNBANALL" ]
    then
        echo "[Unbanning All IP's] ... ... ..."
        logger -t Firewall "[Unbanning All IP's] ... ... ..."
        ipset --flush Blacklist
        ipset --flush BlockedCountries
elif [ "$1" = "$REMOVEBANS" ]
    then
        nvram set Blacklist="$(printf "%s" "$(ipset -L Blacklist | wc -l)")"
        echo "[Deleting All $(nvram get Blacklist) Entries From Blacklist] ... ... ..."
        logger -t Firewall "[Deleting All $(nvram get Blacklist) Entries From Blacklist] ... ... ..."
        ipset --flush Blacklist
        ipset --flush BlockedCountries
        ipset --save > /jffs/scripts/ipset.txt
elif [ "$1" = "$SAVEIPSET" ]
    then
        echo "[Saving Blacklists] ... ... ..."
        ipset --save > /jffs/scripts/ipset.txt
        printf "%s" "$(sed "/crond: USER admin/d" /tmp/syslog.log > saveiptmpfile && mv saveiptmpfile /tmp/syslog.log)"
elif [ "$1" = "$BANSINGLE" ]
    then
        logger -t Firewall "[Adding $2 To Blacklist] ... ... ..."
        ipset -q -A Blacklist "$2"
        echo "$2 Is Now Banned"
elif [ "$1" = "$BANCOUNTRYSINGLE" ]
    then
        echo "Input Country Abbreviation"
        read -r country
        for IP in $(wget -q -O - http://www.ipdeny.com/ipblocks/data/countries/"$country".zone)
            do
            ipset -q -A BlockedCountries "$IP"
        done
elif [ "$1" = "$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 [ "$1" = "$WHITELIST" ]
    then
        echo "Input file location"
        read -r WHITELISTFILE
        grep -v '^ *#' < "$WHITELISTFILE" | while IFS= read -r IP
        do
            ipset -q -A Whitelist "$IP"
            echo "$IP"
        done
    ipset --save > /jffs/scripts/ipset.txt
elif [ "$1" = "$NEWLIST" ]
    then
        echo "Does The Blacklist Need To Be Downloaded? yes/no"
        read -r ENABLEDOWNLOAD
            if [ X"$ENABLEDOWNLOAD" = X"yes" ]; then
                echo "Input URL For IPSet Blacklist"
                read -r DOWNLOADURL
                wget -O /jffs/scripts/ipset2.txt "$DOWNLOADURL"
            fi
        echo "Input New Set Name"
        read -r SETNAME
        sed -i "s/Blacklist/$SETNAME/g" /jffs/scripts/ipset2.txt
        ipset -q -R  < /jffs/scripts/ipset2.txt
        echo "Successfully Added New Set"
elif [ "$1" = "$CHECKBAN" ]
    then
        checkip=$(ipset -L | grep "$2")
        if test -n "$checkip"; then
            echo "$2" is banned.
            exit
        else
            echo "$2" is not banned.
            exit
        fi
    fi
### Main ban script function

printf "%s" "$(sed "/IP Banning Started/d" /tmp/syslog.log > baniptmpfile && mv baniptmpfile /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

### Add webserver forwards

iptables -t nat -I PREROUTING -d "$(nvram get wan0_ipaddr)"/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination "$(nvram get WWW)":80
iptables -t nat -I PREROUTING -d "$(nvram get wan0_ipaddr)"/32 -p tcp -m tcp --dport 443 -j DNAT --to-destination "$(nvram get WWW)":443
iptables -t nat -I PREROUTING -d "$(nvram get wan0_ipaddr)"/32 -p tcp -m tcp --dport 80 -m set --match-set Whitelist src -j DNAT --to-destination "$(nvram get WWW)":80
iptables -t nat -I PREROUTING -d "$(nvram get wan0_ipaddr)"/32 -p tcp -m tcp --dport 443 -m set --match-set Whitelist src -j DNAT --to-destination "$(nvram get WWW)":443
iptables -I FORWARD -m conntrack --ctstate DNAT -j ACCEPT
iptables -I FORWARD -m conntrack --ctstate DNAT -m set --match-set BlockedCountries src -j DROP
iptables -I FORWARD -m conntrack --ctstate DNAT -m set --match-set Blacklist src -j DROP

### Standard blocking rules based on lists.

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
ipset -q -A Whitelist 192.168.1.0/24
ipset -q -A Whitelist "$(nvram get lan_ipaddr)"/24

###############
# - Logging - #
###############
OLDAMOUNT="$(nvram get Blacklist)"
nvram set Blacklist=$(($(ipset -L Blacklist | wc -l) - 6))
NEWAMOUNT="$(nvram get Blacklist)"
nvram set BlacklistTotal=$(($(ipset -L | wc -l) - 26))
current_time=$(date +%s)
start_time=$((current_time - start_time))
echo "[Complete] $NEWAMOUNT IPs currently banned. $((NEWAMOUNT - OLDAMOUNT)) New IP's Banned. $(nvram get BlacklistTotal) Banned Overall ($start_time s)"
logger -t Firewall "[Complete] $NEWAMOUNT IPs currently banned. $((NEWAMOUNT - OLDAMOUNT)) New IP's Banned. $(nvram get BlacklistTotal) Banned Overall ($start_time s)"

As of this moment, this passes ShellCheck 100%!

Many thanks to @Neurophile , @Fitz Mutch , and @barzot for helping me fix the code.

To-do:

  1. Allow users to specify webserver IP at top of script instead of expecting them to set WWW in nvram.
  2. Use printf instead of echo.
  3. Incorporate the updated malware code by @Neurophile and @swetoast
    1. http://www.snbforums.com/threads/using-ipset-revisited.32817/
  4. Allow users to specify ports wanted (if any) at the start of the script.
  5. Remove any unused/unwanted arguments.
  6. Allow users to specify countries in a separate file.
  7. Put everything on github.
 
Last edited:
(I went over the character limit)
  • Issue 2:
Not really an issue per say, but more of a 'nice to have' request. I want to convert the following functions from using EXPR to Ash's built in arithmetic features.

Code:
nvram set Blacklist=`expr \`ipset -L Blacklist | wc -l\` - 6`

nvram set BlacklistTotal=`expr \`ipset -L | wc -l\` - 26`

I'm starting to think it isn't possible to not use EXPR, but I just wanted to check and see if anyone can help figure out a clean method.

BTW, feel free to use this code for yourself. I can't really provide support as it is customized for my needs. However I'm willing to try and help if anyone runs into issues.
 
Code:
elif [ "$1" = "$CHECKBAN" ]
then
    checkip=$(ipset -L | grep "$2")
        if test -n "$checkip"; then
        echo "$2" is banned.
    exit   
    else
        echo "$2" is not banned.
    exit
fi

This is malformed. you are missing a fi and the indents are all messed up. Try this:
Code:
elif [ "$1" = "$CHECKBAN" ]
then
    checkip=$(ipset -L | grep "$2")
    if test -n "$checkip"; then
        echo "$2" is banned.
        exit   
    else
        echo "$2" is not banned.
        exit
    fi
fi
Of course I could be wrong, shell scripting isn't my strong suit.
 
Code:
elif [ "$1" = "$CHECKBAN" ]
then
    checkip=$(ipset -L | grep "$2")
        if test -n "$checkip"; then
        echo "$2" is banned.
    exit  
    else
        echo "$2" is not banned.
    exit
fi

This is malformed. you are missing a fi and the indents are all messed up. Try this:
Code:
elif [ "$1" = "$CHECKBAN" ]
then
    checkip=$(ipset -L | grep "$2")
    if test -n "$checkip"; then
        echo "$2" is banned.
        exit  
    else
        echo "$2" is not banned.
        exit
    fi
fi
Of course I could be wrong, shell scripting isn't my strong suit.

I'll give this a shot tomorrow and report back. I appreciate the help!
 
Code:
elif [ "$1" = "$CHECKBAN" ]
then
    checkip=$(ipset -L | grep "$2")
        if test -n "$checkip"; then
        echo "$2" is banned.
    exit  
    else
        echo "$2" is not banned.
    exit
fi

This is malformed. you are missing a fi and the indents are all messed up. Try this:
Code:
elif [ "$1" = "$CHECKBAN" ]
then
    checkip=$(ipset -L | grep "$2")
    if test -n "$checkip"; then
        echo "$2" is banned.
        exit  
    else
        echo "$2" is not banned.
        exit
    fi
fi
Of course I could be wrong, shell scripting isn't my strong suit.

It worked, thank you! The missing 'fi' was the problem.

Now I hope someone can come along and provide advice on the 'expr' function.
 
Code:
nvram set Blacklist=`expr \`ipset -L Blacklist | wc -l\` - 6`
nvram set BlacklistTotal=`expr \`ipset -L | wc -l\` - 26`



HOWTO: Evaluate math expression in shell script
Code:
nvram set Blacklist=$(($(ipset -L Blacklist | wc -l) - 6))
nvram set BlacklistTotal=$(($(ipset -L | wc -l) - 26))
 
HOWTO: Evaluate math expression in shell script
Code:
nvram set Blacklist=$(($(ipset -L Blacklist | wc -l) - 6))
nvram set BlacklistTotal=$(($(ipset -L | wc -l) - 26))

Yes! I could have sworn I tried this, but who knows. Either way it works. Thanks!

A typo:
Code:
elif [ "1" = "$UNBANALL" ]
should be:
Code:
elif [ "$1" = "$UNBANALL" ]

Thanks! I noticed that after I posted but forgot to fix it in the original post. All of the fixed code will be placed in the opening post shortly.
 

Similar threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top