WinRM HTTPS クライアント証明書認証で Access is denied になる原因と対策(Windows Server 2012/2016・ClientAuthTrustMode)

Linux から WinRM(HTTPS/5986)で Windows Server を管理する際、Basic 認証は通るのにクライアント証明書認証(証明書マッピング)だけが Windows Server 2012/2016 で「Access is denied/InvalidCredentials」になることがあります。本記事では原因のポイントと、レジストリ 1 つで解消できる代表的な対処を具体手順つきでまとめます。

目次

症状:WinRM(HTTPS/5986)の証明書認証だけが 2012/2016 で拒否される

今回の現象を、よくある実務パターンに落とすと次のようになります。

  • Linux から WinRM(5986/HTTPS)で Windows Server を操作したい
  • Basic 認証なら接続できる(疎通は取れている)
  • 要件により クライアント証明書認証(証明書マッピング)へ切り替えたい
  • 自己署名のクライアント証明書(EKU: clientAuth)を用意し、サーバー側の証明書ストアへ投入、ローカル管理者へマッピング済み
  • 開発環境では成功するのに、テスト環境だと Windows Server 2008 は成功、2012/2016 が一部だけ失敗

エラーの見え方は環境により多少異なりますが、代表例は以下です。

クライアント操作代表的なエラー示唆
WindowsEnter-PSSession / New-PSSession(-UseSSL -CertificateThumbprint)Access is denied / The WinRM client cannot process the requestWinRM 以前(TLS)か、WinRM の証明書認証・マッピングのどこかで拒否
Linuxpywinrm / Ansible(WinRM over HTTPS)InvalidCredentials / 401 / 403 相当の拒否同じく TLS〜WinRM 認証層の問題。Basic が通るなら通信や WinRM 自体は概ね OK

ポイント:証明書マッピングは「最後の一手前」まで通って初めて効く

WinRM のクライアント証明書認証は、ざっくり言うと次の二段階で成立します。

  1. TLS ハンドシェイクでクライアント証明書が提示され、サーバー側(SCHANNEL)が「信頼できる証明書チェーン」として受理する
  2. WinRM(WSMan)が certmapping(証明書マッピング)に基づいて証明書→ユーザーを紐付け、権限チェックを行う

重要なのは、certmapping が正しく入っていても、1 の時点で“信頼できない”判定になると 2 に進まないことです。現象としては「証明書は入っている」「マッピングも入っている」のに Access is denied/InvalidCredentials になり、切り分けが難しく感じます。

観点Basic 認証クライアント証明書認証(証明書マッピング)今回の肝
失敗しやすい層ユーザー権限やポリシーTLS(SCHANNEL のチェーン判定)+マッピング2012/2016 の一部だけ失敗する“環境差”は TLS 側が原因になりやすい
ありがちな誤解—「Trusted People に入れたから信頼されるはず」ストアに“存在する”ことと、SCHANNEL が“信頼チェーンとして受理する”ことは別

原因:SCHANNEL のクライアント証明書 Trust Mode が“信頼の判定”を変える

結論として、Windows の TLS(SCHANNEL)には「クライアント証明書をどういうモードで信頼判定するか」を切り替える要素があり、その挙動差で 同じ証明書でも環境によって“信頼できない”扱いになることがあります。

ここで効いてくるのが、SCHANNEL のレジストリ値 ClientAuthTrustMode です。Microsoft Learn の Q&A でも、WinRM の証明書認証が一部の Windows Server 2012 系で失敗するケースの対処として、この値の設定が紹介されています。

解決策:ClientAuthTrustMode を 2(Exclusive CA Trust)に設定する

問題が出ている Windows Server 2012/2016 側で、次のレジストリ値を追加します。

項目設定
パスHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL
値名ClientAuthTrustMode(REG_DWORD)
値2
補足Stack Overflow では 2 が SCHANNEL の Trust Mode を Exclusive CA Trust にする設定として説明されています

PowerShell(管理者)での設定例

New-ItemProperty `
  -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL' `
  -Name 'ClientAuthTrustMode' -PropertyType DWord -Value 2 -Force

反映と再テストのコツ

この値は SCHANNEL に関わるため、反映に再起動が必要になる場合があります。切り分けとしては次の順が安全です。

  • 設定後、まず WinRM サービスを再起動して再テスト(環境によってはこれで反映する)
  • 変化がなければ、計画停止のうえでサーバー再起動して再テスト(確実)

設定確認(現在値の確認)

Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL' `
  -Name 'ClientAuthTrustMode' -ErrorAction SilentlyContinue

WinRM 側の確認:certmapping と認証設定を「目で見て」揃える

ClientAuthTrustMode で改善するケースでも、WinRM 側の設定に不足があると当然失敗します。次の 3 点は、まずコマンドで確認しておくと迷いません。

