#はじめに
備忘録と練習を兼ねて初投稿です。
読みづらいところがあればご指摘いただけると嬉しいですm(_ _)m
#概要
WANからのアクセスが可能で、リモートデスクトップサービスがインストールされたWindowsServerに、Windowsファイアウォールを使ってIPアドレス制限をかける方法です。
PowerShellのスクリプトを使います。
国内のIPアドレスを公開しているサイトからリストを取得し、事前に作成したwindowsファイアウォールのルールにスコープを追加します。
リストはIPv46様のhttps://ipvx.info/country/range/jp/p/ を利用させていただきます。
#環境
- OS
- WindowsServer2012R2 Standard、WindowsServer2016 Standard
- ファイアウォール
- Windowsファイアウォール
- PowerShell
- version4、version5
#準備
- リモートデスクトップの待受けポートは標準のままだとアタックされ放題なので、次のwebサイトを参考に、ポート変更とWindowsファイアウォールのルールの追加を行います。
- windowsファイアウォールのルールの名前はサイトの通り「RDP」とします。
#PowerShellスクリプト
- Windowsファイアウォールのルール「RDP」にスコープを追加します。
- スクリプトと同じディレクトリに次の2つのファイルを出力します。
- GIP.txt(追加したIPアドレスリスト、上書き)
- GIPUpdate.log(実行時間と登録した件数、追記)
$scriptPath = $MyInvocation.MyCommand.Path
$scriptPath = Split-Path -Parent $scriptPath
$GIPFile = $scriptPath + "\GIP.txt"
$logFile = $scriptPath + "\GIPUpdate.log"
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
Write-Output (Get-Date)>>$logFile
Write-Output "GIPの取得を開始します。">>$logFile
try{
$url = "https://ipvx.info/country/range/jp/p/"
$response = Invoke-WebRequest $url
$response.Content >$GIPFile
#1.まずRDPのスコープをanyにします
Get-NetFirewallRule | Where { $_.DisplayName -eq 'RDP'} | Set-NetFirewallRule -RemoteAddress any
$fwRDP = New-object -comObject HNetCfg.FwPolicy2
$myRDPrules = @($fwRDP.Rules | where {$_.Name -eq 'RDP'}) #@()で囲むと要素が1つでも配列になる
$textlist = ($response.Content) -as [string[]]
$lines = $textlist -split "`n"
foreach ($myRDPrule in $myRDPrules){
$lineCount = 0
foreach ($line in $lines) {
if ($line -match "^[0-9]"){
if ($myRDPrule.RemoteAddresses -eq '*'){
$myRDPrule.RemoteAddresses = $line
$lineCount++
}else{
$myRDPrule.RemoteAddresses += (","+ $line)
$lineCount++
}
}
}
Write-Output ("RDPのルール " + $lineCount + " 件のアドレスが許可に設定されました。")>>$logFile
}
}catch{
$Error[0] >>$logFile
}
Write-Output "--------------------------------------------------------------------">>$logFile
出力されるファイルはこんな感じです。
2019年4月19日 11:57:28
GIPの取得を開始します。
RDPのルール 2247 件のアドレスが許可に設定されました。
--------------------------------------------------------------------
#解説
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
httpsにアクセスするためにTLS 1.2 を有効化します。
Get-NetFirewallRule | Where { $_.DisplayName -eq 'RDP'} | Set-NetFirewallRule -RemoteAddress any
定期的な実行を想定しているため、最初にスコープを削除します。
$myRDPrules = @($fwRDP.Rules | where {$_.Name -eq 'RDP'})
Windowsファイアウォールでプロファイルをいじっていたら同じ名前のルールが複数できていたことがあったため、配列にしています。
いらないルールを消しておけばいいのですが。。
#実行方法
次のようなバッチファイルを作ってタスクスケジューラで定期的に実行しています。
powershell -ExecutionPolicy RemoteSigned -File <スクリプトファイルのフルパス>
スクリプトファイルのパスがC:\GIP\FWaddRemoteIP.ps1
の場合、次のようになります。
powershell -ExecutionPolicy RemoteSigned -File "C:\GIP\FWaddRemoteIP.ps1"
#WindowsServer2008R2の場合
- ルールのスコープが1000件までしか登録できないので、ルールを3つ作っておいて分割して登録する必要があります。
- PowerShell2.0ではGet-NetFirewallRuleが使えないのでnetshを使う必要があります。
#おわりに
VPNとかクライアントのIPを固定するとか上位ネットワークで対応するとか、もっと安全な方法があると思うのですが、今回はどれも許されなかったので、苦肉の策です。
#参考記事