Visual Studio入りEC2にRDP接続できなくなったので色々試してみた

2022.08.07

しばたです。

前の記事で作成したVisual Studio入りEC2でいろいろと調査・検証していたのですが、あるとき突然RDP接続できなくなってしまいました。

本記事ではこの事象に対して行った対応について共有します。

TL;DR

最終的に理想的な結果にならなかったので最初に結論を書いておきます。

今回は何らかの理由によりセキュアチャネルが破損しRDP接続出来なくなりました。
セキュアチャネルが破損した際の一般的な対応を行うもVisual Studio入りEC2だと権限不足のエラーとなり解消できず、最終的に当該インスタンスを破棄し新しいインスタンスを作り直すことになりました。

Visual Studio入りEC2は利用可能なユーザーを制限するためにActive Directoryまわりの設定がかなり特殊です。
加えてマネージドサービスであるAWS Managed Microsoft ADでは管理者ユーザーはドメイン環境に対する完全な管理者権限(Domain AdminsEnterprise Admins)を持っていません。
両者の制限により一般的な対応がうまくいかなかったものと推測されます。

何が起きたか?

Visual Studio入りEC2の調査を行い一度インスタンスをシャットダウンしました。
翌日にインスタンスを起動しRDP接続しようとしたところ下図のエラーメッセージが表示される様になってしまいました。

メッセージの内容自体はネットワークレベル認証(NLA)を要求するエラーですが、もともとNLAは有効で前日までは普通に接続できていました。
このため事前の設定不足ではなく新たにセキュリティに関連する何らかの問題が起きてしまった様です。

行った対応

このエラーメッセージが出た時の対応は多岐にわたるのですが、Azure VM向けのこのドキュメントがよくまとまっているので参考になります。

本記事でもこちらの内容に従って対応してみました。

1. SSM Session接続

RDPが使えない状況でしたがSSM Sessionは普通に使えました。
このため以後の対応は全てSSM Session上で行っています。

2. グループポリシーの更新

まずはドキュメントにある通りgpupdate /forceコマンドを使いグループポリシーの適用を試してみました。

gpupdate /force

結果としては何度か適用に失敗したあとにで適用に成功したのですが状況は改善されませんでした。
グループポリシー適用後に改めてインスタンスを再起動しなおしてもダメでした。

ワークアラウンドとしてNLAを無効にする方法もありますが、検証環境でしたしわざわざセキュリティを脆弱にする気も無かったので今回は採用しませんでした。

3. セキュアチャネルの検証

次にTest-ComputerSecureChannelコマンドを使いセキュアチャネルの状態を確認しました。

Test-ComputerSecureChannel -Verbose

結果は以下の様になり、ここでセキュアチャネルが破損していることが分かりました。

PS C:\> Test-ComputerSecureChannel -Verbose
VERBOSE: Performing the operation "Test-ComputerSecureChannel" on target "EC2AMAZ-PK0PF0F".
False
VERBOSE: The secure channel between the local computer and the domain corp.contoso.com is broken.

原因が分かったのであとは復旧してやるだけ、と気楽に構えていたのですがここからが長くなります...

4. セキュアチャネルの復旧

通常であればTest-ComputerSecureChannel -Repairでセキュアチャネルの復旧をしてやります。
SSM Session上でGUIが無いので以下の様な感じでクレデンシャルを指定して実行する必要があります。

$username = "admin@corp.contoso.com" # AWS Managed Microsoft ADの管理者ユーザー
$password = ConvertTo-SecureString "管理者のパスワード" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($username, $password)
Test-ComputerSecureChannel -Repair -Credential $cred

結果は残念ながらアクセス権エラーになってしまいました。
AWS Managed Microsoft ADの管理者ユーザーの権限で実行してるのでこれ以上の権限はユーザーにはありません。

PS C:\> Test-ComputerSecureChannel -Repair -Credential $cred
Test-ComputerSecureChannel : Cannot reset the secure channel password for the computer account in the domain. Operation failed with the following exception: Access is denied. (Exception from HRESULT: 0x80070005
(E_ACCESSDENIED)).
At line:1 char:1
+ Test-ComputerSecureChannel -Repair -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (EC2AMAZ-PK0PF0F:String) [Test-ComputerSecureChannel], InvalidOperationException
    + FullyQualifiedErrorId : FailToResetPasswordOnDomain,Microsoft.PowerShell.Commands.TestComputerSecureChannelCommand

5. コンピューターアカウントパスワードのリセット

次にReset-ComputerMachinePasswordコマンドを使いコンピューターアカウントパスワードのリセットを試みました。
こちらも前節と同様にしてクレデンシャルを指定してやります。

$username = "admin@corp.contoso.com" # AWS Managed Microsoft ADの管理者ユーザー
$password = ConvertTo-SecureString "管理者のパスワード" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($username, $password)
Reset-ComputerMachinePassword -Server "$(hostname)" -Credential $cred

