背景:
PoshSSH是一款在PowerShell下非常流行的SSH指令行用戶端,可以通過https://www.powershellgallery.com/packages/Posh-SSH 擷取。
近期筆者在使用這款用戶端完成批量任務下發的時候遇到了部分主機連結失效的問題,于此同時使用獨立用戶端工具putty嘗試連接配接卻是正常的,證明問題存在于用戶端自身。

圖 1連接配接意外的報錯資訊
PS C:\Users\zhouguanyu> New-SSHSession-ComputerName ??.??.??.??
位于指令管道位置 1 的 cmdlet New-SSHSession
請為以下參數提供值:
(請鍵入 !? 以檢視幫助。)
Credential
New-SSHSession : Key exchange negotiation failed.
所在位置行:1 字元: 1
+ New-SSHSession -ComputerName ??.??.??.??
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (Renci.SshNet.SshClient:SshClient) [New-SSHSession],SshConnectionException
+ FullyQualifiedErrorId : SSH.NewSshSession
處理:
首先使用“Key exchange negotiation failed.”作為關鍵字檢索發現有github上的一個issuse315[1] ,和我的症狀一緻,是以嘗試了更新PoshSSH的版本為2.3.0 後測試依舊存在問題,聯想到這些出現故障連結的主機曾經都有重裝過系統,莫非有些主機特征被記錄在SSH的用戶端裡,但是因為PoshSSH是PowerShell的一個子產品,本身也沒有配置項記錄的檔案。
PS C:\Program Files\WindowsPowerShell\Modules\Posh-SSH\2.3.0> tree /F
檔案夾 PATH 清單
C:.
│ Posh-SSH.psd1
│ Posh-SSH.psm1
│ PoshSSH.dll
│ PoshSSH.pdb
│
├─Assembly
│ Ionic.Zlib.dll
│ Newtonsoft.Json.dll
│ Renci.SshNetPS.dll
├─en-US
│ Posh-SSH-help.xml
│ Posh-SSH.psm1-Help.xml
│ PoshSSH.dll-help.xml
└─Format
Renci.SshNet.Sftp.SftpFile.Format.ps1xml
Renci.SshNet.SshCommand.Format.ps1xml
SFTPSession.Format.ps1xml
SSHSession.Format.ps1xml
請出 Mark Russinovich 大師的 Process Monitor 抓一下系統包,了解一下PoshSSH在運作的時候都去系統的那些竄過門。
圖 2使用主機IP作為關鍵字進行檢索
确實可以發現對“系統資料庫”和“TCP連結”的兩種操作,同時系統資料庫的詳細資訊内可以看到他查詢了主機,通過删除該主機在系統資料庫中的鍵值,再次連結問題得到解決。
圖 3證據支援PoshSSH會利用系統資料庫進行遠端主機指紋的記錄
存下曆史連結主機的指紋可以加速下次連結進入的速度,但是PoshSSH并沒有考慮到系統renew指紋後的再次連接配接的問題。
結論:
因為筆者還需要繼續操作腳本,并避免下次遇此問題被回退,可以在腳本裡面加一條清理“HKEY_CURRENT_USER\Software\PoshSSH”鍵值的語句。
reg delete HKEY_CURRENT_USER\Software\PoshSSH /f
更新:
新版PoshSSH新版已經有指令支援删除信任主機的指令(Remove-SSHTrustedHost),是以批量或單點操作的時候可以使用。
使用方式可以配合羅列信任主機的指令(Get-SSHTrustedHost)一同操作更加高效。
删除所有已經記錄的信任主機(等同于 reg delete HKEY_CURRENT_USER\Software\PoshSSH /f )
Get-SSHTrustedHost | Remove-SSHTrustedHost
-=EOB=-
[1] https://github.com/darkoperator/Posh-SSH/issues/315