OpenVPN Access Server 向け Fail2ban フィルター: real_ip と jail
Access Server は独自のログ形式を書き出すため、既製のフィルターは何にも一致しません。real_ip を軸に固定し、jail を接点ごとに分け、アドレスがプロキシでないことを確認します。
コミュニティの投稿からOpenVPNの jail をコピーし、fail2ban を再起動しても、どのアドレスも永久にブロックされません。原因はほとんど常にログ形式です。Access Server は、既製のフィルターが期待する認証失敗の行を書き出しません。フィルターに触る前に、そもそも記録が存在するかを確認してください。サービスが一度も記録していないものにパターンは一致できないからです。
Access Server ホストで私が使う手順は次のとおりです。記録の形を確認し、固定した式をひとつ書き、実際のログで試し、攻撃を受けている接点ごとに jail を分け、ブロックがファイアウォールまで届くことを確かめます。
失敗の記録が存在することを確認する
Access Server は独自の構造化された行を/var/log/openvpnas.logに書き出し、クライアントのアドレスは syslog 行の先頭ではなく、引用符で囲まれたreal_ipフィールドに入ります。パターンを書く前に、起きたと分かっている失敗ログインを検索してください。
grep -i 'LOG ERR' /var/log/openvpnas.log | tail -20何も出てこない場合、次の容疑者はログレベルです。Access Server には/usr/local/openvpn_as/etc/as.confにログデータベースのデバッグスイッチがあり(DEBUG_LOGDB=1)、変更後はサービスを再起動する必要があります。そのスイッチは、パターンができたら元に戻す診断用の設定として扱い、恒久的な構成とは考えないでください。
ファイルを見ているついでに、どの接点がそこへ書き込むかを確認してください。クライアントポータル、管理画面、トンネル認証の失敗は同じファイルに別々のマーカーで記録され、この違いが後で jail の構成を決めます。
real_ip でフィルターをひとつ固定する
式は狭く保ちます。IP アドレスを含む行をすべて拾うフィルターは、日常的な切断でも人をブロックし、多忙なサーバーではノート PC を閉じただけでロックアウトされたという苦情だけが症状になります。エラー記録だけを対象にし、引用符で囲まれたアドレスを捕捉してください。
# /etc/fail2ban/filter.d/openvpnaccess.local
[Definition]
failregex = ^ .*LOG ERR.*"real_ip": "<HOST>".*
ignoreregex =先頭の空白は飾りではありません。Access Server は記録を字下げするため、そこを軸に固定すれば、同じファイルに書き込む無関係なサービスの行まで拾うことを防げます。記録の先頭がタイムスタンプの場合はその接頭辞に合わせますが、対象にしたいすべての記録に確実に存在するものへ固定してください。
接点ごとの精度が必要なときは、同じ行に接点マーカー(WEB_CLIENT、WEB_ADMIN、VPN)を要求してさらに絞り込みます。三つのパターンを持つ一つのフィルターは、一語だけ違う三つのフィルターより監査しやすいです。
jail を有効にする前に式を試す
本番ログに対して実行していないフィルターは絶対に有効にしないでください。文書化されたテストはフィルターを二度渡します。一度は読み込み、一度は適用のためで、取りこぼした行のレポートこそ読む価値のある部分です。
fail2ban-regex --print-all-missed /var/log/openvpnas.log \
/etc/fail2ban/filter.d/openvpnaccess.local \
/etc/fail2ban/filter.d/openvpnaccess.local > missed.txt一致件数を最初の手順で確認した失敗と比較してください。一致がゼロならパターンが誤りです。認証失敗ではない行に一致するなら広すぎます。拾わないと決めた行をすべて説明できるまでmissed.txtを読んでください。
ログが大きい場合はコピーでこのテストを行い、Access Server を更新するたびに再実行してください。ログ形式は照合する対象のインターフェースであり、安定した API ではありません。
jail はデーモンではなく接点で分ける
一つの Access Server は複数の認証接点を提供します。クライアントと管理者の Web 画面は 943/tcp、トンネルは多くの構成で 1194/udp または 443/tcp です。すべてを覆う単一の jail では、トンネルへの推測が管理者用の経路でもあるアドレスをブロックしてしまい、どの接点が実際に攻撃されているか分からなくなります。接点ごとに独自のポートとしきい値を持つ jail を与えてください。
# /etc/fail2ban/jail.d/openvpnaccess.local
[openvpnas-web-client]
enabled = true
port = 943
protocol = tcp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 3
findtime = 10m
bantime = 1h
[openvpnas-tunnel]
enabled = true
port = 443
protocol = udp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 5
findtime = 10m
bantime = 1h小さなカウンタと短いブロックから始め、実際のトラフィックを一週間観察してから引き上げてください。共有のオフィスアドレスに寛大なしきい値を置くと、一つの NAT の背後にいる全員が罰を受け、トンネル側の強いブロックは、保存された資格情報が夜間に失効した正規のクライアントを切断します。
ブロック、バックエンド、副作用を確認する
再起動後、ステータス出力が jail の存在とカウントを確認する最速の手段です。
fail2ban-client status
fail2ban-client status openvpnas-tunnel次に、ブロックが実際に運用しているファイアウォールまで届くことを確認してください。何も適用しないバックエンド向けに設定された jail は何も守りません。iptables アクションではアドレスが jail の名前を持つチェーンに現れ(f2b-openvpnas-tunnel)、nftables アクションでは fail2ban 自身のテーブルのセットに入ります。想定せずに、ホストが使っている方を確認してください。
ブロックそのものより重要な副作用の確認が二つあります。第一に、real_ipがクライアントのアドレスであり、ロードバランサやリバースプロキシではないことを確かめてください。プロキシの背後では、ブロックはすべてプロキシに当たり、サービス全体を巻き込みます。第二に、解除手順を書いておいてください。02:00 にしきい値を超えるアドレスは、たいてい当番のエンジニアのものです(fail2ban-client set openvpnas-tunnel unbanip 203.0.113.24)。
調整するときは境界を意識してください。Fail2ban は一つの認証接点におけるレート制限であり、アクセス制御層ではありません。MFA、アカウント単位の制限、管理画面を公開インターネットから外すことの代わりにはならず、Access Server には独自の autoban 設定があるため、同じポートに二つのレート制限を重ねる前に確認する価値があります。