[Security] abuseIPDBを利用する

セキュリティ上問題があるIPアドレスのデータベース

不正アクセスを行ったり、ブルートフォースアタックに使われたIPアドレスをデータベース化しているサービスは色々あるんですが、その中の一つにabuseIPDBと言うのがあります。

IPアドレスを検索キーに入れることで、そのIPアドレスに不正アクセスの申告が行われているかどうかを確認することが出来ます。

問題ありのIPアドレスに対しては上記のように表示される
該当IPから不正アクセスを受けたという申告内容を参照することが出来る

abuseIPDBのAPIを利用する

そして、abuseIPDBでは、この不正IPアドレスリストを取得できるAPIが提供されています。基本的な機能は無償で提供、さらに必要に応じて有償プランが構成されています。

AbuseIPDB のプラン

API提供されているものでありがたいのが「Basic Blacklist」という機能であり、10,000個のブラックリストを提供して貰うことが出来るので、これをフィルタリングリストに加えるなどの対応をとることで、不正アクセスの防御をある程度動的なセキュリティ施策をとることが出来るという話。

順序としてざっくり書くとこんな感じです。

サインアップ
abuseIPDBのサイト右上にある「Sign up」をクリックし、必要情報を入力する
メールアドレスのベリファイ
必要情報を入力して送信すると、追ってメールが送付されます。そのメールをクリックしてメールアドレスのアクティベーションを行います。これでログインアカウントが有効となり、APIキーを作成可能な状態になります。
APIキーの作成
APIキーの作成を行います。赤枠の流れでタブ・リンクを選択し、APIに対して割り当てる名前を定義します(任意の名前でOK)。すると、APIキーとして長い文字列が出力されますので、これを控えておきます。これでAPIを通じてIPアドレスリストを取得することが出来ます。
実装する
HTTPSアクセスをcurlで行うことにより、10,000個のIPアドレスリストを取得できます。
形式は単純に1行1レコードのIPアドレスリストになっており、IPv4アドレス・IPv6アドレスが混在した形で拾えます。

Nginxと連携とかさせてみる

取得したリストを元にして、Nginxとの連携を行うスクリプトを書きました。

#!/bin/bash

API_KEY="********************************"
TRANS_TMP="/tmp/blacklist-plane.txt"
TRANS_TMP2="/etc/nginx/blacklist/blacklist-deny.txt"
DAYS=`date "+%Y%m%d"`
LOGFILES="/var/log/abuseIPDB-Getlist-${DAYS}.log"

echo `date "+%Y%m%d-%H%M%S"`  [INFO]  Start get data from abuseIPDB. >> ${LOGFILES}

curl -G https://api.abuseipdb.com/api/v2/blacklist \
  -d countMinimum=15 \
  -d maxAgeInDays=60 \
  -d confidenceMinimum=90 \
  -H "Key: $API_KEY" \
  -H "Accept: text/plain" > ${TRANS_TMP}

RECORD_NUM=`grep -E "^([0-9.]+)" ${TRANS_TMP} |wc -l`
if [ ${RECORD_NUM} -ne 0 ]; then
  echo `date "+%Y%m%d-%H%M%S"`  [INFO]  Complete get data from abuseIPDB. >> ${LOGFILES}
  echo `date "+%Y%m%d-%H%M%S"`  [INFO]  Start create deny list data. >> ${LOGFILES}

  cat ${TRANS_TMP}|sed -e 's/^\([0-9\.]\+\)$/deny \;/g'|grep "deny" > ${TRANS_TMP2}

  echo `date "+%Y%m%d-%H%M%S"`  [INFO]  Complete create deny list data. >> ${LOGFILES}
  echo `date "+%Y%m%d-%H%M%S"`  [INFO]  Nginx restart. >> ${LOGFILES}

  systemctl restart nginx

  echo `date "+%Y%m%d-%H%M%S"`  [INFO]  Nginx restart complete. >> ${LOGFILES}
else
  echo `date "+%Y%m%d-%H%M%S"`  [ERROR]  abuseIPDB get error. >> ${LOGFILES}
fi

やってる処理は非常にシンプルで、以下のようなフローとなってます。

  • curlコマンドによりIPアドレスリストを取得する
  • アドレスリストのIPv4アドレスの行数をカウントして0行(取得失敗)であれば異常終了
  • 1行以上取得できていれば、全ての行に対して
    • 先頭に「deny」を付与
    • 末尾に「;」を付与
  • Nginxを再起動

当方の環境では、この設定をMastodonサイト・RADOSGWに対して適用しています。

これを使うことにした経緯

何故これを使ってるかというと、Mastodonサイトに結構な不正アクセスが来たからです。不正アクセスと言っても、恐らくはspam目的のアカウント登録が行われようとした形跡がありまして、それがまた次元の低い話ですが、同じIPアドレスを使って連日アカウント登録依頼が来てるという。

それでそのIPアドレスを検索してみるとこりゃー見事なまでにブルートフォースやらしまくってるIPアドレスだったと言うことで、それに対して一々モデレーション操作をするのも馬鹿らしい・・・だったらもっと手前でブロックしてやれと考えた結果がこれです。

APIで遊ぶのはやっぱりおもろい

私はコーディング初心者・・・もといほぼ素人なわけですが、やっぱりコーディングする際に何が障壁になるかって、「何をコーディングすれば良いかというネタが見つからない」なんですね。どーしても何を頑張っても必要に迫られないとこういう事に頭を使おうと思わない私はこんな感じでネタを見つけながら作ってる感じであります。

何て言うんでしょうかね、インフラ方面だとやっぱり運用のためのコード化というのが一番の同期になるのかなーと思って今日も悪い頭をフル回転させながらコツコツと気まぐれでコードを書いて遊んでいたりします。