需要帮助使用安全 LDAP 设置 Google Cloud Directory Sync with AD

Mik*_*ike 6 certificate active-directory ldap google g-suite

我想看看是否有其他人通过安全 LDAP (LDAPS) 使用他们的 Active Directory 设置了 Google Cloud Directory Sync (GCDS aka GADS)。我们一直在通过端口 389 进行同步,我想对该连接进行加密,但是当我切换到端口 636 时,连接失败了。

我正在我域中的成员服务器上运行 GCDS 工具 - 我试图在端口 636 上建立的连接是在 Google 的异地服务器和我的 DC 之间建立的,还是在 GCDS 工具和我的 DC 之间建立的?即使它在 GCDS 工具和我的 DC 之间,它是否仍然需要第 3 方证书还是自签名证书就足够了,因为该软件正在加入域的服务器上运行?我应该在 DC 上运行程序吗?

如果这是我需要第 3 方证书的问题,请提供一些指导,因为我对证书不是特别了解。谢谢!

Lar*_*man 5

2020 年 9 月 23 日 更新 今天我更新了 GCDS,TLS 的东西又坏了。这一次,问题是无法从离线根 CA 访问我们的 CRL 文件。我发现谷歌已经在这里加强了 GCDS 证书问题的帮助页面: https : //support.google.com/a/answer/3075991我在那里找到了我的解决方案。

2020 年 1 月 20 日更新: 预计在 2020 年 3 月的补丁中, Microsoft 将禁止不安全绑定。这个答案可能会引起一些额外的关注,因为除非使用 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 的证书,这里有一个完整的脚本,您可以通过 Task Scheduler 运行以保持您的证书在域控制器上保持最新,假设您在同一个域控制器上运行 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
Run Code Online (Sandbox Code Playgroud)