Score:0

PHP8 ldap_bind : Error -1 Can't contact LDAP server

us flag

I m on almalinux 8.7 with PHP8. Test ldapsearch with TLS is ok

ldapsearch -H ldap://xxxx -x -ZZ /etc/pki/tls/certs/xxxx.pem -D 'xxxxx' -w 'xxxx' -b 'cn=xxx,cn=users,dc=xxx,dc=xxxx'

But ldap_bind won't find ldap server. Error -1. Without ldap_start_tls($ldap_con);, it is ok.

- EDIT error message :

  • enter image description here

What am i missing?

if(empty(!$_POST["password"]))
        {
        // Configuration pour interface PHP de notre annuaire LDAP
        $server = "ldap://xxx:389";
        $login =  $_POST['login'];
        $password = $_POST['password'];
        $basedn = 'dc=xxx,dc=xxx';
        $group = 'xxxxx';

        // Connexion à LDAP.
        echo "Connexion...<br>";
        $ldap_con=ldap_connect($server) or die('Could not connect to LDAP server.');
        ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, "/etc/pki/tls/certs/xxx.pem");
        ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, "/etc/pki/tls/private/xxx.key");
        ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
        ldap_set_option($ldap_con, LDAP_OPT_REFERRALS, 0);
        ldap_set_option($ldap_con, LDAP_OPT_NETWORK_TIMEOUT, 10);
        ldap_start_tls($ldap_con);

        if (!@ldap_bind($ldap_con, $login . "@xxxx", $password))
                {
                // Ici on peut voir quelle est la vraie nature de l'erreur (commenter la redirection)
                 echo "<p>Error:" . ldap_error($ldap_con) . "</p>";
                 echo "<p>Error number:" . ldap_errno($ldap_con) . "</p>";
                 echo "<p>Error:" . ldap_err2str(ldap_errno($ldap_con)) . "</p>";
                // Rediriger quand erreur
                // header("Location: https://xxxxx?error=1");
                }
        else
                {
                echo("Login correct <br>");

Tests with debug

> <?php
>         $server = "ldap://xxxx:389";
>         $login =  "xxxx";
>         $password = "xxxx";
>         $basedn = 'dc=xxx,dc=com';
>         $group = 'xxxx';
> 
>         // Connexion à LDAP.
>         echo "Connexion...<br>";
>         $ldap_con=ldap_connect($server) or die('Could not connect to LDAP server.');
>         ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, "/etc/pki/tls/certs/xxxx.pem");
>         ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, "/etc/pki/tls/private/xxxx.key");
>         ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
>                 ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
>         ldap_set_option($ldap_con, LDAP_OPT_REFERRALS, 0);
>         ldap_set_option($ldap_con, LDAP_OPT_NETWORK_TIMEOUT, 10);
>         ldap_start_tls($ldap_con);
> 
>         ldap_bind($ldap_con, $login . "@xxxx", $password) ?>

Output

