在PowerShell中使用System.Net.WebClient访问具有SAN证书的HTTPS URL

6

这里有一个有点奇怪的问题。我们正在使用的脚本是:

$username = "itrpo"
$url = "https://homepages.domain.com/cgi-bin/checkperms.cgi?user=$username"
$homepagesUser = "REMOVED"
$homepagesPass = "REMOVED"
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = new-object System.Net.NetworkCredential($homepagesUser, $homepagesPass)
$result = $webclient.DownloadString($url)

当我在桌面上运行时(Windows 8,PowerShell v3使用.NET v4.0.30319),它可以正常工作。但是,在服务器上运行时(Windows Server 2008 R2,PowerShell v2使用.NET v2.0.50727),它无法正常工作。最终,它会挂起并返回错误:“Exception calling "DownloadString" with "1" argument(s): "The operation has timed out"”。
使用NetMon,我确定服务器未执行任何TLS客户端密钥交换。
homepages.domain.com的SSL证书实际上是一个SAN证书,其中homepages是实际服务器名称的别名(我们称其为servera.domain.com)。当我在脚本中将$url更改为实际服务器名称时:
$url = "https://servera.domain.com/cgi-bin/checkperms.cgi?user=$username"

它可以工作,但这并不理想(如果服务移动到另一台机器上,脚本将会崩溃)。

似乎 PowerShell v2(.NET v2)在使用 SAN 证书时存在问题?进一步支持此观点的证据是,我们使用以上样式的脚本针对具有标准 SSL 证书的另一台服务器进行通信时,它能够正常工作。

这可能是由于使用的 WebClient 类有所不同导致的吗?这是 .NET v2 下它的文档: http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.80%29.aspx 以及 .NET v4 下的文档: http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.100%29.aspx

我对编程知之甚少,无法正确解释上述文档(也不知道自己是否正确),

理想情况下,我们希望该脚本在 PowerShell v2 和 .NET v2 下运行而无需升级或强制 PowerShell 使用 .NET v4。如果我的猜测是正确的,那么我们可以指定一个参数或修改脚本的方式来“修复”此问题吗?

非常感谢任何建议。


有没有完整的源代码示例,可以作为最终解决方案? - Kiquenet
很遗憾,我无法让以下建议起作用。我们正在将脚本迁移到Server 2012和PowerShell v3。 - Robin
有没有使用PS v3的示例? - Kiquenet
1个回答

5
我的直觉是,这与PowerShell版本(或一般的底层平台细节)关系不大,而与证书和HTTPS握手更相关。可能已经有了识别嵌入在证书中的替代主题名称的改进,但测试它的简单方法是将此行PowerShell添加到您的脚本中:
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

这将导致所有证书都被接受 - 无论它们是否被信任、过期等。这是一个很大的锤子,在生产环境中使用它是不明智的,但在帮助诊断设置时可能会有用。
您可以在MSDN页面上查看ServerCertificateValidationCallback的更多信息,包括它传递给委托的参数。理论上,您只需将您正在使用的证书列入白名单,并为该服务器返回true即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接