こちらも結果は失敗し「サーバーは使用可能でない」旨のエラーが出てしまいました。

PS C:\> Reset-ComputerMachinePassword -Server "$(hostname)" -Credential $cred
Reset-ComputerMachinePassword : Cannot reset the secure channel password for the computer account in the domain. Operation failed with the following exception: The server is not operational.
.
At line:1 char:1
+ Reset-ComputerMachinePassword -Server "$(hostname)" -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (EC2AMAZ-PK0PF0F:String) [Reset-ComputerMachinePassword], InvalidOperationException
    + FullyQualifiedErrorId : FailToResetPasswordOnDomain,Microsoft.PowerShell.Commands.ResetComputerMachinePasswordCommand

6. ドメインからの離脱

ここまで全ての手順がダメでした。
仕方なく「一旦ドメインから離脱してその後EC2を再起動すれば自動でAWS License Managerが再参加させてくれるだろう。」と考えました。

ドメインからの離脱はRemove-Computerコマンドで行えます。
通常であればAWS Managed Microsoft ADの管理者ユーザーで何の問題もなく実行できるはずです。

$username = "admin@corp.contoso.com" # AWS Managed Microsoft ADの管理者ユーザー
$password = ConvertTo-SecureString "管理者のパスワード" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($username, $password)
Remove-Computer -Credential $cred -Force

管理者ユーザーの権限でコマンドを実行したのですが、予想に反してアクセス権エラーで離脱できませんでした。

PS C:\> Remove-Computer -Credential $cred -Force
Remove-Computer : Failed to unjoin computer 'EC2AMAZ-PK0PF0F' from domain 'corp.contoso.com' with the following error message: Access is denied.
At line:1 char:1
+ Remove-Computer -Credential $cred -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (EC2AMAZ-PK0PF0F:String) [Remove-Computer], InvalidOperationException
    + FullyQualifiedErrorId : FailToUnjoinDomain,Microsoft.PowerShell.Commands.RemoveComputerCommand

正直この結果は全く予想できませんでした...
「なんで管理者なのにドメインから離脱できないの???」って感じです。

ここからは予想になるのですが、前の記事で軽く紹介した様にAWS License Managerによるドメイン参加処理はかなり特殊です。
AWSが管理するAWS ReservedOU配下にインスタンス毎専用のOUを新規作成したうえでそこにコンピューターオブジェクトを配置する様になっています。
このため管理者であってもユーザーには離脱の権限が無いんだと思います。

実際自由にドメインから離脱できてしまうとグループポリシーによる制限も適用できずに不正な利用ができてしまいます。
このため制限されているのでしょう。

EC2の再作成

ここまでやって復旧を諦めEC2を再作成することに決めました。

EC2の再作成自体は簡単ですがその前に既存インスタンスに対するユーザーの関連付けを解除してやる必要があります。
マネジメントコンソールからAWS License Managerを開き、インスタンス一覧から削除対象のインスタンスを選び詳細画面を表示します。

画面下部で割り当てられているユーザーを選択し「ユーザーの関連付けを解除」をクリックします。

確認画面が表示されるので解除ボタンをクリックして確定させます。

解除処理が開始されます。

少し待つと関連付けが解除されます。

ユーザー数ぶん繰り返し関連付けされたユーザーが0人になるまで繰り返します。

あとはEC2インスタンスを終了するだけです。

AWS License Manager側のステータスも「終了済み」になります。
(この情報はしばらく待つと消えます。ただ、EC2インスタンスの情報よりは長く残ります)

あとは新しいインスタンスを作り、ユーザーを関連付けしなおします。
具体的な作成手順は割愛します。

(新しいインスタンスi-0d163b2b9bb1a8664にユーザーを関連付けしなおせばOK)

以上で完了です。

補足

当たり前ですがインスタンスを削除したあともActive Directory側情報は残り続けています。

ただ、インスタンスの状態はAWS License Managerで把握可能なのでそのうち自動で更新してくれるんじゃないかと予想しています。
こちらはもうしばらく待ってどうなるかを追記したいと思います。

追記 : トラブルシュート用SSMドキュメント

記事を公開したあとで気が付いたのですが、AWSにはトラブルシュート向けのSSMドキュメントがあるのを失念してました...

もうインスタンスを作り直してしまったので動作確認はできませんが、最初ににAWSSupport-TroubleshootRDPを試せばよかったなと思った次第です。

最後に

以上となります。

セキュアチャネルが破損してしまった根本原因は不明ですが、まあ、調査の過程で私がなにかやらかしたんだと思います。そうでなくてもセキュアチャネルの破損は「稀によくある」系の障害なので本当に運が悪かっただけかもしれません。

結果としてはインスタンスを再作成することになりましたが、本記事の内容で対応できるケースもあるかもしれないので公開しておきます。
この内容がみなさんの役に立てば幸いです。