> Connexion...<br>ldap_extended_operation_s ldap_extended_operation
> ldap_send_initial_request ldap_new_connection 1 1 0
> ldap_int_open_connection ldap_connect_to_host: TCP xxx:389
> ldap_new_socket: 4 ldap_prepare_socket: 4 ldap_connect_to_host: Trying
> xxxx:389 ldap_pvt_connect: fd: 4 tm: 10 async: 0 ldap_ndelay_on: 4 attempting to connect: connect errno: 115 ldap_int_poll: fd: 4 tm:
> 10 ldap_is_sock_ready: 4 ldap_ndelay_off: 4 ldap_pvt_connect: 0
> ldap_open_defconn: successful ldap_send_server_request ldap_result ld
> 0x55808231ec30 msgid 1 wait4msg ld 0x55808231ec30 msgid 1 (infinite
> timeout) wait4msg continue ld 0x55808231ec30 msgid 1 all 1
> ** ld 0x55808231ec30 Connections:
> * host: xxxx port: 389  (default)   refcnt: 2  status: Connected   last used: Mon Nov 28 11:31:12 2022
> 
> 
> ** ld 0x55808231ec30 Outstanding Requests:  * msgid 1,  origid 1, status InProgress    outstanding referrals 0, parent count 0   ld
> 0x55808231ec30 request count 1 (abandoned 0)
> ** ld 0x55808231ec30 Response Queue:    Empty   ld 0x55808231ec30 response count 0 ldap_chkResponseList ld 0x55808231ec30 msgid 1 all 1
> ldap_chkResponseList returns ld 0x55808231ec30 NULL ldap_int_select
> read1msg: ld 0x55808231ec30 msgid 1 all 1 read1msg: ld 0x55808231ec30
> msgid 1 message type extended-result read1msg: ld 0x55808231ec30 0 new
> referrals read1msg:  mark request completed, ld 0x55808231ec30 msgid 1
> request done: ld 0x55808231ec30 msgid 1 res_errno: 0, res_error: <>,
> res_matched: <> ldap_free_request (origid 1, msgid 1)
> ldap_parse_extended_result ldap_parse_result ldap_msgfree TLS trace:
> SSL_connect:before SSL initialization TLS trace: SSL_connect:SSLv3/TLS
> write client hello TLS trace: SSL_connect:error in SSLv3/TLS write
> client hello ldap_int_tls_start: ldap_int_tls_connect needs read
> ldap_int_poll: fd: 4 tm: 10 ldap_is_sock_ready: 4 ldap_ndelay_off: 4
> TLS trace: SSL_connect:SSLv3/TLS write client hello TLS trace:
> SSL_connect:SSLv3/TLS read server hello TLS certificate verification:
> depth: 1, err: 0, subject: /DC=com/DC=xxx/CN=xxxx, issuer:
> /DC=com/DC=xx/CN=xx-CA TLS certificate verification: depth: 0,
> err: 0, subject: , issuer: /DC=com/DC=xxx/CN=xxxx TLS trace:
> SSL_connect:SSLv3/TLS read server certificate TLS trace:
> SSL_connect:SSLv3/TLS read server key exchange TLS trace:
> SSL_connect:SSLv3/TLS read server certificate request TLS trace:
> SSL_connect:SSLv3/TLS read server done TLS trace:
> SSL_connect:SSLv3/TLS write client certificate TLS trace:
> SSL_connect:SSLv3/TLS write client key exchange TLS trace:
> SSL_connect:SSLv3/TLS write certificate verify TLS trace:
> SSL_connect:SSLv3/TLS write change cipher spec TLS trace:
> SSL_connect:SSLv3/TLS write finished TLS trace: SSL_connect:error in
> SSLv3/TLS write finished ldap_int_tls_start: ld 0x55808231ec30 9 s
> 976966 us to go ldap_int_tls_start: ldap_int_tls_connect needs read
> ldap_int_poll: fd: 4 tm: 9 ldap_is_sock_ready: 4 ldap_ndelay_off: 4
> TLS trace: SSL_connect:SSLv3/TLS write finished TLS trace:
> SSL_connect:SSLv3/TLS read change cipher spec TLS trace:
> SSL_connect:SSLv3/TLS read finished ldap_sasl_bind_s ldap_sasl_bind
> ldap_send_initial_request ldap_send_server_request ldap_result ld
> 0x55808231ec30 msgid 2 wait4msg ld 0x55808231ec30 msgid 2 (infinite
> timeout) wait4msg continue ld 0x55808231ec30 msgid 2 all 1
> ** ld 0x55808231ec30 Connections:
> * host: xxxx port: 389  (default)   refcnt: 2  status: Connected   last used: Mon Nov 28 11:31:12 2022
> 
> 
> ** ld 0x55808231ec30 Outstanding Requests:  * msgid 2,  origid 2, status InProgress    outstanding referrals 0, parent count 0   ld
> 0x55808231ec30 request count 1 (abandoned 0)
> ** ld 0x55808231ec30 Response Queue:    Empty   ld 0x55808231ec30 response count 0 ldap_chkResponseList ld 0x55808231ec30 msgid 2 all 1
> ldap_chkResponseList returns ld 0x55808231ec30 NULL ldap_int_select
> read1msg: ld 0x55808231ec30 msgid 2 all 1 read1msg: ld 0x55808231ec30
> msgid 2 message type bind read1msg: ld 0x55808231ec30 0 new referrals
> read1msg:  mark request completed, ld 0x55808231ec30 msgid 2 request
> done: ld 0x55808231ec30 msgid 2 res_errno: 0, res_error: <>,
> res_matched: <> ldap_free_request (origid 2, msgid 2)
> ldap_parse_result ldap_msgfree ldap_free_connection 1 1
> ldap_send_unbind TLS trace: SSL3 alert write:warning:close notify
> ldap_free_connection: actually freed

