[Security] Fail2banとCloudFlare API v4を統合する方法

fail2banのカスタムアクションで CloudFlare API v4 を統合して、Webサーバーへの攻撃/アタックをブロックします。(2018/02/07作成)

Flare Designerkottayam / Pixabay

Cloudflareとは

Cloudflare(クラウドフレア)は、コンテンツデリバリーネットワークや分散型ドメイン名サーバシステムを提供するアメリカ合衆国の企業で、ウェブサイトにリバースプロキシを動作させることで閲覧者と自社ユーザーのホスティングプロバイダー間を取り持っている。(出典: Wikipedia)

fail2banとは

fail2ban(フェイルトゥバン)は、SSH等の不正アクセス(ログイン失敗)を検知し、一定時間そのIPアドレスからのアクセスをブロックするソフトである。 通常、fail2banは単体では使用せず、ファイアウォールソフト(iptablesやfirewalld)ともに使用する。 この記事では、firewalldを使用する。(出典: Google)

1.fail2banとCloudFlare API v4を統合する概要

・Nginx側の環境整備を行う
・cURLを使用してCloudFlare API v4をテストする
・fail2banとの統合用カスタムCloudFlareアクションの作成する

2.Nginx側の環境整備

・Cloudflareの使用中にfail2banを使用することはできますか? →answer
・Nginxでオリジナルの訪問者IPを復元するにはどうすればよいですか? →answer

3.cURLを使用してCloudFlare API v4をテストする

1)インストール環境

$ cat /etc/redhat-release
CentOS release 6.9 (Final)

$ sudo fail2ban-client -V | head -n 1
Fail2Ban v0.9.6

$ curl -V | head -n 1
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2

2)CloudFlare API v4のテスト【禁止ルール追加】

ここ から CloudFlare API Key を取得して 下の値に置き換えて、IPアドレス「 1.2.3.4 」をテストとして禁止します。以下は、fail2ban禁止アクションになります。

◆リクエスト例

curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \
-H "X-Auth-Email: CloudFlare-username" \
-H "X-Auth-Key: CloudFlare-API-Key" \
-H "Content-Type: application/json" \
--data '{"mode":"block","configuration":{"target":"ip","value":"1.2.3.4"},"notes":"Fail2ban"}'

※IPルールが CloudFlareに追加された場合は、success: true がレスポンスされます。

◆レスポンス例

{"result":{"id":"8286c03a200db3b5d09bab0f414dc111","mode":"block","allowed_modes":["block","challenge","whitelist","js_challenge"],"status":"active","notes":"Fail2ban","scope":{"id":"b39e813030ef3ce72a82896683932a7d","email":"CloudFlare-username","type":"user"},"configuration":{"value":"1.2.3.4","target":"ip"},"created_on":"2016-09-08T14:36:36.770021Z","modified_on":"2016-09-08T14:36:36.770021Z"},"success":true,"errors":[],"messages":[]}

3)CloudFlare API v4のテスト【禁止ルール削除】

先程作成したCloudFlareファイアウォールの禁止ルールを削除してテストします。これは fail2ban unbanアクションに使用されます。
注:これはネストされたcURLコマンドを使用しています。削除するためにルールIDを取得する必要があります。

◆リクエスト例

curl -X DELETE "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$( \
curl -s -X GET "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=1.2.3.4&page=1&per_page=1&match=all" \
-H "X-Auth-Email: CloudFlare-username" \
-H "X-Auth-Key: CloudFlare-API-Key" \
-H "Content-Type: application/json" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' | tr -d '"' | head -n 1)" \
-H "X-Auth-Email: CloudFlare-username" \
-H "X-Auth-Key: CloudFlare-API-Key" \
-H "Content-Type: application/json"

※IPルールが CloudFlareから削除された場合は、success: true がレスポンスされます。

◆レスポンス例

{"result":{"id":"8286c03a200db3b5d09bab0f414dc111"},"success":true,"errors":[],"messages":[]}

