Project

General

Profile

Actions

Bug #17063

open

pfSense Plus 26.07 - Google Secure LDAP client certificate fails when TLS certificate options are set after ldap_connect()

Bug #17063: pfSense Plus 26.07 - Google Secure LDAP client certificate fails when TLS certificate options are set after ldap_connect()

Added by nicnac nicnac 2 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Authentication
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Plus Target Version:
Release Notes:
Default
Affected Version:
2.6.x
Affected Architecture:
1541

Description

Environment

pfSense Plus: 26.07-RELEASE
Authentication backend: Google Workspace Secure LDAP
LDAP server: ldap.google.com
Port: 636
Transport: SSL/TLS
LDAP protocol: Version 3
CA: Global Root CA List
Client certificate: Google Secure LDAP client certificate imported into pfSense Certificate Manager
Bind authentication: Google Secure LDAP Access Credentials

Problem

Google Secure LDAP authentication fails when configured through a pfSense LDAP Authentication Server according to the Netgate Google Workspace Secure LDAP recipe.

Diagnostics > Authentication reports that pfSense cannot bind to the LDAP server.

The same Google Secure LDAP server, client certificate/private key, and Access Credentials work successfully from the same pfSense system when tested directly with ldapsearch and PHP LDAP.

Testing indicates that the failure depends on whether the TLS client certificate/key are configured before or after ldap_connect().

Test 1 - ldapsearch

Using the Google client certificate/key and Google LDAP Access Credentials:

env LDAPTLS_CERT=/tmp/client.crt LDAPTLS_KEY=/tmp/client.key \
/usr/local/bin/ldapsearch \
-H ldaps://ldap.google.com:636 \
-x \
-D "<ACCESS_USERNAME>" \
-W \
-b "dc=example,dc=com" \
"(mail=)" dn uid mail cn

Result:

ldap_bind: Success (0)
additional info: Valid access code
result: 0 Success
numEntries: 1

The expected Google Workspace user is returned.

Test 2 - PHP LDAP using LDAPTLS_CERT / LDAPTLS_KEY

When LDAPTLS_CERT and LDAPTLS_KEY are present in the environment before PHP creates the LDAP connection:

ldap_bind() = true

Test 3 - PHP, ldap_connect() BEFORE setting TLS client certificate

Sequence:

$ldap = ldap_connect("ldaps://ldap.google.com:636");

ldap_set_option(
$ldap,
LDAP_OPT_X_TLS_CERTFILE,
"/tmp/client.crt"
);

ldap_set_option(
$ldap,
LDAP_OPT_X_TLS_KEYFILE,
"/tmp/client.key"
);

ldap_bind($ldap, $username, $password);

Result:

ldap_bind() = false

Test 4 - PHP, TLS client certificate BEFORE ldap_connect()

Sequence:

ldap_set_option(
NULL,
LDAP_OPT_X_TLS_CERTFILE,
"/tmp/client.crt"
);

ldap_set_option(
NULL,
LDAP_OPT_X_TLS_KEYFILE,
"/tmp/client.key"
);

$ldap = ldap_connect("ldaps://ldap.google.com:636");

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

ldap_bind($ldap, $username, $password);

Result:

CERTFILE: true
KEYFILE: true
ldap_bind: true

pfSense source code behavior

In /etc/inc/auth.inc, the LDAP functions currently create the LDAP connection before calling ldap_setup_caenv().

For example, ldap_test_connection() performs:

$ldap = ldap_connect($ldapserver);

...

ldap_setup_caenv($ldap, $authcfg);

ldap_setup_caenv() then configures the client certificate using:

ldap_set_option(
$ldap,
LDAP_OPT_X_TLS_CERTFILE,
"{$cert_prefix}.crt"
);

ldap_set_option(
$ldap,
LDAP_OPT_X_TLS_KEYFILE,
"{$cert_prefix}.key"
);

Similar ordering appears in multiple LDAP code paths in /etc/inc/auth.inc.

On this pfSense 26.07 system, the relevant calls appear approximately at:

ldap_connect() ldap_setup_caenv()
1117 1127
1227 1237
1313 1323
1457 1467
1663 1678

Observed behavior

ldapsearch + client cert/key SUCCESS

PHP + LDAPTLS_CERT/LDAPTLS_KEY SUCCESS

PHP:
ldap_connect()
> set TLS client cert/key
> ldap_bind()
FAIL

PHP:
set TLS client cert/key
> ldap_connect()
> ldap_bind()
SUCCESS

pfSense Authentication Server FAIL

Expected behavior

Google Secure LDAP authentication using a client certificate should work through the pfSense LDAP Authentication Server as documented in the Netgate Google Workspace / Secure LDAP recipe.

Suspected cause

The TLS client certificate and private key appear to need to be configured in the OpenLDAP TLS context before ldap_connect() creates the LDAP connection.

Currently, auth.inc calls ldap_connect() before ldap_setup_caenv(), and ldap_setup_caenv() is where LDAP_OPT_X_TLS_CERTFILE and LDAP_OPT_X_TLS_KEYFILE are configured.

This ordering appears to cause Google Secure LDAP mutual TLS authentication to fail with the OpenLDAP/PHP LDAP versions included in pfSense Plus 26.07.

Additional observation

Google Secure LDAP audit logs show successful requests for the direct ldapsearch tests. During the failing pfSense Authentication Server test, no corresponding Google Secure LDAP request was observed, which is consistent with the failure occurring during local TLS/client-certificate setup before a usable LDAP session is established.

No modifications to /etc/inc/auth.inc have been made.

cat /etc/version
26.07-RELEASE

php -v
PHP 8.5.7 (cli) (built: Jun 17 2026 08:35:14) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.5.7, Copyright (c) Zend Technologies
with Zend OPcache v8.5.7, Copyright (c), by Zend Technologies

php -i | grep -iE "LDAP Support|Vendor Name|Vendor Version"
LDAP Support => enabled
Vendor Name => OpenLDAP
Vendor Version => 20613

No data to display

Actions

Also available in: Atom