#014: Entra Joined な VMにMacからEntra認証できず、別の方式を検討

※本記事は、個人の意見および個人的活動を記したものであり、会社を代表するものではありません

検証したけどやっぱりできなかったねー、別の方式を検討したよという記事を１つ。
記録しながら試していたので、出来なかった事もせっかくなので記事にすることにした。
いつか参照するかもしれない、「あー、あの時どうやったっけなー」となった時の自分用の記録。
参考にしたのは以下のドキュメント。

https://learn.microsoft.com/en-us/entra/identity/devices/howto-vm-sign-in-azure-ad-windows

# 1. VMのOSローカルアカウント管理をいい加減やめたい

VMを構築すると、VMのOSローカルのアカウント管理は運用を考える上で面倒なことの１つ。

- 誰がVMにアクセスできるか
- パスワードポリシー(長さ、複雑さ、アカウントロック)
- パスワード変更ルール(利用後は必ずリセット)
- 管理者・開発者・運用担当者などのユーザーを分けて権限も分ける

など、Entraとは別に管理しなければならないのでちょー面倒くさい。。

## 1-1. Windowsだけに許された便利機能「VMのEntra認証」

なんとかEntraIDで認証できるようにしたいという思いから、MSドキュメントを見ながら試行錯誤してみたが、これができるのはAAD Joined以外にもOSの縛りがあった。

- VMのOS
    - Windows Server の 「2019 Datacenter Edition」以降
    - Windows Desktop の 「10 1809」以降

https://learn.microsoft.com/en-us/entra/identity/devices/howto-vm-sign-in-azure-ad-windows

- 接続元のクライアントOS
    - パスワード、もしくは制限されたパスワードレス（？）でログインする場合
        - Widows Desktop の 「10 20H1」以降
    - パスワードレスでログインできるようにする場合
        - Windows 11 (KB5018418)以降
        - Windows 10 20H2 (KB5018410)以降
        - Windows Server 2022 (KB5018421)以降

https://learn.microsoft.com/en-us/entra/identity/devices/howto-vm-sign-in-azure-ad-windows#log-in-using-passwordlimited-passwordless-authentication-with-microsoft-entra-id

Macではそもそもできなかったー。

::: note
VMのOSの制約はドキュメントの一番上の方に記載されているが、接続元のクライアントOSの制約は、中盤ぐらいに記載されている。どちらも一番上の方にまとめて書いておいて欲しかった。。
:::

# 2. VMのEntra認証奮闘ログ

参考にしたドキュメントでは、VMにEntra IDでログインできるようにするまでのステップとして、以下３が記載されている。

- Windows VMをAzure AD Joinedにする（AADLogin拡張機能のインストール）
- VMにアクセスするEntraユーザーにロールを割り当てる
- Entra認証でWindows VMにログインする

上記以外の内容として、条件付きアクセスポリシーやらAzure Policyを使ってEntraIDでログインできるVMを制限したりする方法が記載されているが、単純にログインできるようにするには上記３ステップがあれば良い。

## 2-1. AADLogin拡張機能のインストール

既存のVMに対して拡張機能をインストールするだけでAADJoinedなOSになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/c6b59296-b9b7-be35-1809-fac9b0b60955.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/e1a5c5fc-d769-ca6f-d7d3-85cceead5516.png)

パラメータは何も必要なし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/47d9c999-77cc-5ea8-7a14-5f81e07efd98.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/125f4b35-2ffa-f765-aa57-a1608c1583ab.png)

### 2-1-1. AADJoinedの確認方法

VMにBastionかRDPでリモートログインし、「dsregcmd /status」コマンドを実行して「AzureAdJoined」が「Yes」になっていることを確認する。