4.fail2banとの統合用カスタムCloudFlareアクションの作成

1)CloudFlare fail2banアクションを作成

$ sudo cp -p /etc/fail2ban/action.d/cloudflare.conf /etc/fail2ban/action.d/cloudflare.conf.bak
$ sudo vi /etc/fail2ban/action.d/cloudflare.conf

先にテストしたこの設定をCloudFlareのAPI v4を使用して fail2banのカスタムアクションを作成します。
unbanアクションは、fail2banの bantimeが期限切れになったときに禁止を削除する上からのネストcURLコマンドです。これにより CloudFlare側の IPブラックリストがきれいに保たれます。

設定箇所
・CloudFlareのユーザー名(あなたのメールアドレス)を cfuserに設定。
・CloudFlare API Key を cftoken に設定。

#
# Author: Mike Andreasen from https://guides.wp-bullet.com
# Adapted Source: https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf
# Referenced from: https://www.normyee.net/blog/2012/02/02/adding-cloudflare-support-to-fail2ban by NORM YEE
#
# To get your Cloudflare API key: https://www.cloudflare.com/my-account
#

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart =

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop =

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck =

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:      IP address
#            number of failures
#            unix timestamp of the ban time
# Values:  CMD

actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \
            -H "X-Auth-Email: <cfuser>" \
            -H "X-Auth-Key: <cftoken>" \
            -H "Content-Type: application/json" \
            --data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"Fail2ban"}'

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:      IP address
#            number of failures
#            unix timestamp of the ban time
# Values:  CMD
#

actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$( \
              curl -s -X GET "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=<ip>&page=1&per_page=1&match=all" \
              -H "X-Auth-Email: <cfuser>" \
              -H "X-Auth-Key: <cftoken>" \
              -H "Content-Type: application/json" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' | tr -d '"' | head -n 1)" \
              -H "X-Auth-Email: <cfuser>" \
              -H "X-Auth-Key: <cftoken>" \
              -H "Content-Type: application/json"

[Init]

# Option: cfuser
# Notes.: Replaces <cfuser> in actionban and actionunban with cfuser value below
# Values: Your CloudFlare user account

cfuser = put-your-cloudflare-email-here

# Option: cftoken
# Notes.: Replaces <cftoken> in actionban and actionunban with cftoken value below
# Values: Your CloudFlare API key

cftoken = put-your-API-key-here

2)fail2banのfilter定義

$ sudo vi /etc/fail2ban/filter.d/nginx-dos.conf

[Definition]
failregex = ^<HOST> -.*"(HEAD|GET|POST).*
ignoreregex = \.(?i)(jpe?g|gif|png|bmp|pdf|js|css|woff|eot|ttf|ico|txt|xml|swf|xlsx?|docx?|pptx?)

3)fail2banのJail(ban)定義

$ sudo vi /etc/fail2ban/jail.local

[nginx-dos]
enabled = true
port = http,https
filter = nginx-dos
logpath = /var/log/nginx/access.log
action = iptables-multiport[name=dos, port="http,https", protocol=tcp]
         cloudflare
         sendmail-whois[name=dos, dest=root, sender=fail2ban]
maxretry = 12
findtime = 3
bantime = 7200

このJail(檻)設定内容をまとめると「 /etc/fail2ban/filter.d/nginx-dos.conf フィルターファイルのルールに、3秒間で12回一致したら、そのIPアドレスを1日ブロック」する。CloudFlareのAPI v4 を用いて、IPアドレスを「Block」する。ブロック結果は root宛にメール配信する。

4)起動/自動起動設定

$ sudo /etc/init.d/fail2ban start

5.参考文献

How to Integrate fail2ban with CloudFlare API v4 Guide
https://guides.wp-bullet.com/integrate-fail2ban-cloudflare-api-v4-guide/

以上

About yoshimasa

埼玉県さいたま市在住、2男3女のパパです。Linux系の技術情報を中心にまとめています。1978年2月生まれ。