AbuseIPDBって何?
これ https://www.abuseipdb.com/
世界中のいろいろな人が悪いIPを晒上げるサイトで、怪しげなアクセスがあったときのIP調べるのに使ったする。
1個1個調べたり1個1個晒上げるならサイト上の検索やREPORTで十分だが、自動でブラックリストもらってきたり、まとめて晒上げたい場合WebAPIを使うことになる。
今回はこのサイトのWebAPIを使ってIPブラックリストとってきたり、悪いIPを晒上げてみるまでのことを書く。
WebAPI使うまでの準備
まずはアカウント作成
貧乏なのでFREEなアカウントを使う。
下記にアクセスして、INDVIDUALの下のSIGN UPを選択する。
https://www.abuseipdb.com/pricing
適当に入れるもん入れてアカウント作成すると、以下のような画面に遷移する。
しばらくすると登録したアドレスにメールが来るので、そこに貼ってあるリンクを押すと登録完了。
下記のようにEmailの横がverifiedになる。メールが来ないときはRESEND VERIFICATION EMAILのボタンを押す。(メールが来るの結構おそかったから私は連打してしまった)
APIキー作成
「APIv2」っていうタブがあるからそこ押して「Create Key」でAPIキー作成。名前は適当でいい。
このキーを使ってWebAPIにアクセスすることになる。
IPブラックリスト取得
この辺にcurlを利用した使い方が書いてある。
https://docs.abuseipdb.com/#plaintext-blacklist
とりあえず下記で取得できた。
$ YOUR_API_KEY="APIキー"
$ curl -G https://api.abuseipdb.com/api/v2/blacklist \
-d countMinimum=15 \
-d maxAgeInDays=60 \
-d confidenceMinimum=90 \
-H "Key: $YOUR_API_KEY" \
-H "Accept: text/plain" > blacklist.txt
$ head blacklist.txt
60.29.254.252
118.24.214.107
111.231.88.23
41.33.61.165
128.199.61.227
112.112.102.79
223.111.139.210
36.156.24.99
36.156.24.96
223.111.139.211
$ wc -l blacklist.txt
9999
9999個しかないのはたぶんお金払ってないから。。。Basic Blacklistなるものしか手に入らない。
悪いIP報告
1個1個報告する場合
ここから報告できる。
https://www.abuseipdb.com/report
API使う場合は以下参照。
https://docs.abuseipdb.com/#report-endpoint
SSHブルートフォースが来た場合の報告例
$ curl https://api.abuseipdb.com/api/v2/report \
--data-urlencode "ip=悪いIP" \
-d categories=18,22 \
--data-urlencode "comment=SSH login attempts with user root." \
-H "Key: $YOUR_API_KEY" \
-H "Accept: application/json"
API報告の場合、カテゴリをID(数字)で指定することになる。
下記のカテゴリがある。
https://www.abuseipdb.com/categories
まとめて報告する場合
CSVに悪いIP情報をまとめて、それをアップすることでバルク報告できる。
https://www.abuseipdb.com/bulk-report
一定以上の攻撃を検知してバルクで送信する例
やりたかったのはこれ。
WebApp攻撃が一定以上あったIPを1日1回チェックして、AbuseIPDBにバルクで送信するスクリプト。
WebApp攻撃検知としてModSecurityを使用し、攻撃検知データの蓄積には[waf-fle] (http://www.waf-fle.org/)を使用。
waf-fleのDBつついてIPと攻撃数を取得し、AbuseIPDBに送信する。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb
import datetime
import requests
import sys
tmp_csv = "/tmp/report.csv"
# abuseipdb接続情報
api_url = "https://api.abuseipdb.com/api/v2/bulk-report"
api_key = "APIキー"
# DB接続情報
dbname = "wafdb"
dbuser = "DBユーザ"
dbpass = "DBパスワード"
# 攻撃検知閾値
threshold = 100
# SQL文
dt_now = datetime.datetime.now()
start_day = (dt_now - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
end_day = dt_now.strftime("%Y-%m-%d")
query="SELECT COUNT(a_client_ip), INET_NTOA(a_client_ip), MAX(a_timestamp) FROM events" \
" WHERE a_timestamp >= \"{0} 00:00:00\" AND a_timestamp < \"{1} 00:00:00\" " \
" GROUP BY a_client_ip HAVING COUNT(a_client_ip) > {2} ORDER BY COUNT(a_client_ip) DESC;".\
format(start_day, end_day, threshold)
# DB接続して閾値以上の攻撃IP取得
connect = MySQLdb.connect(host='localhost', port=3306, user=dbuser, passwd=dbpass, db=dbname,
charset='utf8')
cursor = connect.cursor()
cursor.execute(query)
result = cursor.fetchall()
if len(result) == 0:
# 攻撃がなければ終了
cursor.close()
connect.close()
sys.exit(0)
# CSVファイルにに書き出し
f = open(tmp_csv,'w')
f.write('IP,Categories,ReportDate,Comment\n')
for row in result:
f.write('{0},\"16,21\",{1},\"{2} attacks in a short period.\"\n'.format(row[1], row[2], row[0]))
f.close()
cursor.close()
connect.close()
# AbuseIPDBにバルク送信
fileDataBinary = open(tmp_csv, 'rb').read()
files = {'csv': (tmp_csv, fileDataBinary)}
headers = {'Accept': 'application/json', 'Key': api_key}
response = requests.post(api_url, headers=headers, files=files)
# print(response.status_code)
# print(response.content)
このスクリプトをcronで毎日1回実行することにした。
これで自動で悪いIPをAbuseIPDBにさらすことができる。
余談
なんかpythonモジュールとしてabuseipdbというのがあったが、バルク送信に対応してないし、正直この程度APIなら普通にrequests使ったほうがいいと思う。
https://pypi.org/project/abuseipdb/