はじめに
こんにちは、サイオステクノロジーの佐藤 陽です。
以前、PowerShell – Exchange Onlineに証明書を使用して接続する –の記事にて、自己証明書を用いてExchange Onlineに接続する方法が紹介されていました。
今回は、その中で紹介されている「証明書オブジェクトを使用する方法」において、Azure KeyVaultに保管されている証明書を使って接続を試みたいと思います。
環境
今回は、DockerHubにて提供されているLinux PowerShellのイメージを利用し、PowerShellコンテナからExchange Onlineへのアクセスを試みます。
環境は以下の通りです
- WSL2(Ubuntu 20.04)
- Docker
- Powershell (Linux Image – Ubuntu 20.04)
- Exchange Online PowerShell V2
- Azureへのアプリケーションの登録およびExchange Onilne PowerShell V2のインストール方法に関してはこちらを参照ください。
手順
自己証明書の作成
初めに、Exchange Onlineへのアクセスを承認するための自己証明書を作成します。
Azure KeyVaultには自己証明書を生成する機能が備わっているため、今回はそちらを利用します。
Azure KeyVaultリソースのCertificatesブレードを選択し、新規でCertificateを生成します
各種パラメータは以下のように登録します。
Subjectに関しては必要な内容を適宜入力してください。
生成が完了したら、Certificateからcerファイルをダウンロードします。
ダウンロードしたcerファイルを、ExchangeOnlineへアクセスするアプリケーションのへアップロードします。
以上で各種証明書の登録が完了です。
PowerShellからAzureへアクセス
次にPowerShellからAzureのテナントへ接続します。
接続にはPoweshellのCmdletであるConnect-AzAccountを利用します。
ログイン方法としてはいくつかあるのですが、今回はパスワードレスを意識して実装しているため証明書ベースのログインを行います。
証明書の作成に関して、Windows PowerShellであればNew-SelfSignedCertificateのCmdletが用意されていますが、今回はLinux Powershellを使用しているのでopensslを使って証明書を作成します。
#秘密鍵を作成
openssl genrsa 2048 > private-key.pem
#csrファイルを作成
openssl req -new -key private-key.pem > my-request.csr
#crtファイルを作成
openssl x509 -req -in my-request.csr -signkey private-key.pem -out public-key.crt -days 30
#pfxファイルを作成
openssl pkcs12 -export -in public-key.crt -inkey private-key.pem -out my-identity.pfx
作成が完了したら、ログイン対象のアプリケーションのCertificateにcrtファイルを登録します。
次に、pfxファイルをUbuntuの証明書ストアに登録します
$pathToPfx = '<pfx file path>'
$exportPassword = '<pfx export password>'
$storeName = [System.Security.Cryptography.X509Certificates.StoreName]::My
$storeLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new($storeName, $storeLocation)
$flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pathToPfx, $exportPassword, $flag)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($Certificate)
$store.Close()
$Certificateに証明書の情報が含まれていればOKです。
では最後にストアに登録した証明書の情報を用いて、Azureにアクセスします。
$tenantId = '<Tenand Id>'
$appId = '<Application Id>'
Connect-AzAccount -ApplicationId $appId -Tenant $tenantId -CertificateThumbprint $certificate.Thumbprint
なお、この後にKeyVaultにアクセスするため、ログインしたアプリケーションに対して必要な権限を付与しておいてください。
PowerShellからExchangeOnlineへアクセス
Azureへのログインが完了したら、以下のスクリプトでKeyVaultにアクセスし、Certificate情報を取得します
$AzKeyVaultName = '<Key Vault Name>'
$CertificateName = '<Certificate Name>'
$KeyVaultCertificateSecret = Get-AzKeyVaultSecret -VaultName $AzKeyVaultName -Name $CertificateName -AsPlainText
$Certificate = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList ([Convert]::FromBase64String( $exoKeyVaultCertificateSecret )), '', 'DefaultKeySet'
次に、生成した証明書オブジェクトを用いてExchangeOnlineに接続します
$Organization = '<Organization>'
$AppId = '<Application Id>'
Connect-ExchangeOnline -Organization $Organization -AppID $AppId -Certificate $Certificate -ShowBanner:$False
これでAzure KeyVaultに保管してある証明書を用いて、ExchangeOnlineにアクセスすることが出来るようになりました。
最後にExchangeOnlineへの接続を切断することも忘れないようにしましょう!
Disconnect-ExchangeOnline
おまけ
PowerShellのコンテナからExchangeOnlineにアクセスする場合、以下のようなエラーが発生する場合があります
Error Acquiring Token: System.Net.Http.HttpRequestException: Resource temporarily unavailable (login.microsoftonline.com:443)
これはWSLのDNSのドメイン設定が問題のようなので、/etc/resolve.confに適切なDNSサーバーを割り当てると解消します。
最後に
Azure KeyVaultを利用することでExchangeOnlineへのパスワードレスなアクセスを実現できました。
是非みなさんも試してみてください!