WindowsServer2016でfail2banっぽいことをする


はじめに

WindowsServerへのリモートデスクトップ接続を国内IPアドレスのみに限定するの続きっぽい記事です。
WANから接続可能なリモートデスクトップサーバーへのブルートフォースアタックを抑制したいと思い、fail2banにたどり着いたのですが、Windows上で動作させる方法が見つかりませんでした。
ですのでfail2banを実際に使ったことのない者がこの記事を書いています。すみません;

概要

リモートデスクトップ接続に失敗すると、イベントビューアーにログオンタイプ3で失敗の監査が記録されます。
WindowsServer2012R2までは、イベントにIPアドレスが記録されませんでした。(仕様?)
WindowsServer2016では記録されるようになったので、PowerShellとタスクスケジューラを使って次の動作をさせたいと思います。

  • 20分以内に10回ログインに失敗したIPアドレスを拒否する。
    • 拒否の解除は自動で行わない。

今回は該当IPアドレスからのすべてのアクセスを拒否します。
リモートでしかアクセスできないサーバーにはおすすめしません。

環境

  • OS
    • WindowsServer2016 Standard
  • ファイアウォール
    • Windowsファイアウォール
  • PowerShell
    • version5

作業手順

Windowsファイアウォールルールの追加


セキュリティが強化されたWindowsファイアウォールを開き、
【受信の規則】をクリック。

【新しい規則】をクリック。

【カスタム】にチェックして次へ。

【すべてのプログラム】にチェック(デフォルト)を確認して次へ。

デフォルトのまま次へ。

下段、「この規則を適用するリモートIPアドレスを選択してください。」の
【これらのIPアドレス】にチェック、【追加】ボタンをクリック。

「このIPアドレスまたはサブネット」に、拒否していいIPアドレスを1つ以上入力。
(私は過去にアタックしてきたIPを入れていますが、1.1.1.1とかでも良さそう。)
【OK】をクリック。

IPアドレスが追加されたことを確認して次へ。

【接続をブロック】にチェックして次へ。

デフォルトのまま次へ。

ルールの名前は「MyBanRule」にします。

ルールが追加されました。

PowerShellスクリプト

  • Windowsファイアウォールのルール「MyBanRule」にスコープを追加します。
  • 結果を次のファイル名で、スクリプトと同じディレクトリに出力します。
    • MyBanRule.log
FWDeny.ps1
$scriptPath = $MyInvocation.MyCommand.Path
$scriptPath = Split-Path -Parent $scriptPath
$logFile = $scriptPath  + "\MyBanRule.log"

#最新のログイン失敗イベントを抽出
$events = Get-WinEvent -LogName security -FilterXPath "Event[System[Provider[@Name='Microsoft-Windows-Security-Auditing']]] and Event[System[EventID='4625'] and EventData[Data[(@Name='Logontype')] = '3']]" -MaxEvents 1
#イベントをXMLに変換
$eventsXML = [xml]$events.toXML()
#XMLからIPアドレスを抽出
$FaleIpAddress = ($eventsXML.Event.EventData.Data | ? {$_.Name -eq "IpAddress"}).'#text'
Write-Output (Get-Date) >>$logFile
Write-Output ("IPアドレス" + $FaleIpAddress + "がログインに失敗しました。")>>$logFile

#IPが記録されなかったり、ループバックアドレスだった場合はスキップ
if(($FaleIpAddress -ne "-") -and ($FaleIpAddress -notlike "127*")){
    #過去20分のイベントを抽出
    $pastEvents = Get-WinEvent -LogName security -FilterXPath "Event[System[Provider[@Name='Microsoft-Windows-Security-Auditing']]] and Event[System[EventID='4625'] and EventData[Data[(@Name='Logontype')] = '3']] and Event[System[TimeCreated[timediff(@SystemTime) <= 1200000]]]"
    #テキストに変換
    $txtpastEvents = $pastEvents.toXML()
    #調べたIPが何回失敗しているかカウント
    $IpCount = ($txtpastEvents | Select-String $FaleIpAddress).Count
    Write-Output ($IpCount.toString() + "回失敗しています。")>>$logFile

    #10回以上失敗していたら事前に作成したファイアウォールルールのスコープにIPアドレスを追加
    if($IpCount -ge 10){
        $fwDeny = New-object -comObject HNetCfg.FwPolicy2
        $myDenyRule = $fwDeny.Rules | where {$_.Name -eq 'MyBanRule'}
        $myDenyRule.RemoteAddresses += (","+ $FaleIpAddress)

        Write-Output ("IPアドレス" + $FaleIpAddress + "のログイン失敗回数が10回を超えました。")>>$logFile
        Write-Output "接続拒否リストに追加します。">>$logFile


    }

}

Write-Output "--------------------------------------------------------------------">>$logFile

説明

#過去20分のイベントを抽出
$pastEvents = Get-WinEvent -LogName security -FilterXPath "Event[System[Provider[@Name='Microsoft-Windows-Security-Auditing']]] and Event[System[EventID='4625'] and EventData[Data[(@Name='Logontype')] = '3']] and Event[System[TimeCreated[timediff(@SystemTime) <= 1200000]]]"

過去20分をミリ秒で指定しています。
時間を変える場合は1200000を変更してください。
時間ではなく、過去500件のイベントを抽出したい場合は↓

$pastEvents = Get-WinEvent -LogName security -FilterXPath "Event[System[Provider[@Name='Microsoft-Windows-Security-Auditing']]] and Event[System[EventID='4625'] and EventData[Data[(@Name='Logontype')] = '3']]" -MaxEvents 500

件数を変更したい場合はMaxEvents 500500を変更してください。

 #10回以上失敗していたら事前に作成したファイアウォールルールのスコープにIPアドレスを追加
 if($IpCount -ge 10){

何回失敗で拒否するかはこちらの数字で変更してください。

実行バッチファイル

PowerShellスクリプトを実行するバッチファイルを作っておきます。

PSexe.bat
powershell -ExecutionPolicy RemoteSigned -File <スクリプトファイルのフルパス>

スクリプトファイルのパスがC:\fail2ban_win\FWDeny.ps1の場合、次のようになります。

PSexe.bat
powershell -ExecutionPolicy RemoteSigned -File "C:\fail2ban_win\FWDeny.ps1"

タスクスケジューラの設定

失敗の監査イベントが発生したときにバッチファイルを実行するように設定します。


タスクスケジューラを開き、【タスクスケジューラライブラリ】をクリック。

【タスクの作成】をクリック。

任意の名前をつけます。
【ユーザーがログオンしているかどうかにかかわらず実行する】にチェック。

【トリガー】タブをクリック。
【新規】ボタンをクリック。

「タスクの開始」で【イベント時】を選択。

【カスタム】にチェックし、【新しいイベントフィルター】ボタンをクリック。

【ログごと】にチェック。
「イベントログ」で「Windowsログ」を展開し、【セキュリティ】にチェック。

「イベントID」に【4625】と入力。
OKをクリック。

OKをクリック。

【操作】タブをクリック。
【新規】ボタンをクリック。

【参照】ボタンをクリック。

バッチファイル「PSexe.bat」を選択。
【開く】ボタンをクリック。

【開始オプション】にバッチファイルのあるディレクトリを入力。
OKをクリック。

タスクの作成ウィンドウを閉じるときにパスワードを訊かれたら入力して終了です。


タスクが作成されました。

拒否の解除は今回作ったWindowsファイアウォールのルールを開いて、スコープタブから削除します。

おわりに

スコープに何件まで登録できるのかわからないので、あまりにアタックが多いとどうなるかわかりません。

参考記事