```bash
Microsoft Windows [Version 10.0.20348.2655]
(c) Microsoft Corporation. All rights reserved.

C:\Users\satoadmin>dsregcmd /status

+----------------------------------------------------------------------+
| Device State                                                         |
+----------------------------------------------------------------------+

             AzureAdJoined : YES <- ここね
          EnterpriseJoined : NO
              DomainJoined : NO
               Device Name : AdminHost

+----------------------------------------------------------------------+
| Device Details                                                       |
+----------------------------------------------------------------------+

                  DeviceId : 92xx95
                Thumbprint : DDxxDA
 DeviceCertificateValidity : [ 2024-09-06 22:44:14.000 UTC -- 2034-09-06 23:14:14.000 UTC ]
            KeyContainerId : dfxx14
               KeyProvider : Microsoft Platform Crypto Provider
              TpmProtected : YES
          DeviceAuthStatus : SUCCESS

+----------------------------------------------------------------------+
| Tenant Details                                                       |
+----------------------------------------------------------------------+

                TenantName :
                  TenantId : acxxd4
               AuthCodeUrl : https://login.microsoftonline.com/acxxd4/oauth2/authorize
            AccessTokenUrl : https://login.microsoftonline.com/acxxd4/oauth2/token
                    MdmUrl :
                 MdmTouUrl :
          MdmComplianceUrl :
               SettingsUrl :
            JoinSrvVersion : 2.0
                JoinSrvUrl : https://enterpriseregistration.windows.net/EnrollmentServer/device/
                 JoinSrvId : urn:ms-drs:enterpriseregistration.windows.net
             KeySrvVersion : 1.0
                 KeySrvUrl : https://enterpriseregistration.windows.net/EnrollmentServer/key/
                  KeySrvId : urn:ms-drs:enterpriseregistration.windows.net
        WebAuthNSrvVersion : 1.0
            WebAuthNSrvUrl : https://enterpriseregistration.windows.net/webauthn/acxxd4/
             WebAuthNSrvId : urn:ms-drs:enterpriseregistration.windows.net
    DeviceManagementSrvVer : 1.0
    DeviceManagementSrvUrl : https://enterpriseregistration.windows.net/manage/acxxd4/
     DeviceManagementSrvId : urn:ms-drs:enterpriseregistration.windows.net

+----------------------------------------------------------------------+
| User State                                                           |
+----------------------------------------------------------------------+

                    NgcSet : NO
           WorkplaceJoined : NO
             WamDefaultSet : NO

+----------------------------------------------------------------------+
| SSO State                                                            |
+----------------------------------------------------------------------+

                AzureAdPrt : NO
       AzureAdPrtAuthority :
             EnterprisePrt : NO
    EnterprisePrtAuthority :

+----------------------------------------------------------------------+
| Diagnostic Data                                                      |
+----------------------------------------------------------------------+

        AadRecoveryEnabled : NO
    Executing Account Name : xxx\xxx
               KeySignTest : PASSED

        DisplayNameUpdated : YES
          OsVersionUpdated : YES
           HostNameUpdated : YES

      Last HostName Update : NONE

+----------------------------------------------------------------------+
| IE Proxy Config for Current User                                     |
+----------------------------------------------------------------------+

      Auto Detect Settings : YES
    Auto-Configuration URL :
         Proxy Server List :
         Proxy Bypass List :

+----------------------------------------------------------------------+
| WinHttp Default Proxy Config                                         |
+----------------------------------------------------------------------+

               Access Type : DIRECT

+----------------------------------------------------------------------+
| Ngc Prerequisite Check                                               |
+----------------------------------------------------------------------+

            IsDeviceJoined : YES
             IsUserAzureAD : NO
             PolicyEnabled : NO
          PostLogonEnabled : YES
            DeviceEligible : NO
        SessionIsNotRemote : NO
            CertEnrollment : none
              PreReqResult : WillNotProvision

For more information, please visit https://www.microsoft.com/aadjerrors
C:\Users\satoadmin>
```

### 2-1-2. 拡張機能のインストールに失敗し、デバイス登録できないケース

前に一度でも同じ名前のVMに対してAzure AD Windows Login拡張機能をインストールしている場合、Entraのデバイス管理機能にて以前にインストールした時のデバイス情報が残っており、重複が発生するため、拡張機能のインストールに失敗する。

::: note
IaCをやっている場合はハマるポイント。VM拡張機能を登録する前に、デバイス情報を削除するスクリプトを実行できるようにした方が良い。
:::

以下デバイス管理画面のaudit logで失敗した登録処理のログ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/e4aaa13a-e40f-a61b-59d2-f86219f8a7cb.png)

詳細を確認すると、「Status reason」に「ObjectAlreadyExistsException」というエラーが発生していることがわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/83fe9ef3-3451-21a9-a28b-15cd5de87e91.png)

