node-ldapjs icon indicating copy to clipboard operation
node-ldapjs copied to clipboard

LDAPS (ldap over ssl) working with ssl certificates

Open aneelaSaleem opened this issue 10 years ago • 13 comments

hi all,

i have generated self-signed certificate and i have used following code snippet to access certificates on same machine while using ldaps:///

var tlsOptions = { // This is necessary only if the server uses the self-signed certificate ca: [ fs.readFileSync('/etc/ldap/cacert.pem') ] };

var ldap = require('ldapjs'); var client = ldap.createClient({url: 'ldaps://plat.com:636',tlsOptions: tlsOptions});

this works fine if the ldap server and certificate are on same machine, but it fails if the ldap server is on remote machine.

any help/guidance regarding such issue?

aneelaSaleem avatar Oct 12 '15 08:10 aneelaSaleem

Because ldapjs uses the tls.TLSSocket/tls.TLSServer API for TLS sockets, I would suggest looking to that documentation in order to interpret any errors you may be observing.

pfmooney avatar Oct 12 '15 14:10 pfmooney

Thanks prmooney.

can you please give some examples how to start TLS in ldap. Because i spent much time starting TLS but i was not successful. But LDAP with SSL was successfully working for me. That's why i chose ssl.

aneelaSaleem avatar Oct 12 '15 19:10 aneelaSaleem

And also it was working fine with the above code snippet on same machines.

aneelaSaleem avatar Oct 12 '15 19:10 aneelaSaleem

I'm stuck at this problem for days. Please guide me

aneelaSaleem avatar Oct 13 '15 20:10 aneelaSaleem

I would suggest starting with the node.js documentation on TLS.

pfmooney avatar Oct 14 '15 01:10 pfmooney

yes i have followed the documentation

https://nodejs.org/api/tls.html

Also tried following code snippet and other combinations as well

var tls = require('tls'); var fs = require('fs');

var options = { key: fs.readFileSync('server-key.pem'), cert: fs.readFileSync('server-cert.pem'),

// This is necessary only if using the client certificate authentication. requestCert: true,

// This is necessary only if the client uses the self-signed certificate. ca: [ fs.readFileSync('client-cert.pem') ] };

var server = tls.createServer(options, function(socket) { console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized'); socket.write("welcome!\n"); socket.setEncoding('utf8'); socket.pipe(socket); }); server.listen(8000, function() { console.log('server bound'); });

But get the exception i.e., events.js:72 throw er; // Unhandled 'error' event ^ Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE at SecurePair. (tls.js:1370:32) at SecurePair.EventEmitter.emit (events.js:92:17) at SecurePair.maybeInitFinished (tls.js:982:10) at CleartextStream.read as _read at CleartextStream.Readable.read (_stream_readable.js:320:10) at EncryptedStream.write as _write at doWrite (_stream_writable.js:223:10) at writeOrBuffer (_stream_writable.js:213:5) at EncryptedStream.Writable.write (_stream_writable.js:180:11) at write (_stream_readable.js:583:24)

aneelaSaleem avatar Oct 14 '15 06:10 aneelaSaleem

I'm continuously getting below error:

events.js:72 throw er; // Unhandled 'error' event ^ Error: socket hang up at SecurePair.error (tls.js:1013:23) at EncryptedStream.CryptoStream._done (tls.js:705:22) at CleartextStream.read as _read at CleartextStream.Readable.read (_stream_readable.js:320:10) at EncryptedStream.onCryptoStreamFinish (tls.js:301:47) at EncryptedStream.g (events.js:180:16) at EncryptedStream.EventEmitter.emit (events.js:117:20) at finishMaybe (_stream_writable.js:356:12) at endWritable (_stream_writable.js:363:3) at EncryptedStream.Writable.end (_stream_writable.js:341:5)

Following is my server-side code:

var tlsOptions= { key: fs.readFileSync('/home/aneela/client-ldapjs/serverkey.pem'), cert: fs.readFileSync('/home/aneela/client-ldapjs/servercrt.pem'), requestCert: true, // This is necessary only if the server uses the self-signed certificate rejectUnauthorized: true, ca: [ fs.readFileSync('/etc/ldap/servercrt.pem') ] };

var server = tls.createServer(tlsOptions, function(socket) { console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); process.stdin.resume(); process.stdin.pipe(server); }); server.listen(8001, function() { console.log('server bound'); });

Following is my client-side code: var tlsOptions = { // These are necessary only if using the client certificate authentication key: fs.readFileSync('/etc/ldap/serverkey.pem'), cert: fs.readFileSync('/etc/ldap/servercrt.pem'), ca: CAcerts, //where CAcerts is the certificate chain requestCert: true, rejectUnauthorized: true };

var server = tls.connect(8001,tlsOptions, function() {

    console.log('client connected', server.authorized ? 'authorized' : 'unauthorized');
    if(!server.authorized) {
console.log("authorizationError: " + server.authorizationError);

} process.stdin.resume(); process.stdin.pipe(server); });

server.setEncoding('utf8'); server.on('data',function(data){ console.log(data); }); server.on('end', function() { console.log('client closing...'); server.close(); });

aneelaSaleem avatar Oct 14 '15 10:10 aneelaSaleem

Hi pfmooney!

I have spent a lot of time discovering the solution. The following code works fine in my case. Just wanted a little bit guidance. Please have a look on following code and tell me is it the correct approach?

//Server.js file

var fs = require('fs'); var tls = require('tls');

var tlsOptions = { key: fs.readFileSync('/etc/ldap/serverkey.pem'), cert: fs.readFileSync('/etc/ldap/servercrt.pem'), requestCert: true, rejectUnauthorized: true, ca: [ fs.readFileSync('/etc/ssl/certs/cacert.pem') ] };

var server = tls.createServer(tlsOptions, function(socket) { console.log(socket.getPeerCertificate()); console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); socket.write("welcome Client!\n"); socket.setEncoding('utf8'); socket.pipe(socket); }); server.on('data',function(data){ console.log(data); }); server.on('uncaughtException', function(error) { console.log('error ',error); }); server.listen(8002, function() { console.log('server bound'); });

//Client.js file

var fs = require('fs'); var tls = require('tls'); var ldap = require('ldapjs');

var tlsOptions = { host: 'plat.com', key: fs.readFileSync('/etc/mycerts/clientkey.pem'), cert: fs.readFileSync('/etc/mycerts/clientcrt.pem'), ca: fs.readFileSync('/etc/ssl/certs/cacert.pem') };

var server = tls.connect(8002,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://plat.com:636',tlsOptions:tlsOptions});
            client.bind(dn, password, function (err) {
            cb(err === null, err);
            });

//Perform LDAP search operation var opts = { filter: '(&(objectclass=organizationalRole))', scope: 'sub', attributes: ['cn'] };

            client.search('dc=plat,dc=com', 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); });

aneelaSaleem avatar Oct 18 '15 17:10 aneelaSaleem

Hi @aneelaSaleem @pfmooney Were you able to get a final solution for this? I am also facing a similar issue.

biswasaveek avatar Apr 18 '17 09:04 biswasaveek

Please use backticks for syntax highlighting, it's much easier to read

```js your code goes here ```

ORESoftware avatar Jun 15 '17 23:06 ORESoftware

I'm sorry to bump this, but I am still unable to use the createClient to connect to an OpenLDAP server using a certificate key:crt pair. I've been looking for days and trying so many ways of doing this, and I still am unable to get anything to work. Can someone please give a concrete example of how this works using this API? The documentation doesn't even cover the basics. I've also looked at the source code and I can't really make out how it is handled either. I'm out of options here...

nathandtrone avatar Feb 07 '19 13:02 nathandtrone

Had a similar issue here but solved it by https://github.com/ldapjs/node-ldapjs/issues/229

Unsure though if that's satisfactory for you, since it doesn't involve actually using certificates, though it does connect to a secure LDAPS server successfully with

tlsOptions = { 'rejectUnauthorized': false }

The LDAPS server I am talking to seems to accept this.

SineOfLight avatar Mar 16 '20 14:03 SineOfLight

If you've come here looking for an implementation of SASL ldapts has an implementation on v3.2.0

wattry avatar Dec 22 '21 13:12 wattry

👋

On February 22, 2023, we released version 3 of this library. As a result, we are closing this issue/pull request.

Please see issue #839 for more information, including how to proceed if you feel this closure is in error.

jsumners avatar Feb 22 '23 19:02 jsumners