I have LDAP connections working properly with node-ldapjs. I am trying to implement LDAPS connections with node-ldapjs. The setup/configuration I am using is equivalent to the solution which was described as being successful by another individual and was posted here - https://github.com/mcavage/node-ldapjs/issues/307. My code is shown below. When I execute the code below, I get the following message:
{[Error: unable to get local issuer certificate] code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'}
Here is the full stacktrace -
Error: unable to get local issuer certificate
at Error (native)
at TLSSocket.<anonymous> (_tls_wrap.js:1022:38)
at emitNone (events.js:67:13)
at TLSSocket.emit (events.js:166:7)
at TLSSocket._init.ssl.onclienthello.ssl.oncertcb.TLSSocket._finishInit (_tls_wrap.js:586:8)
at TLSWrap.TLSSocket._init.ssl.onclienthello.ssl.oncertcb.ssl.onnewsession.ssl.onhandshakedone (_tls_wrap.js:428:38)
On the same client computer which my nodeJS app is running on, LDAPS binds to the remote DC are successful when I test with LDP or Apache Directory Studio.
Can anyone help me to determine (1) what is the root cause of the error message above and (2) how can I resolve this issue ?
Here is my code:
var fs = require('fs');
var tls = require('tls');
var ldap = require('ldapjs');
var tlsOptions = {
host: 'FQDN',
cert: fs.readFileSync('mycert.pem'),
ca: fs.readFileSync('my-root-CA.cer'),
rejectUnauthorized: true
};
var server = tls.connect(636,tlsOptions,function() {
console.log('tls connect');
console.log('client connected', server.authorized ? 'authorized' : 'unauthorized');
process.stdin.resume();
process.stdin.pipe(server);
if ( server.authorized )
{
var client = ldap.createClient({url: 'ldaps://domainControllerIP:636',tlsOptions:tlsOptions});
client.bind(username, password, function (err) {
cb(err === null, err);
});
//Perform LDAP search operation
var opts = {
filter: '(&(objectclass=organizationalRole))',
scope: 'sub',
attributes: ['cn']
};
client.search('dc=domain,dc=local', opts, function(err, res) {
res.on('searchEntry', function(entry) {
console.log('entry: ' + JSON.stringify(entry.object));
});
res.on('searchReference', function(referral) {
console.log('referral: ' + referral.uris.join());
});
res.on('error', function(err) {
console.error('error: ' + err.message);
});
res.on('end', function(result) {
console.log('status: ' + result.status);
});
});
}
});
server.setEncoding('utf8');
server.on('data',function(data){
console.log('data section: ',data);
});
server.on('secureConnect',function(data){
console.log('secure connect section: ',data);
});
server.on('error', function(error) {
console.log('client closing...',error);
});
I don't see a problem eyeballing your code. The raw error as reported is propagating back up from the openSSL
layer (of Node.js), and typically arises because the certificate cannot establish its trust chain; in an LDAPS context, I'd expect the problem was validating the server certificate at the client end.
This error can arise with self-signed certificates, or more generally if the trust chain depends upon the correct installation of intermediate certificates to complete the trust from a certificate authority root (assuming nothing has expired). And, in a corporate environment, this can be complicated further by the presence of proxies/firewalls, and their (mis-)configuration.
I'd suggest you concentrate your efforts on diagnosing/validating the combination of your certificates and dependencies to the trusted root CAs along the secure connections that need to be established. In this regard, other tooling, such as curl
or openssl
tools (and similar can be helpful).