Blocking bad IPs using badips.com API

Regarding this post http://www.badips.com/blog/scores-are-here now the API for scores work. Now it is possible to use it for e.g. enhance your iptables to block all the bad IPs which have been reported to http://www.badips.com/.
Afterwards you’ll find two  scripts which are able to use the API and block the reported IPs. The first one is able to use the hosts.deny file. The second one defines rules in iptables. Another way could be the use of ipset, but for now you can choose between these two ways.

Script for hosts.deny:

Script for iptables:

13 thoughts on “Blocking bad IPs using badips.com API

  1. Hey Timo

    Thanks for this blog post!

    You may use a “hidden feature”: _service could be set to “any”, which would match every category.

    A second “hidden feature” is “age=” parameter:

    http://www.badips.com/get/list/any/3?age=2w

    This would select all IPs with a score 3 or higher, in any category and with a maximum age of 2 weeks.

    You can use h, d, w, m and y, for hours, days, weeks, months and years.

    The features will be in the API doc soon..

    R, Amy

    1. Hi Amy,
      thanks for the hint.
      Could you also provide some infos to your scoring system?
      How does the rating works?

      1. Hey Timo

        The rating is a mix of different attributes an IP, and almost as important, the reporter, has. The problem here is that the scoring is in a very early status and I’d like to keep it a secret for the moment. If you feel like you could share some ideas to make it better, or worse, you found a bug, I’m very happy to hear from you!

        One problem we have is that we need some more reporters to submit more IPs so that our algorithms get more precise; we have too less data at the moment. Although, if I compare our results to other blacklists, I think badips.com does a fairly good job.

        In this sense I’d like to thank you for spreading the word!

        R, Amy

        P.S. You misspelled the domain in your post title, it’s badips.com, so plural.

  2. Slightly modified to add Amy’s suggestions looking forward to age limiting on our private key in the future hopefully.

    #!/bin/bash
    # Script for blocking IPs which have been reported to http://www.badips.com
    # Usage: Just execute with root privileges
    # —————————

    _file=/etc/hosts.deny # Location of the hosts.deny files (might be correct)
    _input=badips.db # Name of database (will be downloaded with this name)
    _input2=badipsprivate.db
    _level=5 # Blog level: not so bad/false report (0) over confirmed bad (3)
    _service=any # Logged service (see http://www.badips.com for that)
    _age=1y # You can use h d w m and y hours days weeks months years ex 2w is 2 weeks
    _tmp=tmp # Name of temporary file
    _PRIVATESERVICE=any # Logged service (see http://www.badips.com for that)
    _PRIVATELEVEL=3 # Blog level: not so bad/false report (0) over confirmed bad (3)
    #_PRIVATEAGE=1y # Same as _age but not working yet for private keys
    _keyservice=ENTER YOUR KEY HERE # Your own private key

    # Get the bad IPs
    wget -qO- http://www.badips.com/get/list/${_service}/${_level}?age=${_age} > $_input || { echo “$0: Unable to download ip list.”; exit 1; }
    wget -qO- http://www.badips.com/get/list/${_PRIVATESERVICE}/${_PRIVATELEVEL}/apidoc?key=${_keyservice} > $_input2 || { echo “$0: Unable to download ip list.”; exit 1; }

    # Define some start and end quotes for detecting the IPs defined by this script
    _start=”# ##### start block list — DO NOT EDIT #####”
    _end=”# ##### end block list #####”

    # Delete the old entries
    _line_start=grep -x -n "$_start" $_file | cut -f1 -d:
    _line_end=grep -x -n "$_end" $_file | cut -f1 -d:
    _lines=wc -l $_tmp
    tail -n
    expr $_lines – $_line_end` $_file >> $_tmp
    else
    cp $_file $_tmp
    fi

    # Add the new entries
    echo $_start >> $_tmp
    cat $_input | sed “s/^/ALL: /g” >> $_tmp
    cat $_input2 | sed “s/^/ALL: /g” >> $_tmp
    echo $_end >> $_tmp

    # Replace and cleanup the old file
    mv $_tmp $_file
    rm $_input
    rm $_input2

    exit 0

  3. Hi,
    Is the iptable still working ?
    Cause I get this kind or message : “iptables: Chain already exists.” or this “iptables: No chain/target/match by that name.”

    Thanks.

  4. have ipv6 IP is the blocklist; but our web server only support ipv4 address, so would you mind tell me how to only get ipv4 version ip address ?

  5. I use “wget https://www.badips.com/get/list/any/3?age=2w“, but get errors like following:

    https://www.badips.com/get/list/any/3?age=2w
    Resolving http://www.badips.com (www.badips.com)… 94.23.162.156, 2001:41d0:2:1f20::bad:195
    Connecting to http://www.badips.com (www.badips.com)|94.23.162.156|:443… connected.
    HTTP request sent, awaiting response… 200 OK
    Length: unspecified [text/plain]
    3?age=2w: Protocol error

    Cannot write to ‘3?age=2w’ (Protocol error).

  6. I’ve adjusted the iptables script so that it includes age as well:

    #!/bin/bash
    # Script for blocking IPs which have been reported to http://www.badips.com
    # Usage: Just execute by e.g. cron every day
    # —————————

    _ipt=/sbin/iptables # Location of iptables (might be correct)
    _input=badips.db # Name of database (will be downloaded with this name)
    _pub_if=eth0 # Device which is connected to the internet (ex. $ifconfig for that)
    _droplist=droplist # Name of chain in iptables (Only change this if you have already a chain with this name)
    _level=5 # Blog level: not so bad/false report (0) over confirmed bad (3) to quite aggressive (5) (see http://www.badips.com for that)
    _service=any # Logged service (see http://www.badips.com for that)
    _age=2w # Maximum age. You can use h, d, w, m and y, for hours, days, weeks, months and years.

    # Get the bad IPs
    wget -qO- http://www.badips.com/get/list/${_service}/$_level?age=$_age > $_input || { echo “$0: Unable to download ip list.”; exit 1; }

    ### Setup our black list ###
    # First flush it
    $_ipt –flush $_droplist
    # Create a new chain
    $_ipt -N $_droplist

    # Filter out comments and blank lines
    # store each ip in $ip
    for ip in cat $_input
    do
    # Append everything to $_droplist
    $_ipt -A $_droplist -i ${_pub_if} -s $ip -j LOG –log-prefix “Drop Bad IP List”
    $_ipt -A $_droplist -i ${_pub_if} -s $ip -j DROP
    done

    # Finally, insert or append our black list
    $_ipt -I INPUT -j $_droplist
    $_ipt -I OUTPUT -j $_droplist
    $_ipt -I FORWARD -j $_droplist

    exit 0

Leave a 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.