はじめに

リモートデスクトップで接続する際に、下記の警告に遭遇することがよくあります。

ほとんどの人が無視して接続していると思いますが、なりすましに気づけないなど好ましい状態ではないのでLet’s Encryptで作った証明書を使ってエラーを出なくしましょう。


証明書の入手

こちらを参考に入手してください。p12形式への変換も行い、そのファイルをWindowsへファイル転送しておいてください。
#上記ではワイルドカード証明書を作っていますが、通常の形式でも問題ありません。

証明書のインポートと適用

自動化も見据えてPowerShellでやってみます。

PowerShellを管理者権限で起動

スタートメニューでPowerShellを検索し、右クリック、「管理者として実行」で起動します。

証明書インポート

以下のコマンドでインポートできます。
“password”は証明書をp12形式にした際に指定したパスワードに置き換えてください。
証明書ファイルのパスも実際のパスに置き換えてください。

PS C:> certutil -p password -importpfx .\certfile.p12
証明書 "CN=*.example.com" がストアに追加されました。

CertUtil: -importPFX コマンドは正常に完了しました。

インポートした証明書をRDPで使うように設定する

まずは、証明書のフィンガープリントを取得します。

PS C:> dir cert:\LocalMachine\My


    ディレクトリ: Microsoft.PowerShell.Security\Certificate::LocalMachine\My


Thumbprint                                Subject
----------                                -------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  CN=*.example.com

上記のXXXXXX…の部分がフィンガープリントです。
複数あるものは有効期限(NotAfter)が最大のものを選ぶ必要があります。
上記の出力ではわからないので下記コマンドを使用してください。

PS C:> dir cert:\LocalMachine\My


    ディレクトリ: Microsoft.PowerShell.Security\Certificate::LocalMachine\My | Format-List

Subject      : CN=*.example.com
Issuer       : CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Thumbprint   : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
FriendlyName :
NotBefore    : 2018/07/16 10:04:30
NotAfter     : 2018/10/14 10:04:30
Extensions   : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, S
               ystem.Security.Cryptography.Oid...}

Subject      : CN=*.example.com
Issuer       : CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
Thumbprint   : YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
FriendlyName :
NotBefore    : 2018/04/21 17:20:13
NotAfter     : 2018/07/20 17:20:13
Extensions   : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, S
               ystem.Security.Cryptography.Oid...}

使う証明書のフィンガープリントがわかったら、下記のコマンドを実行します。
XXXXX…部分を上記で取得したフィンガープリントに置き換えて実行してください。

PS C:> $cert = @{SSLCertificateSHA1Hash="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
PS C:> $path = (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").__path
PS C:> Set-WmiInstance -Path $path -argument $cert
__GENUS                                : 2
__CLASS                                : Win32_TSGeneralSetting
__SUPERCLASS                           : Win32_TerminalSetting
__DYNASTY                              : CIM_ManagedSystemElement
__RELPATH                              : Win32_TSGeneralSetting.TerminalName="RDP-Tcp"
__PROPERTY_COUNT                       : 20
__DERIVATION                           : {Win32_TerminalSetting, CIM_Setting, CIM_ManagedSystemElement}
__SERVER                               : ServerName
__NAMESPACE                            : root\cimv2\terminalservices
__PATH                                 : \\ServerName\root\cimv2\terminalservices:Win32_TSGeneralSetting.TerminalN
                                         ame="RDP-Tcp"
Caption                                :
CertificateName                        : *.example.com
Certificates                           : {0, 0, 0, 0...}
Comment                                :
Description                            :
InstallDate                            :
MinEncryptionLevel                     : 3
Name                                   :
PolicySourceMinEncryptionLevel         : 1
PolicySourceSecurityLayer              : 0
PolicySourceUserAuthenticationRequired : 0
SecurityLayer                          : 1
SSLCertificateSHA1Hash                 : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SSLCertificateSHA1HashType             : 3
Status                                 :
TerminalName                           : RDP-Tcp
TerminalProtocol                       : Microsoft RDP 6.1
Transport                              : tcp
UserAuthenticationRequired             : 0
WindowsAuthentication                  : 0

出力結果のCertificateNameが設定した証明書であり、SSLCertificateSHA1Hashが先ほど取得したものであることを確認して終了です。

おまけ1)RDPでどの証明書が使われているか確認

リモートデスクトップで対象のサーバに接続します。
全画面表示にした際にでてくる、上部のバーの鍵マークをクリックして出てくるダイアログBOXの証明書の表示をクリックします。


おまけ2)フィンガープリント確認と証明書適用を一緒にやる

さらに自動化を見据えてこういう風に書けばコマンドの書き換え不要で流し込んで実行することができます。

PS C:> $cert = dir cert:\LocalMachine\My | 
 where{$_.Subject -match "CN=\*.example.com$" } |
 sort NotAfter -Des | Select -First 1 |
 Foreach{@{SSLCertificateSHA1Hash=$_.Thumbprint}}
PS C:> $path = (Get-WmiObject `
-class "Win32_TSGeneralSetting" `
-Namespace root\cimv2\terminalservices  `
-Filter "TerminalName='RDP-tcp'").__path 
PS C:> Set-WmiInstance -Path $path -argument $cert

参考リンク

参考にさせていただきました。
http://www.atmarkit.co.jp/ait/articles/1309/20/news036.html