Windows Server 2012 リモートデスクトップ IPアドレス制限

More than 3 years have passed since last update.

Windows Server 2012 リモートデスクトップ IPアドレス制限

posted at 2019-11-06

updated at 2019-11-14

はじめに

備忘録と練習を兼ねて初投稿です。
読みづらいところがあればご指摘いただけると嬉しいです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ファイアウォールのルールの追加を行います。
    • リモートデスクトップ接続で使用するポートを変更する方法(PROJECT-GROUP)
  • windowsファイアウォールのルールの名前はサイトの通り「RDP」とします。

PowerShellスクリプト

  • Windowsファイアウォールのルール「RDP」にスコープを追加します。
  • スクリプトと同じディレクトリに次の2つのファイルを出力します。
    • GIP.txt(追加したIPアドレスリスト、上書き)
    • GIPUpdate.log(実行時間と登録した件数、追記)

FWaddRemoteIP.ps1

$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

出力されるファイルはこんな感じです。

GIPUpdate.log

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ファイアウォールでプロファイルをいじっていたら同じ名前のルールが複数できていたことがあったため、配列にしています。
いらないルールを消しておけばいいのですが。。

実行方法

次のようなバッチファイルを作ってタスクスケジューラで定期的に実行しています。

PSexe.bat

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

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

PSexe.bat

powershell -ExecutionPolicy RemoteSigned -File "C:\GIP\FWaddRemoteIP.ps1"

WindowsServer2008R2の場合

  • ルールのスコープが1000件までしか登録できないので、ルールを3つ作っておいて分割して登録する必要があります。
  • PowerShell2.0ではGet-NetFirewallRuleが使えないのでnetshを使う必要があります。

おわりに

VPNとかクライアントのIPを固定するとか上位ネットワークで対応するとか、もっと安全な方法があると思うのですが、今回はどれも許されなかったので、苦肉の策です。

参考記事

  • PowerShellスクリプトを簡単実行
  • リモートデスクトップ接続で使用するポートを変更する方法(PROJECT-GROUP)
  • PowerShell で GitHub に wget(Invoke-WebRequest) できない場合の対処方法
  • WindowsServer2016でfail2banっぽいことをする

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information

What you can do with signing up