セイテクエンジニアのブログ かつて山市良と呼ばれたおじさんのブログ vol.54 Azure&Entra IDの情報取得、スクリプト大作戦
2024年10月24日配信
執筆者:山内 和朗
Microsoft AzureやMicrosoft Entra IDの情報をスクリプトから取得したい。それも、それらを管理する専用のPowerShellモジュールを使用せずに。その答えは、Microsoft AzureおよびMicrosoft GraphのREST APIにありそうです。その前に、Azure PowerShellのスクリプト化に挑戦し、その課題を洗い出します。
Microsoft Azureのリソースの情報を取得する方法には、Azureポータルを使用する方法と、Azure PowerShellモジュールやAzure CLI(コマンドラインインターフェイス)を使用する方法がまず思いつきます。いずれも、Webブラウザーベースの認証、それも通常は多要素認証(MFA)をパスした上でのアクセスになります(画面1)。なお、Microsoft Entra IDやMicrosoft 365のコアサービス、Microsoft Intuneへのアクセスには、一部Azure PowerShellモジュールを使用できるものもありますが(Get-AzADUserなど、ただし現在は非推奨*1)、Microsoft Graph PowerShellモジュールを使用する(Get-MgUserなど)のが一般的です。
*1 重要なお知らせ: Azure AD PowerShell および MSOnline PowerShell モジュールの廃止(2024-04-07)|Japan Azure Identity Support Blog
画面1 AzureポータルのAzure PowerShellによるAzure仮想マシン(VM)の一覧の取得
最初に、Azure PowerShellのスクリプト化に挑戦しますが、最終的には専用のPowerShellモジュールやAzure CLIをインストールすることなしに、「Azure REST API」(Microsoft Learn)や「Microsoft Graph REST API」(Microsoft Learn)にスクリプトからアクセスして、情報を取得することを目指します。Azure PowerShellを使用するには、管理者としてモジュールをインストールする必要があるため、その手間を取り除くとともに、環境に依存せずに(Linuxなどの別のOS環境を含む)情報を取得したいからです。そのため、Azure PowerShellのインストール方法については説明しません。以下のドキュメントを参照してください。
Windows に Azure PowerShell をインストールする|Azure PowerShell(Microsoft Learn)
Azure PowerShellでAzureのテナントに接続する際のConnect-AzAccountコマンドレットは、Webベースの認証ダイアログボックスを表示して、資格情報の入力を求めます。つまり、ユーザーによる対話的な操作を経てからでないと、Azure PowerShellの他のコマンドレット(例えば、Azure VMの一覧を取得するGet-AzVM)を実行できないわけです。
ConvertTo-SecureStringを使用してプレーンテキスト(平文)のパスワードを、セキュリティで保護された文字列(System.Secure.SecureString)に変換し、ユーザー名と組み合わせて資格情報を作成してあげれば、対話的なやり取りを行うことなく、Azure PowerShellの任意のコマンドレットを実行することができます(画面2)。なお、この方法を使用した場合に表示される「警告」はすごく重要なことなのですが、後ほど触れます。また、同じサブスクリプションに複数のテナントが紐づいている場合はテナントIDの指定も必要です(以下の#コメントアウト部分)。
#$tenantid = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
ドメイン名" |
画面2 ユーザー認証を含めてすべてPowerShellでスクリプト化。警告メッセージについては後ほど
実行するスクリプトにプレーンテキスト(平文)のパスワードが埋め込まれていることは、自動化の上でセキュリティを極端に低下させる要因になります。このセキュリティ問題を緩和する方法の1つは、次のようにして、セキュリティで保護された文字列を、暗号化された標準文字列に変換してスクリプトの外部のテキストファイルに保存することです。
$password = ConvertTo-SecureString "YOURPASSWORD" -AsPlainText -Force $password | ConvertFrom-SecureString -key (1..16) | Set-Content "~\azuresecret.txt" #$password | ConvertFrom-SecureString | Set-Content "~\azuresecret.txt" |
(プレーンテキストで表示)
-keyパラメーターは、別のユーザーによる使用を想定したものです。暗号化したのと同じユーザーのみが使用する場合は、-keyパラメーターを省略できます。その場合、別のユーザーは、テキストファイルからセキュリティで保護された文字列を生成することはできません。-keyパラメーターを使用する場合、セキュリティで保護された文字列や、暗号化された標準文字列は、このテキストファイルにアクセスできるユーザーならだれでもプレーンテキストに戻すこともできることに注意してください。
暗号化された標準文字列を含むテキストファイルを読み取れるユーザーは、次のスクリプトを実行することで、セキュリティで保護された文字列を取得し、資格情報を作成して使用することができます(画面3)。
$passwordfile = "~¥azuresecret.txt" $password = Get-Content $passwordfile|ConvertTo-SecureString -key (1..16) #$password = Get-Content $passwordfile|ConvertTo-SecureString $username = "ユーザー名@FQDNドメイン名" $cred = New-Object System.Management.Automation.PSCredential($username , $password) Connect-AzAccount -Credential $cred |
画面3 プレーンテキストのパスワードをセキュリティで保護された文字列に変換後、さらに暗号化された標準文字列に変換して外部テキストファイルに保存。そのテキストファイルから文字列を取り出してセキュリティで保護された文字列に変換して使用
ここまでのAzure PowerShellのスクリプト化の例は、スクリプトの内部であれ、外部であれ、プレーンテキスト(平文)パスワードがそのまま、または復元可能な状態で存在する必要があります。暗号化された標準文字列として外部ファイルに保持することでセキュリティは緩和されますが、あくまで“緩和”されるだけです。
言い忘れていましたが、今回スクリプトの実行に使用した資格情報は、Azureサブスクリプションの管理者(従来のサブスクリプション管理者やアカウント管理者、共同管理者、または同等のAzureのロールが割り当てられたユーザー)のものであり、もし外部に情報が漏れた場合、Azureサブスクリプションのリソースすべてが侵害されるセキュリティ上の高いリスクがあります。それだけではありません、Microsoftは2024年から段階的に、AzureポータルやMicrosoft Entra管理センター、Azure PowerShell、Azure CLIなど、すべてのAzureサインイン試行に対して、スマートフォンの「Authentication」アプリや電話などによる多要素認証(MFA≪Multi-Factor Authentication≫)を必須にすることを進めています。実は、今回のテストは一時的にユーザーのMFAをオフにして行いました。MFAが有効な場合、そもそも対話型認証のスクリプトによる自動化はできなくなります(画面4)
Azure やその他の管理ポータルの必須多要素認証の計画|Microsoft Entra(Microsoft Learn)
画面4 Azureへのサインインに使用するユーザーでMFAが有効になっている場合(今後、すべてのサインインに段階的に必須化)、対話型認証をスクリプトで自動化することはできない
最後に、画面2の“警告: Authentication with a username and password at the command line is strongly discouraged.(コマンドラインでのユーザー名とパスワードによる認証は、強く推奨されません。)”に注目しましょう。提示されているURLリンク(https://go.microsoft.com/fwlink/?linkid=2276971)を見れば分かるように、ここまで紹介したAzure PowerShellのスクリプト化は、「対話型認証(Interactive authentication)」を無理やりスクリプト化したものということができます。
Azure PowerShell から Azure にサインインする|Auzre PowerShell(Microsoft Learn)
自動化のためには、以下のドキュメントで説明されているように、最小限の特権を持つプリンシパルによる「非対話型認証(Noninteractive authentication)」を使用するべきなのです。その1つが「サービスプリンシパル」の使用です。サービスプリンシパルは、Azureの通常のユーザー(ユーザープリンシパル)とは異なり、アプリケーションが使う資格情報のセットであり、MFAやAzureの条件付きアクセスの対象外です。Azureポータルへのサインインには使用できません。また、必要最小限のリソースに対するアクセス許可に制限できます。次回は、サービスプリンシパルの作成とその資格情報を使用したスクリプト化に挑戦します。
サービス プリンシパルを使用して Azure PowerShell にサインインする|Auzre PowerShell(Microsoft Learn)