在 Web 请求中信任 HTTPS 站点的证书
Trusting certificate of HTTPS site in web request
我想使用 PowerShell 2.0 测试我们的 Web 服务器(位于 Intranet 上)是在线 (1
) 还是离线 (0
)。为此,我有一个脚本可以导航到页面并检查页面上是否有 html 字符串。
function Get-HeartBeat {
$isAlive = $false
try {
$webclient = New-Object WebClient
$userName = "xxx"
$password = "xxx"
$domain = "xxx"
$url = "ourUrl.com"
$html = '<input type="submit">'
$webclient.Credentials = New-Object System.Net.NetworkCredential($userName, $password, $domain)
$webpage = $webclient.DownloadString($url)
$isAlive = $webpage.Contains($html)
} catch {
# A WebException is thrown if the status code is anything but 200 (OK)
Write-Host $_
$isAlive = $false
}
return "$([Int32]$isAlive)"
}
不幸的是,这 returns 一个错误:
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
一种信任我们证书的方法是创建一个具有如下证书策略的类型(this answer 的修改):
Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustOurCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint servicePoint, X509Certificate certificate,
WebRequest request, int certificateProblem)
{
return certificate.Issuer.Equals("OUR ISSUER")
&& certificate.Subject.Contains("our application");
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustOurCertsPolicy
这仍然感觉有点 "stringly typed" 而不是 100% 安全。
这里安全吗?有没有更好的方法来创建接受一个证书的 WebClient?我们应该信任的证书在 cert:LocalMachine\My
.
中可用
处理证书错误的正确方法是将网络服务器证书的证书链(根和中间 CA 证书)导入本地证书存储(分别作为受信任的根 CA 和中间 CA)。如果服务器证书是自签名的,您需要将服务器证书导入为受信任的根 CA。
根据您实际需要检查的内容,另一种选择可能是修改您的算法。例如,如果你真的只需要一个心跳(不验证实际请求 returns 一个特定的结果)你可以简单地尝试建立一个到端口的 TCP 连接:
function Get-HeartBeat {
$url = 'ourUrl.com'
$port = 443
$clnt = New-Object Net.Sockets.TcpClient
try {
$clnt.Connect($url, $port)
1
} catch {
0
} finally {
$clnt.Dispose()
}
}
在较新的 Windows 版本中,您可以使用 Test-NetConnection
cmdlet 达到相同目的:
function Get-HeartBeat {
$url = 'ourUrl.com'
$port = 443
[int](Test-Net-Connection -Computer $url -Port $port -InformationLevel Quiet)
}
我想使用 PowerShell 2.0 测试我们的 Web 服务器(位于 Intranet 上)是在线 (1
) 还是离线 (0
)。为此,我有一个脚本可以导航到页面并检查页面上是否有 html 字符串。
function Get-HeartBeat {
$isAlive = $false
try {
$webclient = New-Object WebClient
$userName = "xxx"
$password = "xxx"
$domain = "xxx"
$url = "ourUrl.com"
$html = '<input type="submit">'
$webclient.Credentials = New-Object System.Net.NetworkCredential($userName, $password, $domain)
$webpage = $webclient.DownloadString($url)
$isAlive = $webpage.Contains($html)
} catch {
# A WebException is thrown if the status code is anything but 200 (OK)
Write-Host $_
$isAlive = $false
}
return "$([Int32]$isAlive)"
}
不幸的是,这 returns 一个错误:
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
一种信任我们证书的方法是创建一个具有如下证书策略的类型(this answer 的修改):
Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustOurCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint servicePoint, X509Certificate certificate,
WebRequest request, int certificateProblem)
{
return certificate.Issuer.Equals("OUR ISSUER")
&& certificate.Subject.Contains("our application");
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustOurCertsPolicy
这仍然感觉有点 "stringly typed" 而不是 100% 安全。
这里安全吗?有没有更好的方法来创建接受一个证书的 WebClient?我们应该信任的证书在 cert:LocalMachine\My
.
处理证书错误的正确方法是将网络服务器证书的证书链(根和中间 CA 证书)导入本地证书存储(分别作为受信任的根 CA 和中间 CA)。如果服务器证书是自签名的,您需要将服务器证书导入为受信任的根 CA。
根据您实际需要检查的内容,另一种选择可能是修改您的算法。例如,如果你真的只需要一个心跳(不验证实际请求 returns 一个特定的结果)你可以简单地尝试建立一个到端口的 TCP 连接:
function Get-HeartBeat {
$url = 'ourUrl.com'
$port = 443
$clnt = New-Object Net.Sockets.TcpClient
try {
$clnt.Connect($url, $port)
1
} catch {
0
} finally {
$clnt.Dispose()
}
}
在较新的 Windows 版本中,您可以使用 Test-NetConnection
cmdlet 达到相同目的:
function Get-HeartBeat {
$url = 'ourUrl.com'
$port = 443
[int](Test-Net-Connection -Computer $url -Port $port -InformationLevel Quiet)
}