🦘

PowerShellでダブルホップ問題の手軽な回避策

2025/01/14に公開

PowerShellのダブルホップ問題とは

セキュリティ上の理由から、リモート接続先からさらに別のPCへのリモートアクセスが制限される問題です

  1. ServerA にログインしています。
  2. ServerA からリモート PowerShell セッションを開始して ServerB に接続します。
  3. PowerShell リモート処理セッションを介して ServerB で実行するコマンドは、ServerC 上のリソースにアクセスを試みます。
  4. PowerShell リモート処理セッションの作成に使った資格情報は ServerB から ServerC に渡されないため、ServerC 上のリソースへのアクセスは拒否されます。

https://learn.microsoft.com/ja-jp/powershell/scripting/security/remoting/ps-remoting-second-hop?view=powershell-7.4

ダブルホップ、セカンドホップ、マルチホップなど呼称が統一されていなさそうでした
さすがに不便すぎるためかマイクロソフト公式にいくつか回避策が載っています

うまくいった手軽な方法

RunAs を使用する PSSessionConfigurationがうまく行きました
RunAs*を指定したConfigurationでPSSessionを作成するとダブルホップ問題が回避できるようです

このためのInvoke-PSSessionというモジュールがPowerShell Galleryにあるのでこれを利用すると簡単にできました

Install-Module Invoke-PSSession
$Session = Invoke-PSSession -ComputerName $ServerB -Credential Get-Credential
Invoke-Command -Session $Session -ScriptBlock {
    hostname
    Invoke-Command -ComputerName $ServerC -Credential Get-Credential -ScriptBlock {
        hostname
    }
}

ソースを見るとInvoke-PSSessionは、

  1. 一度Invoke-Commandでリモートに入り
  2. -RunAsCredential付きのPSSessionConfigurationを登録し
  3. 改めてそのPSSessionConfigurationを指定してセッションを作成して返す
    という挙動になっていました

弱点としてはユーザー名と同じ名前のPSSessionConfigurationがサーバーBに登録されたままになるので、セキュリティを気にするなら後で消しといたほうがよさそうです

ダメだったほかの方法

CredSSP

回避策として一番おすすめされているのがCredSSPを使う方法ですが、
事前に次の設定が必要そうで断念しました

  • サーバー、クライアント側両方でPowerShellのコマンドで許可が必要
  • グループポリシーの設定

こちらの記事がわかりやすかったです

Invoke-Command スクリプト ブロックの内部で資格情報を渡す

CredentialInvoke-Command内に渡してしまう方法です

# This works without delegation, passing fresh creds
# Note $Using:Cred in nested request
$cred = Get-Credential Contoso\Administrator
Invoke-Command -ComputerName ServerB -Credential $cred -ScriptBlock {
    hostname
    Invoke-Command -ComputerName ServerC -Credential $Using:cred -ScriptBlock {hostname}
}

https://learn.microsoft.com/ja-jp/powershell/scripting/security/remoting/ps-remoting-second-hop?view=powershell-7.4#example-1

これができれば一番よかったのですが手元の環境では動作しませんでした

Edit 12/5/16: After much research internally we have concluded that this technique does not support double-hop for WinRM-based commands (Invoke-Command, Enter-PSSession, Get-CimInstance, etc.). I plan to release more details on this later.

とあるので以前は動作したけど、今はダメになったとかなのかもしれません

参考

https://learn.microsoft.com/ja-jp/powershell/scripting/security/remoting/ps-remoting-second-hop?view=powershell-7.4
https://learn.microsoft.com/ja-jp/archive/blogs/ashleymcglone/powershell-remoting-kerberos-double-hop-solved-securely
https://note.shiftinc.jp/n/n5e8f78e054ed
https://www.reddit.com/r/PowerShell/comments/7pv9xh/comment/dslwpjf/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

Discussion