これを解消するためには、一度このデバイスを削除して、VMの拡張機能を再登録すれば解消する。

## 2-2. VM利用ユーザーへのAzureロール割り当て

OSの設定以外にも、ログインユーザー自体にもVMにログインできるようにするためのロールを割り当てる必要がある。

- 仮想マシン管理者ログイン
- 仮想マシンユーザーログイン

ロールを削除すればVMにアクセス出来なくなるので、これでOSローカルなユーザーアカウント管理やパスワード管理から解放される。これは便利。

おーっし、あとはRDPでログインを確認するだけー！

## 2-3. Macは対象外。。

ログイン対象ユーザーへRoleを割り当てるなどの処理を行い、いざログインという段階のところまで読み進めたドキュメント。

ここにきて、MacからはEntra認証によるRDP接続はできなことが発覚。。

最初の方に書いておいて欲しかった。。

https://learn.microsoft.com/ja-jp/entra/identity/devices/howto-vm-sign-in-azure-ad-windows#log-in-using-passwordlimited-passwordless-authentication-with-microsoft-entra-id

実際にログインしてみるが、やっぱりログインできない。

えー、、って感じ。

# 3. Entra認証の代替案

MacではWindows VMへのRDP時にEntra認証ができないということがわかったが、この状態でできるだけVMへのアクセスをセキュアにしたいので、今までに得た知識をもとに方針を以下のようにしてみた。

## 3-1. VMへの接続方式の検討

現時点で、VMへの接続方法は以下２つ。

- P2S VPNでEntra認証で接続後、普通にRDP接続：「P2S VPN方式」とする
- KeyVaultでパスワード管理した状態でBastion接続：「KeyVault方式」とする

VMアクセスユーザーにはアクセス情報の提供を限定しつつ、VM管理者側でアクセス制御できる方法が望ましい。

### 3-1-1. P2S VPN方式のメリットとデメリット

前段でVNetへの接続時にEntra認証が必要なので、RDP時のVMローカルOSアカウントだけよりはセキュアになる。

Entra認証とRDP接続時のVMローカルOSアカウントの認証、２つのアカウントを管理する必要がある。VMを利用するユーザーにVMローカルOSアカウントのパスワードを教える必要があるため、結局今までとおなじようなパスワード管理作業が必須になりそう。

### 3-1-2. KeyVault方式のメリットとデメリット

RDP時にVMローカルOSのパスワードは教える必要がないので、パスワードの流出は限りなく低くなる。

ただし、VMやBastionアクセスできるユーザーならパスワードレスでログイン出来てしまう。

## 3-2. KeyVault方式で決定

P2S VPN方式とKeyVault方式、どちらもセキュアではあるものの、VMへアクセスするユーザーへの提供情報がより少ないのはKeyVault方式。

OSローカルアカウントのパスワードを教える必要がなく、かつパスワードの変更やリセットなどの運用を自動化できる余地がある。

また、どちらの方式においても、VMへのアクセス権限はEntra側でロール制御できる。

# 4. 今後のVM管理方式

今回も含めて、結構時間を使ってVMアクセス方式を確認してきたが、それは単に「VMアカウント管理を単純にして、パスワード管理を手元でやりたくない」という思いから。

今までの検証を踏まえ、今後は後者のKeyVaultによるパスワード管理方式にすることにした。

- KeyVaultへのアクセス制限
    - KeyVaultへのアクセスを特定IP（ローカルPCのパブリックIP、BastionSubnet、KeyVault利用Azureサービス）からのみに制限
    - KeyVaultのシークレットへのアクセスをKeyVaultのアクセスポリシーを用いて特定ユーザーおよび特定のサービスプリンシパルへ限定
    - パスワードの変更はAzure Functionsで自動化（サービスプリンシパルを用いてアクセス）
- VMへのアクセス制限
    - Public IP/RDPは公開せず、Bastion経由でのアクセス限定とする
    - OSローカルユーザーのPasswordは公開せず、KeyVault参照方式とする
    - Bastion参照権限は特定ユーザーにのみ付与する（すべてのユーザーからの参照をDenyとし、特定ユーザーを除外するという感じ）

次回はこの方式をAzure Portalで実装してみる。