EDIT

Launched a strace ps awux | grep sbin/httpd | awk '{print"-p " $2}' | xargs strace -f but nothing to note.

Strace on php-fpm strace -f $(pidof php-fpm | sed 's/\([0-9]*\)/\-p \1/g')

[pid 340925] openat(AT_FDCWD, "/etc/pki/tls/private/xxx.key", O_RDONLY) = -1 EACCES (Permission non accordée)
[pid 340925] write(2, "TLS: could not use key file `/et"..., 70) = 70
[pid 340925] write(2, "TLS: error:0200100D:system libra"..., 85) = 85
[pid 340925] write(2, "TLS: error:20074002:BIO routines"..., 80) = 80
[pid 340925] write(2, "TLS: error:140B0002:SSL routines"..., 90) = 90

   

File /var/log/php-fpm/www-error.log

[30-Nov-2022 08:00:01 UTC] PHP Warning:  ldap_start_tls(): Unable to start TLS: Connect error in /var/www/html/SI/test2.php on line 17
[30-Nov-2022 08:00:01 UTC] PHP Warning:  ldap_bind(): Unable to bind to server: Can't contact LDAP server in /var/www/html/SI/test2.php on line 37

Thanks

Score:0
rs flag

There is probably some confusion going on between StartTLS and TLS, those are two differrent things.

When using StartTLS, you connect to plaintext port (389/tcp for LDAP) and then you issue a command that initiates the encrypted transport. When you call ldapsearch -ZZ ... that means you are invoking StartTLS.

When using "real" SSL/TLS, you connect to encrypted port (636/tcp by default for LDAP), encrypted channel is set up and then the LDAP protocol communication start take effect.

So you are either missing some OPTS in your PHP code to make StartTLS work, or you should use ldaps://hostname/ as your LDAP URI.

Edit: Although factually correct, the root cause does not seem to be in the TLS-StartTLS confusion. The ldap_start_tls() PHP routine probably actually invokes StartTLS so OP's use of 389/tcp is correct.

Alex Lum avatar
us flag
I've tried ldaps://hostname/ and same error. this is very strange because when i debug with my test script (which is the same than prod script), it is ok. Error seems to happen only with apache. I do not have selinux enabled and firewalld is disabled.
rs flag
My bad, sorry. The `ldap_start_tls` seems to use StartTLS so using plaintext ldap port should be correct. Other possible issue is server cert validation. Do you trust the server's (or CA's) certificate?
Alex Lum avatar
us flag
Yes i trust it. "SSL_connect:SSLv3/TLS read server hello TLS certificate verification: > depth: 1, err: 0, subject: /DC=com/DC=xxx/CN=xxxx, issuer: > /DC=com/DC=get/CN=xx-CA TLS certificate verification: depth: 0"
rs flag
Is your error code really `-1`? That looks more like a client library error. If it was `1` in the sense of LDAP error code, then it is just a "generic error". Do you have access to the LDAP logs? Maybe there will be something useful.
Alex Lum avatar
us flag
yes, error number is -1. i ve put error message in edit. I will search ldap log, it is an Active Directory. Note that on centos7 with php8 it is working. maybe it is a missing prerequisite.
Alex Lum avatar
us flag
I confirm, when launched from php cli, it works see "output" part on original post, but not on apache (error -1).
rs flag
That's weird. :-/ At this point I would probably run a strace on it if something shows up.
Alex Lum avatar
us flag
how can i launch httpd with strace?
rs flag
That depends on your setup, you will need to investigate a bit. I believe the "standard way" of deploying PHP on RHEL8 flavors is with php-fpm and it is installed automatically. The starting point would be editing the systemd unit of the daemon you need to trace.
Alex Lum avatar
us flag
I launched `ps awux | grep sbin/httpd | awk '{print"-p " $2}' | xargs strace -f`, result on original post.
Score:0
us flag

Found. Many thanks to @Fiisch.

Solution : -rw-r-----. 1 root apache 3272 28 nov. 11:35 xx.key

it was working as root but not as apache. Just a question, is it secure enough?

rs flag
Glad you found the solution! Permissions look as correct as they possibly can - the PHP must be able to read the file, there is no way around that. :)
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.