如何通过互联网安全地使用PowerShell远程访问机器?
我之前也碰到过一模一样的场景——用开了PowerShell远程的Azure虚拟机,WinRM配置了自签名证书的HTTPS监听器,虽然能正常跑远程命令,但总担心安全问题。下面给你捋清楚问题根源和靠谱的解决办法:
首先先还原下我当时用的基础命令(和你说的几乎一样):
$cred = Get-Credential $option = New-PSSessionOption -SkipCACheck $psSession = New-PSSession -UseSSL -ComputerName $vmHostName -SessionOption $option -Credential $cred Invoke-Command -Session $psSession -ScriptBlock { Write-Host $env:COMPUTERNAME }
这段代码确实能成功建立远程连接,也能保证传输内容的保密性和完整性,但最大的隐患就是-SkipCACheck参数:因为自签名证书没有受信任的CA签发,我们不得不跳过CA校验,这就等于放弃了对服务器证书真实性的验证——换句话说,中间人可以伪造一个自签名证书劫持你的连接,你根本没法察觉,这就是典型的MITM(中间人攻击)风险。
那怎么解决这个问题呢?其实PowerShell远程本身就支持绑定证书指纹来验证服务器身份,这样就算跳过CA校验,也能确保你连接的是目标机器,而不是伪造的节点。具体步骤如下:
获取目标VM的WinRM证书指纹
先在目标Azure VM上运行这条命令,找到用于WinRM的自签名证书:Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.EnhancedKeyUsageList -match "Server Authentication" } | Select-Object Thumbprint, Subject把输出里的
Thumbprint字符串复制出来,注意要去掉所有空格。修改客户端的远程命令
在客户端的PowerShell里,用拿到的指纹来创建会话:$cred = Get-Credential # 如果你的证书主题(Subject)里的CN和你用的$vmHostName完全一致,可以不用加-SkipCNCheck $sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck # 把下面的YOUR_VM_CERT_THUMBPRINT替换成你拿到的指纹字符串 $psSession = New-PSSession -UseSSL ` -ComputerName $vmHostName ` -SessionOption $sessionOption ` -Credential $cred ` -CertificateThumbprint "YOUR_VM_CERT_THUMBPRINT" Invoke-Command -Session $psSession -ScriptBlock { Write-Host $env:COMPUTERNAME }这样一来,客户端会严格验证服务器返回的证书指纹是否和你指定的完全匹配,只要中间人伪造的证书指纹不对,连接就会直接失败,彻底杜绝MITM风险。
额外提一句:如果场景允许,你也可以把目标VM的自签名证书导入到客户端的「受信任根证书颁发机构」存储里,这样就不用加-SkipCACheck参数了,安全性会更高——不过跨互联网场景下,证书导入操作可能有点繁琐,用指纹绑定的方式反而更灵活高效。
备注:内容来源于stack exchange,提问作者Palec

