LB越しの不正アクセスをfail2banを使って防ぐ

こんにちは! grasysの注目若手エンジニア川﨑です。(grasys内ではまだまだ若手ポジション)

今回はGCPのLB経由で来る不正アクセスにfail2banで対処した時の事について書きます。

grasysではECサイトやニュースサイトを運営するお客様がいます。 そのお客様のサイトに悪意をもってCDNが適用されないURLに不正アクセスをしてくるユーザーにだけ何らかの対処をしたいケースに使用しています。

fail2banとは

ログファイルからfilterに定義したルールでIPを割り出し、jailに定義したアクセス回数などのルールを超えたIPに対し定義したactionを実行します。 各webサーバーに機能やアドオンとして持ってるものもありますが、機能も多くwebサーバーに依存しないのでgrasysではfail2banを使用しています。 各種configの例を交えて説明します。 インストールはやディレクトリ構成は公式サイトや参考URLをご確認ください。

fail2banを設定する前に…

fail2banはログファイルから該当のIPを割り出します。 今回はLBを使用しているのでLBのIPでなくクライアントPCのIPを取得したいです。 まずはアクセスログにX-Forwarded-Forを出力するように設定しましょう。

filter

webサーバーのアクセスログからIPを取得する設定ファイルです。 公式にすでにたくさんのものが用意されています。 ログファイルに対して正規表現でアクセス元のIPを取得するようにします。

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

上記のような内容でtest-dos.confという名前でfilter.dに置きます。

failregexのにクライアントのIPが来るように正規表現を書きます。 ignoreregexにはこれが入るものはカウントしないようにします。 webサイトなので画像等へのアクセスと弊社のIPはカウントしないようにします。 この正規表現で意図したIPが取れているかどうかは実際のログファイルに対して下記コマンドでテストすることができます。

fail2ban-regex /var/log/[logfile名]/usr/local/etc/fail2ban/filter.d/[filter名]

これで確認しながら進めることができます。

jail

このファイルでactionやfilterのルールを決めます。 例を元に見ていきましょう。

[DEFAULT]
# filterが読み込むlogファイルを指定します。
apache_access_log = /var/log/httpd/wired_access_log

[test-dos]
# 実際に適用するルールかどうか
enabled = false

# portです。
port = http,https

# ログからIPを検索するfilter名を定義します。
filter = test-dos

# filterが読み込むlogファイルを指定します。
logpath = %(apache_access_log)s

# 20秒間で10回同一IPを見つけたら5秒間bantimeが発生します
maxretry = 10
findtime = 20
bantime = 5

# bantimeが発生した時に動作するactionを定義します。引数を渡すことも可能です。
# 「,」で区切って引数を複数渡すことも可能です
action = banned-hosts[name=https://www.grasys.io/]
         slack[name=test-dos]

# アラートメールの送信先アドレス
destemail = kawasaki@grasys.io

actionの箇所に定義しているのはブロック用のactionと弊社にslackで通知する設定です。

action

jailで定義したルールが適用された場合の動作を定義します。 すでにデフォルトでたくさんのルールが用意されていてLBを使用していない場合にブロックしたいなどはiptables-multiportを使用すればいいと思います。 今回はLB経由で来ているので下記のようなactionで作成したスクリプトを呼び出してます。

action

[Definition]

# actionbanはjailのルールが適用された時にする動作です。
# bashファイルを動かすこともできます。
actionban = sh /fail2ban/script.d/add_banned_hosts.sh <ip> <name>

# actionunbanはjailのbantimeが終了された時にする動作です。
actionunban = sh /fail2ban/script.d/delete_banned_hosts.sh <ip> <name>

[Init]

add_banned_hosts.sh

LB経由なのでiptablesの設定にX-Forwarded-Forで該当ipがある場合にブロックするような設定をしています。

#!/bin/bash

ip=$1
name=$2
iptables -A fail2ban_http_drop -p tcp --dport 80 -m string --algo bm --string "X-Forwarded-For: ${ip}" \
-m string --algo bm --string "${name}" -j DROP

delete_banned_hosts

#!/bin/bash

ip=$1
name=$2
iptables -D fail2ban_http_drop -p tcp --dport 80 -m string --algo bm --string "X-Forwarded-For: ${ip}" \
-m string --algo bm --string "${name}" -j DROP

参考URL

公式GitHub

インストール等参考

grasys三周年 & 半年間の感想

先日grasysが三周年を迎えました!イェイ!! 弊社のスケベ代表 長谷川も喜んでおります!!

そして私事ですが僕も今月の11月で無事に転職して半年が経ちました。 転職前はUnityでWebGLのゲームを作って サーバーサイドもC#で作ってAzure Web Appsを使ってデプロイやサービスの運用をしていました。

転職してからlinuxを初めて触って色々指導してもらいながら四苦八苦しています><

grasysでの仕事はただ単にお客様のインフラを管理するのではなく、今回のようにお客様の問題解決やシステム構成の提案も多いです。 また、時にはアプリケーションのログやコンフィグを読んだり、スロークエリの修正提案、技術検証と幅広い作業をします。 アプリケーションを作るのも楽しかったですが、それとは一味違う面白さとやりがいを感じてます。