Active-Directory

需要幫助使用安全 LDAP 設置 Google Cloud Directory Sync with AD

  • September 23, 2020

我想看看是否有其他人通過安全 LDAP (LDAPS) 使用其 Active Directory 設置了 Google Cloud Directory Sync (GCDS aka GADS)。我們一直在通過埠 389 進行同步,我想加密該連接,但是當我切換到埠 636 時,連接失敗。

我在域中的成員伺服器上執行 GCDS 工具 - 我嘗試在埠 636 上建立的連接是在 Google 的異地伺服器和我的 DC 之間,還是在 GCDS 工具和我的 DC 之間?即使它在 GCDS 工具和我的 DC 之間,它是否仍然需要第 3 方證書或自簽名證書就足夠了,因為該軟體正在加入域的伺服器上執行?我應該在 DC 上執行程序嗎?

如果這是我需要第 3 方證書的問題,我將不勝感激,因為我對證書不是特別了解。謝謝!

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

引用自:https://serverfault.com/questions/852604