gMSA(グループ管理サービス アカウント)の定期的なパスワードローテーションは安全性を高める一方、更新直後に一時的な認証失敗が発生して可用性に影響することがあります。この記事では「ローテーションの時刻は変えられるのか?」という実務上の疑問に端的に答えつつ、設計・運用で取り得る具体的な回避策、移行手順、監視・自動復旧の実装例までを詳しくまとめます。
結論:gMSAのローテーション“時刻”は変更不可。間隔(日数)は作成時のみ設定可能
Active Directory は gMSA のパスワードを既定で 30 日ごとに自動更新します。
制御できるのはローテーションの間隔(日数)のみで、具体的な時刻や時間帯を指定する機能はありません。また既存 gMSA の間隔を後から変更することはできない前提で設計・運用するのが安全です(必要なら新規 gMSA を作成して段階移行)。
| 項目 | 可否 | 備考 |
|---|---|---|
| ローテーションの間隔(何日ごと) | 可(作成時) | New-ADServiceAccount -ManagedPasswordIntervalInDays <日数> で指定 |
| ローテーションの時刻(何時に回すか) | 不可 | AD 内部の決定論的ロジックで決定。ユーザー制御の仕組みなし |
| 既存 gMSA の間隔を後から変更 | 不可(実運用非推奨) | 新規作成 → サービス移行 → 旧 gMSA 廃止が安全 |
なぜ時刻は変えられないのか(内部動作の概要)
gMSA のシークレットはドメイン コントローラ(DC)側で生成・管理され、msDS-ManagedPasswordInterval と msDS‑ManagedPasswordID を基に自動・決定論的に次回更新時刻が計算されます。大量のアカウントが同じ時間に更新され「スパイク」や「スロットリング」を引き起こさないようにする設計です。したがって、任意の“時間帯にずらす”操作は仕様上できません。サーバー側の時計を進める/戻すといった小手先の対策も無意味で、Kerberos の時刻整合性や監査の観点でむしろリスクになります。
ローテーション直後に起こり得る事象と見分け方
- 認証の瞬断(1〜10 分程度):サービスが保持している古いチケット(TGT/TGS)と、KDC 側の新しい鍵バージョン(kvno)が齟齬を起こすと、一時的に Kerberos が失敗します。
- 典型的なログ:System ログ(ソース:Security-Kerberos)で
KRB_AP_ERR_MODIFIEDなど。アプリケーション側には「ログオン失敗」「無効な資格情報」等のメッセージが残ることがあります。 - 複数ノード構成での偏り:一部ノードだけ旧チケットを保持していると負荷分散配下で断続的に 401/403 や 5xx が発生。
発生自体は仕様上の挙動に近いため、短時間で自動回復させる設計が現実解です。
実務で取るべき回避策(一覧)
| 方策 | 概要 | メリット | 注意点 | 適用シーン |
|---|---|---|---|---|
| サービスの自動再起動 | ローテーション直後に対象サービスを自動再起動(タスクスケジューラ等) | 復旧を数十秒に短縮 | 短時間停止が生じる。順序制御が必要 | Web/API、Windows サービス |
| チケットの強制更新 | klist purge 等で古いチケットを破棄 | ログオン状態を保持しつつ再認証 | スクリプト化・権限設定が必要 | 無停止を優先する場面 |
| 間隔の見直し(60/90 日) | 繁忙期を避けるためローテーション頻度を下げて新規 gMSA を導入 | 業務影響の回数を減らす | 変更は新規作成+移行が前提 | ピーク時間が明確な業務 |
| ブルー/グリーン(複数 gMSA) | 2 つの gMSA を用意して段階的に切り替え | ほぼ無停止で更新 | 運用・権限設計が複雑 | 高可用性が最優先の基盤 |
| 冗長化(N+1) | 一部ノードの瞬断をロードバランサで吸収 | ユーザー影響を外部化 | コスト増。ヘルスチェック設計が鍵 | 大規模サービス |
| 従来アカウント+手動更新 | 時刻を完全制御したい場合の最終手段 | 時間帯を自由に指定可 | 運用負荷・秘匿管理のリスク増 | 停止許容・厳密運用が可能な系 |
作成時に間隔を指定する PowerShell 例
新規 gMSA の作成時にだけ、ローテーション間隔(日数)を指定できます。以下は 60 日間隔で作成する例です。
New-ADServiceAccount -Name "MyGMSA" `
-DNSHostName "MyGMSA.example.local" `
-PrincipalsAllowedToRetrieveManagedPassword "MyServer$" `
-ManagedPasswordIntervalInDays 60
-PrincipalsAllowedToRetrieveManagedPassword には gMSA のパスワードを取得できるコンピューター アカウント(MyServer$ のように $ を含む)を指定します。複数ノードのときは複数指定してください。
既存 gMSA の間隔を変えたいときの正攻法:新規作成 → 段階移行
- 新しい gMSA を作成(例:
MyGMSA2)。希望の間隔を指定。 - 各ノードにインストール:
Install-ADServiceAccount -Identity MyGMSA2→Test-ADServiceAccountで疎通確認。 - サービス実行アカウントを切替:順次ノード単位で
sc.exe configもしくはサービス管理ツールで変更し、再起動。 - 監視でエラーがないことを確認:1〜2 サイクル監視後に旧 gMSA を廃止。
切替の具体例(Windows サービス)
# 新 gMSA をノードに導入
Install-ADServiceAccount -Identity "MyGMSA2"
Test-ADServiceAccount -Identity "MyGMSA2"
# サービスの実行アカウントを gMSA に切り替え(パスワードは空文字)
sc.exe config "MyService" obj= "EXAMPLE\MyGMSA2$" password= ""
Restart-Service -Name "MyService" -Force </code></pre>
<p>gMSA を使う場合、<code>password= ""</code>(空文字)にする点に注意してください。</p>
</div>
<div>
<h2>ローテーション直後の失敗を最小化する実装パターン</h2>
<h3>1) 自動再起動+チケット破棄(シンプルで効果的)</h3>
<p>ローテーション直後(=実際には不明なタイミング)に短時間のエラーが出たら、即座にチケットを捨ててサービスを再起動します。イベント トリガー(Kerberos エラー)とスクリプトの組合せが現実的です。</p>
<details>
<summary>例:Kerberos エラーをトリガーに自動復旧させる</summary>
<p><strong>タスクスケジューラ(イベント トリガー)</strong>で、System ログの Security-Kerberos ソースを監視し、エラー発生時に PowerShell を実行します。</p>
<pre><code class="language-powershell"># 例: schtasks(XML フィルターは環境に合わせて調整)
schtasks /Create /TN "Recover-MyService-OnKerberos" ^
/SC ONEVENT /EC System ^
/MO "*[System[Provider[@Name='Microsoft-Windows-Security-Kerberos'] and (EventID=4)]]" ^
/TR "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\Recover-MyService.ps1" ^
/RU "SYSTEM"
復旧スクリプト(例)
# C:\Scripts\Recover-MyService.ps1
try {
# 古いチケットを破棄
klist purge
# サービスを即時再起動
Restart-Service -Name "MyService" -Force -ErrorAction Stop
# 監査ログ
Write-EventLog -LogName Application -Source "Application" ` -EventId 1000 -EntryType Information`
-Message "Kerberos error detected; service restarted successfully."
}
catch {
Write-EventLog -LogName Application -Source "Application" ` -EventId 1001 -EntryType Error`
-Message ("Recovery script failed: " + $_.Exception.Message)
exit 1
}
イベント ID やクエリは環境で発生する実イベントに合わせて調整してください(KRB_AP_ERR_MODIFIED に限らず、アプリ側ログをトリガーにする選択肢も有効です)。
2) ローリング再起動(冗長化前提)
ロードバランサ/クラスタ配下でノードを 1 台ずつ切り離し、チケット破棄&再起動を実施して戻す手順を定期ジョブ化します。ローテーション時刻そのものは読めなくても、短時間で全ノードを最新状態に揃えることで影響時間を最小化できます。
3) 監視強化で早期検知・自動収束
- System ログ(Security-Kerberos)とアプリケーション ログの相関をダッシュボード化
- HTTP 401/403、5xx(割合・継続時間)にしきい値を設定し自動フェイルアウト
- チケット残存率(
klistでの残チケット数)をメトリクス化
ブルー/グリーン(複数 gMSA)で“ほぼ無停止”を実現する
gMSA を 2 つ(例:GMSA-App-A と GMSA-App-B)用意し、常時片系を「待機」にしておきます。更新サイクルの前後で順次ノードの実行アカウントを切り替え、全台が新系に移ったら旧系を待機に戻します。SPN をサービス側で明示設定している場合は整合性に注意してください(重複 SPN は KRB_AP_ERR_MODIFIED の温床)。
ポイントは以下の通りです。
- 両 gMSA を
-PrincipalsAllowedToRetrieveManagedPasswordに同じノード群で許可 - 切替時は LB でトラフィックを外し、
klist purge→ サービス再起動の順に実行 - 切替完了後に旧 gMSA 側の権限をクリーンアップ(最小権限の維持)
注意:サーバーのシステム日時をいじっても無意味
「更新時刻をずらしたいからサーバー時計を操作する」という発想は逆効果です。gMSA のパスワードは DC 側で生成・管理され、更新タイミングは DC 内部のロジックとレプリケーションで決まります。時計操作は Kerberos の許容時刻ずれ(スキュー)や監査の整合性を壊し、原因不明の認証失敗を増やすだけです。
Kerberos とチケットの基本(運用上の勘所)
- TGT(ユーザー/サービス対 KDC)とサービス チケット(対サーバー)は別物です。
いずれかが古いキーを前提に発行されていると、鍵バージョン(kvno)不一致で失敗します。 - KDC は一定期間、旧キーも受理する重複期間を持ちますが、クライアント側が古いチケットを握り続ける限り失敗が続く可能性があります。
klist purgeは簡易かつ強力な解決策です。
ただしサービス停止を伴わないケースでも、セッション切断や再確立が必要な場合があります。
設計方針のヒント(意思決定の軸)
- 可用性重視:N+1 冗長化+ローリング再起動+即時復旧スクリプト。
- 運用容易性重視:既定 30 日のまま、検知・自動復旧だけ整える。
- 業務ピーク回避:60/90 日間隔で新規 gMSA を導入し、発生回数を減らす。
- 完全時刻制御が必要:従来アカウント+手動更新(ただし秘匿・棚卸の仕組み必須)。
環境別の実装テンプレート
| 環境 | 推奨構成 | ポイント |
|---|---|---|
| 小規模(単一ノード) | タスクスケジューラで 1 時間ごとに klist purge → アプリ健全性チェック → 必要時のみ再起動 | ダウンタイム短縮にフォーカス。再起動後のウォームアップ考慮 |
| 中規模(2〜4 ノード) | LB でローリング再起動+エラー イベント トリガー復旧 | 切替順序とヘルスチェックの“戻し判定”を厳密に |
| 大規模(5 ノード以上) | ブルー/グリーンの 2 gMSA 方式+自動切替パイプライン | 権限・SPN の整合性監査を定期実行 |
新規 gMSA の導入からサービス切替まで(手順書)
- gMSA の作成
New-ADServiceAccount -Name "GMSA-App-Prod" ` -DNSHostName "GMSA-App-Prod.example.local" ` -PrincipalsAllowedToRetrieveManagedPassword "APP01$","APP02$","APP03$" ` -ManagedPasswordIntervalInDays 60 - 各ノードに導入
Install-ADServiceAccount -Identity "GMSA-App-Prod" Test-ADServiceAccount -Identity "GMSA-App-Prod" - サービス実行アカウント切替
sc.exe config "AppService" obj= "EXAMPLE\GMSA-App-Prod$" password= "" Restart-Service -Name "AppService" -Force - 健全性確認:エラー率・レイテンシ・ログを確認。必要に応じて
klist purgeを追加実施。
運用に効く監視・可観測性の作り方
- イベント ログ:System(Security-Kerberos)、アプリ ログ、IIS/HTTP ログの相関。
- メトリクス:401/403/5xx の割合、再起動回数、
klist実行結果。 - 分布で見る:短時間のスパイクは 5 分平均だと隠れやすいので 1 分粒度も併用。
- アラート:5 分以上の継続で通知、同時に復旧スクリプトをキックして自己回復。
FAQ(よくある質問)
Q. “今の 8 時間前後”など、任意の時間帯にローテーションを移せますか?
できません。gMSA の更新は DC の内部ロジックにより決定されるため、時間指定やオフセット変更の手段はありません。可用性要件に応じて、本記事の回避策(自動再起動、チケット破棄、冗長化、複数 gMSA)を組み合わせてください。
Q. 30 日より短く(例:7 日)するのはどうですか?
技術的には可能ですが、更新回数が増えるほど影響の機会が増えます。セキュリティ要件と可用性要件のバランスを検討し、十分な冗長化・自動復旧が整ってから短縮してください。
Q. 既存 gMSA の“間隔だけ”を後から変えられませんか?
後からの変更は前提に置かず、新規 gMSA を作って計画的に移行するのが確実です。この手順ならロールバックも容易です。
Q. SPN の設定は?
アプリやプロトコルにより異なります。SPN を登録する場合は重複・誤紐付けがないか必ず確認してください。重複 SPN は KRB_AP_ERR_MODIFIED の主要因です。
まとめ
- gMSA のローテーション“時刻”は変更不可。間隔(日数)は作成時のみ指定。
- 更新直後の一時的な認証失敗は起こり得るため、検知・自動復旧・冗長化でカバーする。
- 時刻制御が必須なら、複数 gMSA 方式または従来アカウント+手動更新を検討。
- 運用は「影響の回数を減らす(間隔延長)」か「影響の時間を減らす(自動復旧)」かのトレードオフ。要件に最適化しよう。
付録:トラブルシュートのチェックリスト
- ドメイン参加/時刻同期(NTP)が健全か
PrincipalsAllowedToRetrieveManagedPasswordに対象ノードが含まれているか- SPN の重複・誤登録がないか(
setspn -Xなどで棚卸) - LB のヘルスチェックが再起動直後のウォームアップを考慮しているか
- イベント トリガー復旧が確実に動作するか(テストで証明)
- ブルー/グリーン方式の権限・棚卸・ロールバック手順が文書化されているか
参考コマンド(抜粋)
# gMSA のプロパティ確認(AD モジュール)
Get-ADServiceAccount -Identity "MyGMSA" -Properties *
# ローカル ノードに gMSA を導入・確認
Install-ADServiceAccount -Identity "MyGMSA"
Test-ADServiceAccount -Identity "MyGMSA"
# サービス実行アカウントを gMSA に(パスワードは空)
sc.exe config "MyService" obj= "EXAMPLE\MyGMSA$" password= ""
# Kerberos チケットの破棄
klist purge
# Kerberos 関連イベントの確認(例)
Get-WinEvent -LogName System |
Where-Object {$_.ProviderName -eq "Microsoft-Windows-Security-Kerberos"} |
Select-Object TimeCreated, Id, LevelDisplayName, Message -First 20
ポイントのおさらい(1 分で読める縮約版)
- gMSA の時刻指定はできない(間隔は作成時のみ指定可)。
- 更新直後の短時間エラーは仕組みによるもの。自動復旧と冗長化で無害化。
- どうしても日付を動かしたいなら、60/90 日間隔の新規 gMSA を導入し繁忙期を避ける。
- 高可用性が最優先なら、複数 gMSA(ブルー/グリーン)+ローリングでゼロダウンに近づける。

コメント