我想看看是否有其他人通过安全 LDAP (LDAPS) 设置了 Google Cloud Directory Sync (GCDS 又名 GADS) 和他们的 Active Directory。我们一直通过端口 389 进行同步,我想加密该连接,但当我切换到端口 636 时,连接失败。
我正在域中的成员服务器上运行 GCDS 工具 - 我尝试在端口 636 上建立的连接是在 Google 的异地服务器和我的 DC 之间建立的,还是在 GCDS 工具和我的 DC 之间建立的?即使它是在 GCDS 工具和我的 DC 之间建立的,它是否仍然需要第三方证书,或者自签名证书是否足够,因为该软件是在加入域的服务器上运行的?我应该在 DC 上运行该程序吗?
如果这是一个需要第三方证书的问题,我将非常感激您的指导,因为我对证书并不是特别了解。谢谢!
答案1
2020 年 9 月 23 日更新 今天我更新了 GCDS,TLS 又出问题了。这次的问题在于无法从离线根 CA 访问我们的 CRL 文件。我发现 Google 已增强了针对 GCDS 证书问题的帮助页面:https://support.google.com/a/answer/3075991我在那里找到了解决方案。
2020 年 1 月 20 日更新: 预计 2020 年 3 月补丁发布后,微软将禁止不安全的绑定。这个答案可能会引起一些额外的关注,因为除非使用 TLS,否则 Google Cloud Directory Sync 很可能会无法连接到 AD。
原始答案
Google Cloud Directory Sync 是一款 Java 应用。GCDS 安装程序会在子文件夹中安装 Java 运行时环境的一个版本。该安装有自己的一组受信任的根证书颁发机构。它不使用 Windows 中安装的证书。
要使一切正常运行,您需要导入颁发域控制器所用证书的受信任证书颁发机构的公共证书。您也可以从域控制器安装公共证书,但该证书的过期时间可能比颁发证书颁发机构的证书要早得多。
Google 在这里提供了说明:https://support.google.com/a/answer/3075991?hl=en 但是,他们的指令使用的是 DC 的公共证书,而不是 CA 的证书。
获取 CA 证书。我将称之为the_cert.cer
如果您遵循 Google 的说明,则您可以从域控制器导出证书:
certutil -store My DomainController %TEMP%\the_cert.cer
但是再说一次,你最好使用 CA 证书。
将证书移至 GCDS 主机。
在 GCDS 主机上
将文件夹更改为安装 GCDS 的 jre 文件夹。对我来说,它是:
cd "c:\Program Files\Google Cloud Directory Sync\jre"
根据您的环境,您的情况可能会有所不同。
将证书安装到 Java 密钥库中:
bin\keytool -keystore lib\security\cacerts -storepass changeit -import -file %TEMP%\the_cert.cer -alias pick_a_name_you_like
该keytool
实用程序将提示:Trust this certificate? [no]:
输入“yes”并按下Enter
键。
清理:
del the_cert.cer
现在,再次违背我的建议并使用 DC 的证书,这里有一个完整的脚本,您可以通过任务计划程序运行它,以使您的证书在您的域控制器上保持最新,假设您在同一个域控制器上运行 GCDS。
<#
.SYNOPSIS
Exports the bound AD LDAPS encryption certificate and imports it into
Google Cloud Directory Sync's Java keystore, so that GCDS syncs will succeed.
.DESCRIPTION
Google Cloud Directory Sync runs on Java. Java maintains its own trusted keystore,
separate from the host operating system. Often, this keystore grows stale when updates
are neglected. Further, the keystore would never contain certificate information for
self-signed or internally-distributed certificates.
In order to make GCDS work with TLS using secure LDAPS binding, it is necessary to
export your trusted certificate from the machine's certificate store and import it into
the GCDS-bundled Java Runtime Environment's certificate store.
This script assumes the DC being contacted resides on the same host as the GCDS installation.
Given a ComputerName and Port, this script will connect to the named DC and determine the
thumbprint of the certificate bound to the DC on the specific port.
Using this thumbprint, the script then exports the certificate from the Local Computer's MY (Personal)
certificate store. This does NOT include the private key, and therefore it's safe to do this.
Next, the script deletes and re-imports the certificate into the JRE certificate store.
.PARAMETER ComputerName
Use the fully-qualified network name of the machine. We're assuming this is the same network name
that will be used in GCDS to bind against the DC, and is also the CommonName represented in the certificate.
.PARAMETER Port
Usually this will be 636, but could be custom depending on your environment.
.OUTPUTS
Will list the thumbprint of the cert found and will show stderr and stdout of the keytool commands.
Error handling could definitely be beefed up here.
.EXAMPLE
C:\PS> .\Update-JavaDomainControllerCertificate.ps1 -ComputerName my.domain.com -Port 636
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]
$ComputerName,
[int]
$Port = 636
)
$FilePath = "$($Env:TEMP)\adcert.crt"
$Certificate = $null
$TcpClient = New-Object -TypeName System.Net.Sockets.TcpClient
try {
$TcpClient.Connect($ComputerName, $Port)
$TcpStream = $TcpClient.GetStream()
$Callback = { param($sender, $cert, $chain, $errors) return $true }
$SslStream = New-Object -TypeName System.Net.Security.SslStream -ArgumentList @($TcpStream, $true, $Callback)
try {
$SslStream.AuthenticateAsClient('')
$Certificate = $SslStream.RemoteCertificate
} finally {
$SslStream.Dispose()
}
} finally {
$TcpClient.Dispose()
}
if ($Certificate) {
if ($Certificate -isnot [System.Security.Cryptography.X509Certificates.X509Certificate2]) {
$Certificate = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $Certificate
}
Write-Output "Found Certificate:"
Write-Output $Certificate
}
Export-Certificate -Cert $Certificate -Force -FilePath $FilePath | Out-Null
Set-Location -Path "C:\Program Files\Google Cloud Directory Sync\jre"
# Delete existing entry
& .\bin\keytool -keystore lib\security\cacerts -storepass changeit -delete -noprompt -alias $ComputerName 2>&1 | %{ "$_" }
# Add entry
& .\bin\keytool -keystore lib\security\cacerts -storepass changeit -importcert -noprompt -file $FilePath -alias $ComputerName 2>&1 | %{ "$_" }
Remove-Item -Path $FilePath -Force
答案2
所以,我刚刚与谷歌支持人员进行了交谈,看来我要改变方向了。他们确认客户端正在与谷歌服务器进行安全通信。他还说启用 SSL 将显著增加同步时间。另外,如果我在 DC 上运行客户端并使用 127.0.0.1,那么我甚至不必担心暴露我们网络上的流量,即使这样,如果我在成员服务器上运行它,它仍然会局限于我们的私人服务器网络。
因此,我可能会再多尝试一下,看看我是否能让 636 正常工作,但我可能不会花太多时间,因为我还有很多其他事情要处理。奇怪的是,我尝试使用装有 GADS 客户端的那台计算机上的 MS LDP 工具,它通过端口 636 连接到我的 DC,没有任何问题。我尝试了各种域\用户名组合,所有这些组合都可以在 389 上正常连接,但是一旦将其更改为 636 和 LDAP+SSL,它就会显示:
正在初始化... 错误:连接失败 异常:无法执行查询,因为基本 DN 处的对象:“DC=mydomain,DC=com”丢失或无法访问。
是的,我不太清楚为什么它无法连接到 636,但看起来我无论如何也不想让它连接。