Windows 11からはTPMが必須となったことで、Hyper-V上のWindows 11仮想マシンでもTPMを有効にして使うのが一般的となりました。そのTPMを有効にしたWindows 11仮想マシンを別のホストマシンに移転させるには仮想マシンイメージだけでなく証明書が必須なことは知られていますが、移転先のホストマシンの証明書の管理にも注意が必要です。
概要
Windows 11をHyper-VのゲストOSとして利用する場合、TPMの扱いについて注意する必要があります。
よく知られている問題としてはゲストOSに対応する証明書の管理に関することですが、場合によっては別の証明書の管理も重要になります。
ここではそれらの管理手順とそれらが必要な理由、および好ましい運用方法について説明します。
厄介なWindows 11のインストール要件
Windows 10からWindows 11にアップグレードする場合、最大の問題となるのはインストール要件です。
Windows 8.1/8/7からWindows 10への無償アップグレードでは、Microsoftが自由にクライアント環境をコントロールできるWindows 10というプラットフォームに移行させることで、徐々にパソコンハードにかかる負荷を増大させて古いパソコンからの買い替えを促進させることでした。
Windows 11では更に買い替えを加速させるために、それまでパソコンメーカーが重要視していなかったセキュアブートとTPMをアップグレードの必須要件としたため、市場のおよそ半数のパソコンがWindows 11へアップグレードできなくなりました。これらのパソコンにはハード的には対応していてもメーカーが無効に設定して出荷したため、未対応パソコンとして扱われるものもあります。
これらのインストール要件はHyper-Vで運用する仮想マシンでも変わりありません。
正式リリース前にWindows Insider Programで提供されていたWindows 11は、TPMに対応していない仮想マシンでもインストールできたのですが、正式リリース後は仮想マシンでもセキュアブートやTPMが必須となりました。
そのためHyper-Vの仮想マシンの設定を見てみると「トラステッド プラットフォーム モジュールを有効にする」という項目がありました。トラステッド プラットフォーム モジュールとはTPMのことです。
これ幸いと何も考えずにTPMを有効化し、Windows 11を仮想マシンにインストールして使っていました。セキュアブートはデフォルトで有効になっており、インストール要件を満たすので問題ありません。
Windows 11仮想マシンの移転で問題発生
パソコンの調子が悪くなりクリーンインストールすることにしました。Hyper-Vの仮想マシンはバックアップから戻し、仮想マシンをインポートすることでHyper-Vマネージャーに登録できました。
ところが、仮想マシンを起動しようとしたところ、このようなダイアログが表示されて起動できません。
いろいろ調べてみると、仮想マシンでTPMを有効化した場合に仮想マシンを移転するには仮想マシンファイルの他に「シールドVMのローカル証明書」というものが必要だということが分かりました。
移行元のパソコンはクリーンインストールで既に消してしまったので、証明書をエクスポートすることはできません。結局この時は新しい仮想マシンを作って、移行した仮想マシンのディスクをマウントさせることで起動することができました。
Hyper-V上のTPMを有効にした仮想マシンを移転するには、仮想マシンの構成ファイルの他にシールドVMのローカル証明書にある2つの証明書を秘密キー付きでエクスポート/インポートする必要があるというのが、現在、広く知られていることです。
証明書の管理ツールはスタートメニューで「cert」を検索すると「ユーザー証明書の管理」と表示されるのでそれを起動します。
新たな問題「ガーディアン'UntrustedGuardian'は秘密キーを持っていないため所有者になることはできません」
新しいパソコンを購入したのでHyper-V上の仮想マシンも移行することにしました。今度は仮想マシンの構成ファイルに加えて証明書もエクスポートしたので準備万端です。
新しいパソコンのセットアップも終わり、データもバックアップから戻し、Hyper-V上の仮想マシンの構成ファイルも戻しました。
証明書をインポートしたのですが「シールドVMのローカル証明書」ストアに入らず「個人」ストアに入ってしまいました。TPMの証明書は証明書ストアのパスが記録されていないようで自分でインポートする証明書ストアを指定しなければなりません。
ところが「シールドVMのローカル証明書」ストアはWindowsのインストール直後には存在せず、証明書の管理ツールからも作成できません。調べると仮の仮想マシンを作ってTPMを有効にすれば「シールドVMのローカル証明書」ストアが作成されるとのことでした。
仮の仮想マシンを作りTPMを有効にしたところ「シールドVMのローカル証明書」ストアができたので、そこを指定してエクスポートした証明書をインポートしました。
仮想マシンを起動してみると問題なく起動できました。
仮の仮想マシンは不要なので削除して、ついでに新規で作成された証明書も不要だと考え削除しました。証明書にはコンピューター名が付いていますので、どのパソコンで作成された証明書かは判別できます。
仮想マシンも起動できたので、毎回証明書の扱いに注意しないといけないのも面倒だし、Windows 11はインストールしてしまえばTPMの有無は判定しないので、今後はTPMを無効化して使おうと考えました。
ところが、仮想マシンの設定でTPMのチェックを外して「適用」をクリックしても、「セキュリティの変更を適用中にエラーが発生しました」と表示されてTPMを無効化できません。
このエラーは厄介で、仮の仮想マシンを作った時にできた証明書を削除したのが原因だとは分かるのですが、証明書は既に無く、「シールドVMのローカル証明書」ストアを削除して最初からやり直そうにも、証明書の管理ツールやHyper-Vマネージャーからは操作ができません。
HGSとは
ヒントとなるのは「UntrustedGuardian」です。検索してみるといろいろ分かってきました。
まず、何も考えずに使っていたHyper-VのTPMですが、これはWindows 11に対応するためにあるのではなくHGSの一部として以前から提供されているものです。
では、HGSとは何なのか、HGSとはHost Guardian Serviceの略でこちらで説明されています。
仮想マシンは単なるファイルですからコピーして盗み出し、自分の環境でじっくり時間をかけて解析して情報を引き出すことも可能なわけです。
HGSとはそれを防ぐために仮想マシンに鍵をかけて、正規の鍵で解錠できる環境以外での仮想マシンの実行を阻止する仕組みです。
本来はAD上でクラスターを組んで管理するものですが、単体のパソコンでも利用することはできます。Hyper-Vマネージャーでそのパソコンで初めて仮想マシンのTPMを有効にした場合にHGSは構成されます。仮想マシンのTPMの説明にこうあります。
暗号化サポートでは、仮想マシン向けにキーの保護機能(KP)の構成が必要です。キーの保護機能がまだない場合は、これらのオプションのいずれかを選ぶと、このホストでの仮想マシンの実行を許可するKPが生成されます。
単体のHyper-Vでのガーディアンの名前は「UntrustedGuardian」で、その状態はGet-HgsGuardianコマンドレットで確認できます。
最初のコマンド実行時はTPMを有効化する前で、まだガーディアンが構成されていません。TPMを有効化した後に再度実行するとガーディアンが機能していることが確認できます。
ここで構成されたガーディアンで使われる証明書は、証明書の管理ツールで「シールドVMのローカル証明書」ストアに表示される2つの証明書です。
この証明書を削除すれば当然、HGSが機能しなくなりますのでTPMの変更などができなくなるわけです。ただし何度か試しましたが、すべての場合で操作できなくなるわけではなくHGSが機能していない状態でも問題なくTPMの変更ができる場合もあります。その違いの条件は分かりませんでした。
HGSを構成し直すには
HGSの構成はHyper-Vマネージャーの裏でHgsClientコマンドレットを使って行われています。
新しいガーディアンの生成はNew-HgsGuardianコマンドレットで行います。生成コマンドがあるのなら削除するコマンドもあるはずです。
「セキュリティの変更を適用中にエラーが発生しました」と表示された場合に、ガーディアンを削除してやりなおすには下記のコマンドレットを実行して既存のガーディアンを削除します。
その他のコマンドレットについてはこちらに詳しく説明されています。
このコマンドレットを実行するとHGSが未構成の状態になりますので、Hyper-Vマネージャーから仮想マシンのTPMを有効化すれば新しいHGSが構成され、「シールドVMのローカル証明書」ストアに新しい証明書が作成されます。
簡単な仮想マシン証明書の管理方法
仮想マシンの移転に関する証明書の問題をHGSも絡めて調べると、エクスポート/インポートを行うPowerShellスクリプトが見つかります。
元は下記のMicrosoft Communityの投稿です。
ここで説明されているスクリプトが不完全なため、下記の記事に修正版が掲載されていますが、ガーディアン名を指定する変数が間違っています。
それを修正してGitHubに登録したものが下記ですが、ガーディアン名をUntrustedGuardianから変更しているのでエクスポートスクリプトで保存した証明書を読み込めません。
修正したものをダウンロードできるようにしました。これは実際にテストして動作を確認しています。
これらのスクリプトを使うといろいろな応用が考えられます。
Export-UntrustedGuardian.ps1
$GuardianName = 'UntrustedGuardian' $CertificatePassword = Read-Host -Prompt 'Please enter a password to secure the certificate files' -AsSecureString $guardian = Get-HgsGuardian -Name $GuardianName if (-not $guardian) { throw "Guardian '$GuardianName' could not be found on the local system." } $encryptionCertificate = Get-Item -Path "Cert:\LocalMachine\Shielded VM Local Certificates\$($guardian.EncryptionCertificate.Thumbprint)" $signingCertificate = Get-Item -Path "Cert:\LocalMachine\Shielded VM Local Certificates\$($guardian.SigningCertificate.Thumbprint)" if (-not ($encryptionCertificate.HasPrivateKey -and $signingCertificate.HasPrivateKey)) { throw 'One or both of the certificates in the guardian do not have private keys. ' + ` 'Please ensure the private keys are available on the local system for this guardian.' } Export-PfxCertificate -Cert $encryptionCertificate -FilePath ".\$GuardianName-encryption.pfx" -Password $CertificatePassword Export-PfxCertificate -Cert $signingCertificate -FilePath ".\$GuardianName-signing.pfx" -Password $CertificatePassword
Import-UntrustedGuardian.ps1
$NameOfGuardian = 'UntrustedGuardian' $CertificatePassword = Read-Host -Prompt 'Please enter the password that was used to secure the certificate files' -AsSecureString New-HgsGuardian -Name $NameOfGuardian -SigningCertificate ".\$NameOfGuardian-signing.pfx" -SigningCertificatePassword $CertificatePassword -EncryptionCertificate ".\$NameOfGuardian-encryption.pfx" -EncryptionCertificatePassword $CertificatePassword -AllowExpired -AllowUntrustedRoot
Windows 11/10、Hyper-V Serverからの証明書のエクスポート
PowerShellスクリプトを実行するには設定変更が必要です。
Windows 11では「設定」アプリの「システム」「開発者向け」「PowerShell」の設定を「オン」にします。そして管理者権限のPowerShellを開きます。
Windows 10では「設定」アプリの「更新とセキュリティ」「開発者向け」「PowerShell」の項目にチェックを入れ「適用」をクリックします。そして管理者権限のPowerShellを開きます。
Hyper-V Serverでは設定変更は不要です。コンソールからPowerShellコマンドを実行して、PowerShellに切り替えます。
「Export-UntrustedGuardian.ps1」を実行します。
移転先で証明書をインポートするためのパスワードを聞かれるので入力します。
「UntrustedGuardian-encryption.pfx」と「UntrustedGuardian-signing.pfx」が生成されるので、これらを移転先のパソコンにコピーします。
Windows 11/10、Hyper-V Serverへの証明書のインポート
移転先のパソコンで既にHGSが構成されていても問題ありません。
証明書にはパソコンのコンピューター名が入りますので、まだHGSが構成されていない場合はコンピューター名を移転元と同じコンピューター名としてインポートして、インポート後に新しいコンピューター名に変更することで、移転した仮想マシンと新規に作成する仮想マシンの証明書をまとめることができます。
移転先のパソコンでもエクスポート時と同じ手順でPowerShellスクリプトを実行できるように設定します。移転先のパソコンで管理者権限のPowerShellを開きます。
カレントフォルダーに「UntrustedGuardian-encryption.pfx」と「UntrustedGuardian-signing.pfx」を置いて「Import-UntrustedGuardian.ps1」を実行します。
パスワードを聞いてくるので、エクスポート時に指定したパスワードを入力してインポートを完了させます。
既にHGSが構成されている場合は、既にUntrustedGuardianが存在するとエラーが発生しますが証明書のインポートは正しく行われます。
HGSが構成されていない場合は、Hyper-VマネージャーでTPMを有効化した場合と同様に新規でガーディアン名「UntrustedGuardian」のHGSが構成されます。
Hyper-VマネージャーでTPMを有効化した場合と違うのは、HGSの管理に使われる証明書は新規に作成されず「UntrustedGuardian-encryption.pfx」と「UntrustedGuardian-signing.pfx」が使用されるということです。
Windows 11仮想マシン管理の最善策
長々書いてきましたが、Windows 11仮想マシンを運用する上での最善策は「TPMをオフにする」ことです。
既にTPMをオンで運用している仮想マシンでもTPMをオフにすれば証明書無しで移転先のパソコンで実行できます。セキュアブートの状態はどちらでも構いません。これらは実験で確認しています。
Windows 11はインストール時とメディアでのアップデート時しかTPMの確認を行っていないので、通常の運用ではTPMをオフにしていても問題ありません。
年に1度の大型アップデートでもWindows Updateから降ってくるアップデートなら大丈夫です。
まとめ
Windows 11/10ではWindows 8.1/8/7のライセンスが使えなくなりましたので、仮想マシンの作り直しはできるだけ避けたいことです。
今は調べれば大概の問題は解決しますが、あまり起きないマイナーな問題だと間違った情報も修正されず検索上位に残ってしまいます。それを間違いだと見抜き修正するには勉強が必要ですので、わけのわからないTPMなどというものは仮想マシンでも使わないことが最善です。
コメント