连接到 Google LDAP 服务器的 SNI 问题
SNI issues connecting to Google LDAP server
我正在尝试使用证书连接到 Google 的 LDAP 服务器,基本代码是
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
$ldap = ldap_connect('ldaps://ldap.google.com', 636);
putenv('LDAPTLS_REQCERT=demand');
putenv("LDAPTLS_CACERT=/etc/ssl/certs/ca-certificates.crt");
putenv("LDAPTLS_CERT=" . path('Google_2024_01_22_49615.crt'));
putenv("LDAPTLS_KEY=" . path('Google_2024_01_22_49615.key'));
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_start_tls($ldap);
ldap_sasl_bind($ldap, null, '', 'EXTERNAL');
$resuts = ldap_search($ldap, 'dc=foo,dc=com', 'uid=*');
print_r(ldap_get_entries($ldap, $searchResults));
它在 ldap_start_tls
和 Unable to start TLS: Can't contact LDAP serer
上失败,进一步调查我可以看到真正的错误是由 hostname (ldap.google.com) does not match common name in certificate (invalid2.invalid)
引起的 TLS: peer cert untrusted or revoked (0x42)
。 Google returns 此证书表明不支持 SNI (https://support.google.com/a/answer/9190869)
但我的 PHP 版本是 2020 年 12 月在 Ubuntu 20.04 上编译的 7.1.33,带有 OpenLDAP 20449(启用了 SASL 支持)和 OpenSSL 1.1.1i。那么为什么我不支持 SNI 呢?在其他地方我看到人们使用 LDAPTLS_REQCERT=never
来绕过这个问题,但是由于 Google 需要 TLS 证书和 SASL 我需要使用 LDAPTLS_REQCERT=demand
或 PHP 不会让我使用SASL 外部身份验证机制(https://gist.github.com/heiglandreas/8a299a6f47a13ba463c3f2da41c679f7),我将无法进行身份验证
值得注意的是,在同一台机器上,以下命令完美运行,使用 SASL EXTERNAL 进行身份验证并列出用户 LDAPTLS_CERT=Google_2024_01_22_49615.crt LDAPTLS_KEY=Google_2024_01_22_49615.key ldapsearch -X -W -D uid=MyUUID,ou=Users,dc=foo,dc=com -H ldaps://ldap.google.com:636 -b dc=foo,dc=com
我也尝试过使用 PHP 选项 LDAP_OPT_X_TLS_REQUIRE_CERT
、LDAP_OPT_X_TLS_CACERTDIR
、LDAP_OPT_X_TLS_CACERTFILE
、LDAP_OPT_X_TLS_KEYFILE
和 LDAP_OPT_X_TLS_CERTFILE
,但它们没有没有什么不同
我的问题是同时使用 ldap_start_tls
和 ldap_sasl_bind
(或 ldap_bind
),而您只需要一个来打开连接,以及使用 ldap_set_option
与 ldap_set_option($ldap, LDAP_OPT_X_TLS_KEYFILE, $keyFilePath);
之类的资源,当它应该像 ldap_set_option(null, LDAP_OPT_X_TLS_KEYFILE, $keyFilePath);
一样用于 null 时,因为它覆盖了 /etc/ldap/ldap.conf 变量。
关注 https://www.php.net/manual/en/function.ldap-get-option.php#124601 有助于解决这个问题
我正在尝试使用证书连接到 Google 的 LDAP 服务器,基本代码是
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
$ldap = ldap_connect('ldaps://ldap.google.com', 636);
putenv('LDAPTLS_REQCERT=demand');
putenv("LDAPTLS_CACERT=/etc/ssl/certs/ca-certificates.crt");
putenv("LDAPTLS_CERT=" . path('Google_2024_01_22_49615.crt'));
putenv("LDAPTLS_KEY=" . path('Google_2024_01_22_49615.key'));
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_start_tls($ldap);
ldap_sasl_bind($ldap, null, '', 'EXTERNAL');
$resuts = ldap_search($ldap, 'dc=foo,dc=com', 'uid=*');
print_r(ldap_get_entries($ldap, $searchResults));
它在 ldap_start_tls
和 Unable to start TLS: Can't contact LDAP serer
上失败,进一步调查我可以看到真正的错误是由 hostname (ldap.google.com) does not match common name in certificate (invalid2.invalid)
引起的 TLS: peer cert untrusted or revoked (0x42)
。 Google returns 此证书表明不支持 SNI (https://support.google.com/a/answer/9190869)
但我的 PHP 版本是 2020 年 12 月在 Ubuntu 20.04 上编译的 7.1.33,带有 OpenLDAP 20449(启用了 SASL 支持)和 OpenSSL 1.1.1i。那么为什么我不支持 SNI 呢?在其他地方我看到人们使用 LDAPTLS_REQCERT=never
来绕过这个问题,但是由于 Google 需要 TLS 证书和 SASL 我需要使用 LDAPTLS_REQCERT=demand
或 PHP 不会让我使用SASL 外部身份验证机制(https://gist.github.com/heiglandreas/8a299a6f47a13ba463c3f2da41c679f7),我将无法进行身份验证
值得注意的是,在同一台机器上,以下命令完美运行,使用 SASL EXTERNAL 进行身份验证并列出用户 LDAPTLS_CERT=Google_2024_01_22_49615.crt LDAPTLS_KEY=Google_2024_01_22_49615.key ldapsearch -X -W -D uid=MyUUID,ou=Users,dc=foo,dc=com -H ldaps://ldap.google.com:636 -b dc=foo,dc=com
我也尝试过使用 PHP 选项 LDAP_OPT_X_TLS_REQUIRE_CERT
、LDAP_OPT_X_TLS_CACERTDIR
、LDAP_OPT_X_TLS_CACERTFILE
、LDAP_OPT_X_TLS_KEYFILE
和 LDAP_OPT_X_TLS_CERTFILE
,但它们没有没有什么不同
我的问题是同时使用 ldap_start_tls
和 ldap_sasl_bind
(或 ldap_bind
),而您只需要一个来打开连接,以及使用 ldap_set_option
与 ldap_set_option($ldap, LDAP_OPT_X_TLS_KEYFILE, $keyFilePath);
之类的资源,当它应该像 ldap_set_option(null, LDAP_OPT_X_TLS_KEYFILE, $keyFilePath);
一样用于 null 时,因为它覆盖了 /etc/ldap/ldap.conf 变量。
关注 https://www.php.net/manual/en/function.ldap-get-option.php#124601 有助于解决这个问题