証明書マッピングが正しく入っているか

winrm enum winrm/config/service/certmapping

Enabled=true、そして Issuer/Subject(または URI/Thumbprint)条件が意図どおりであることを確認します。自己署名証明書は Issuer と Subject が同じに見えるため、複数枚運用している場合は条件が衝突しやすい点に注意してください。

WinRM で Certificate 認証が有効になっているか

winrm get winrm/config/service/auth

出力の中で Certificate = true になっているかを確認します。Basic を無効化する前に、証明書認証が有効化できているか(GPO で上書きされていないか)も見ておきます。

HTTPS リスナーが存在し、意図したサーバー証明書を使っているか

winrm enumerate winrm/config/listener

Transport=HTTPS のリスナーが存在し、Thumbprint が意図したサーバー証明書のものかを確認します。

Windows クライアントからの簡易テスト:Enter-PSSession の -CertificateThumbprint

Linux 側のツール(pywinrm/Ansible)で切り分けが難しいときは、Windows から同じ WinRM に対して証明書認証を試すと、問題がサーバー側かクライアント側かを素早く切り分けできます。

# クライアント証明書(CurrentUser\My)から Thumbprint を指定して接続する例
Enter-PSSession -ComputerName 'server.example.local' -UseSSL -CertificateThumbprint 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

ここでも同様に Access is denied になるなら、Linux 側の実装差というより、サーバー側(SCHANNEL/WinRM 設定/マッピング)に原因が寄っている可能性が高くなります。

補足:同時に確認するとよい点(失敗原因の“取りこぼし”を防ぐ)

ClientAuthTrustMode が本命でも、周辺条件が揃っていないと別の理由で失敗し続けます。現場で効く順にまとめます。

確認項目なぜ重要か確認方法の例NG だと起きやすい症状
クライアント証明書の EKU(clientAuth)用途不一致だと TLS で受理されにくい証明書の詳細で EKU を確認証明書を提示しても認証として成立しない
秘密鍵の存在とアクセス権秘密鍵が読めないと署名できず失敗Linux のファイル権限、Windows の秘密鍵 ACLクライアント側で握手失敗/証明書未送信
証明書ストアの“場所”(LocalMachine / CurrentUser)WinRM サービスが参照できるストアが違うcertlm.msc / certmgr.msc で確認入れたつもりでもサーバー側で信頼されない
接続先名とサーバー証明書の CN/SAN不一致は別エラーになりやすいFQDN で接続、SAN を確認証明書認証以前に TLS で失敗
WinRM 実行権限(グループ/セッション構成)マッピング成功後の最終関門Remote Management Users、セッション構成 ACL常に Access is denied(OS 差は出にくい)

ログで裏取りする:WinRM と Schannel を見る

「証明書は入っているのに拒否される」状況では、ログが判断材料になります。

  • WinRM の Operational ログ:Applications and Services Logs > Microsoft > Windows > WinRM > Operational
  • Schannel:システム ログに TLS 関連の警告/エラーが出ることがある

WinRM 側に“証明書認証を試した”形跡が薄い場合は、TLS の段階で弾かれている可能性が高くなります。このときに ClientAuthTrustMode を変えて改善する、という流れが典型です。

影響範囲とロールバック:SCHANNEL なので段階適用が安全

ClientAuthTrustMode は OS 全体の TLS(SCHANNEL)に関わるため、WinRM 以外のサービスにも影響し得ます。同一サーバーで IIS のクライアント証明書認証などを使っている場合は、必ず影響評価を行い、まずは問題が出ている 1 台から段階的に適用してください。

ロールバック(元に戻す)

切り戻しが必要になった場合は、値を削除(または 0 に戻す)します。

Remove-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL' `
  -Name 'ClientAuthTrustMode' -ErrorAction SilentlyContinue

現場向け:最短で解決するためのチェック順

「WinRM HTTPS+クライアント証明書認証で 2012/2016 だけ Access is denied」という状況で、最短で片付けるための流れを 1 枚にまとめます。

ステップやること狙いコマンド例
AHTTPS リスナーと Certificate 認証の有効化を確認WinRM 設定不足を除外winrm enumerate winrm/config/listener
winrm get winrm/config/service/auth
Bcertmapping を確認マッピング条件の不一致を除外winrm enum winrm/config/service/certmapping
C証明書が LocalMachine の適切なストアにあるか確認“入れたつもり”事故を除外certlm.msc / certutil -store
DClientAuthTrustMode=2 を適用SCHANNEL の信頼判定の環境差を潰すNew-ItemProperty … ClientAuthTrustMode=2
E必要なら再起動して再テスト反映タイミングを確実にするRestart-Service WinRM(切り分け)
Restart-Computer(確実)

参考リンク

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次