Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top
# LDAPTLS_CACERTDIR=/etc/ssl/certs/ ldapwhoami -x -ZZ -H ldaps://ldap.domain.tld
ldap_start_tls: Can't contact LDAP server (-1)
      additional info: TLS error -8172:Peer's certificate issuer has been marked as not trusted by the user.

# openssl s_client -connect ldap.domain.tld:636 -CApath /etc/ssl/certs
<... successful tls negotiation stuff ...>
    Compression: 1 (zlib compression)
    Start Time: 1349994779
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

openssl seems to think the certificate is fine, but openldap's libraries (pam_ldap exhibits similar behavior, which is how I got on to this mess) disagree.
What am I doing wrong?

share|improve this question
up vote 7 down vote accepted

RHEL does not in fact provide anything that can be used as a 'certificate directory' for CA trust purposes. For OpenSSL, a certificate directory - a 'CApath' - is a directory containing individual certificate files (in PEM format or OpenSSL's extended 'trusted certificate' format), with names in a specific format based on a hash of the certificate's subject name. Usually this is achieved by putting files with human-readable names and .pem extensions in a directory and running c_rehash on it (see man c_rehash). For GnuTLS since 3.3.6 (prior to that GnuTLS had no directory support), it's just a directory with PEM files in it; GnuTLS will try and load every file in the directory and succeed on anything PEM-ish (it can't handle OpenSSL's 'trusted certificate' format). I'm not honestly sure if NSS can actually use a directory full of individual certificate files as a trust root somehow, but OpenLDAP's documentation seems to suggest it can (but if the directory also contains an NSS database it'll give that priority). Regardless, RHEL doesn't have anything like a directory full of individual CA certificate files.

Debian and derivatives provide /etc/ssl/certs in this format; /etc/ssl/certs is the canonical trust store location on Debian, and IMO anything that provides it should basically lay it out like Debian's, as Debian's had that directory laid out in more or less the same way since like 1999. RHEL has a /etc/ssl/certs directory, but it is in not in this format - it doesn't contain any individual certificate files at all. You can't use it as a CApath. Honestly, on RHEL (and Fedora, and derivatives) that directory is basically a trap. Don't use it. (See https://bugzilla.redhat.com/show_bug.cgi?id=572725 and https://bugzilla.redhat.com/show_bug.cgi?id=1053882 for some background on why it exists in the first place, and how I'm trying to get it fixed). So I think you're right about what's going on, but wrong about the reason why. OpenLDAP isn't doing anything wrong, and it's not failing because "ca-bundle.trust.crt...is a Mozilla NSS cert/key database" (those are called cert8/9.db and key3/4.db, and the system-wide ones on RHEL live in /etc/pki/nssdb), it's just failing because /etc/ssl/certs is not usable as a 'certificate directory' at all.

RHEL doesn't provide anything usable as a CApath-style trust store anywhere else, either. RHEL's system trust store is provided as a single PEM bundle file (a 'CAfile' in OpenSSL terms), which can be found at /etc/pki/tls/certs/ca-bundle.crt and /etc/pki/tls/cert.pem. It can also be found at /etc/ssl/certs/ca-bundle.crt as /etc/ssl/certs is actually just a symlink to /etc/pki/tls/certs, but that location is not canonical and really shouldn't be used by anything ever. RHEL also provides a bundle in OpenSSL's 'trusted certificate' format as /etc/pki/tls/certs/ca-bundle.trust.crt.

The correct thing to do, as you figured out, is to use the bundle file the system provides. Your answer will work, but for the reasons mentioned above, I would strongly recommend TLS_CACERT=/etc/pki/tls/certs/ca-bundle.crt or TLS_CACERT=/etc/pki/tls/cert.pem over TLS_CACERT=/etc/ssl/certs/ca-bundle.crt.

(There's nothing remotely new in any of this, btw, but confusion on the interwebs is widespread. RH and derivatives have never provided a directory-full-of-certificates, ever. They have provided a bundle file since the year 2000. It was moved from /usr/share/ssl to /etc/pki/tls in 2005. Debian has had both /etc/ssl/certs as a CApath-style directory and /etc/ssl/certs/ca-certificates.crt as a bundle file more or less since the stone age.)

share|improve this answer

/etc/ssl/certs/ contains /etc/ssl/certs/ca-bundle.trust.crt as part of ca-certificates-2010.63-3.el6_1.5.noarch, which is a Mozilla NSS cert/key database. Inclusion of this file within TLS_CACERTDIR causes all other files to be ignored.

TLS_CACERTDIR
Specifies the path of a directory that contains Certificate Authority certificates in separate individual files. The TLS_CACERT is always used before TLS_CACERTDIR.` This parameter is ignored with GnuTLS.

When using Mozilla NSS, may contain a Mozilla NSS cert/key database. If contains a Mozilla NSS cert/key database and CA cert files, OpenLDAP will use the cert/key database and will ignore the CA cert files.`

However, openldap-2.4.23-26.el6_3.2.i686 doesn't seem to handle this properly.

Short Answer
Use LDAPTLS_CACERT=/etc/ssl/certs/ca-bundle.crt
(config file TLS_CACERT=/etc/ssl/certs/ca-bundle.crt)
This file is also included provided by ca-certificates-2010.63-3.el6_1.5.noarch.

share|improve this answer

This is a very common problem, don't fret I have an answer for you.

First RHEL Clones have have two ldap.conf files, /etc/ldap.conf or in RHEL6 is is deprecated but you can use /etc/nslcd.conf for authentication now /etc/openldap/ldap.conf is only for queries, so ldapsearch, ldapmodify, ldapremove, it's really your profile so you don't have to have a nasty long string each time you want to run an ldap command.

Now with that out of the way, you have two parameters,

  • tls_cacertfile - explicitly define the ca cert and you should be good to go
  • tls_cacertdir - drop in the ca cert into the directory but it won't work, because it needs to be hashed ...

use openssl x509 -hash -noout -in $file , ln -s $file $file.0 , then your CA cert will work.

Also note if the config file is in CAPS, you are working in /etc/openldap/ldap.conf, they are very different files.

Hope this clears things up.

share|improve this answer

Anyone else runs into this; this is what worked for me on centos 6 openldap and sssd:

notes: a. Some "smart guy" decided to make sssd require TLS/SSL; behavior change from centos5; this is great for external systems; but when you have 300+nodes on internal appliance with a unreachable internal network to the machine cluster; this is extremely useless security feature.

b. Furthermore self singed certificates do not seem to work anymore; will continue trying

c. Avoid NSLCD at all costs; was plagued with non-stop issues when i set the legacy flag and used instead of sssd (netgroups; deadlocking syslog, etc..).

To get up and running using sssd;

  1. sssd.conf

    [domain/default]
    ldap_id_use_start_tls = True
    id_provider = ldap
    auth_provider = ldap
    chpass_provider = ldap
    cache_credentials = True
    ldap_search_base = dc=local
    enumerate = True
    ldap_uri = ldap://192.168.1.2/
    ldap_tls_cacertdir = /etc/openldap/cacerts
    ldap_tls_reqcert = allow
    ldap_schema = rfc2307bis
    
  2. slapd.conf

    TLSCACertificateFile   /etc/openldap/cacerts/ca-bundle.crt
    TLSCertificateFile      /etc/openldap/cacerts/slapd.pem
    TLSCertificateKeyFile   /etc/openldap/cacerts/slapd.pem
    TLSCipherSuite HIGH:MEDIUM:-SSLv2
    
  3. ldap.conf

    URI ldap://192.168.1.2/
    BASE dc=local
    
    TLS_CACERTDIR /etc/openldap/cacerts
    
share|improve this answer
    
I wouldn't say it's a useless feature. You avoid internal eaves dropping for one. You avoid appliances to be able to tap into traffic where you don't want it to. There's a number of reasons why this isn't useless. – Torxed Jan 12 at 17:20
    
On a internal network running 40gig-100gig? Seriously? What are you going to use to tap the backend of a HPC? Just FYI; that's 1gigabyte of data a second. This is the problem with forced security model... It makes generalized assumptions for all end users. Like you just did... On a model where I am running a proprietary 100% internal network; with 16megabyte MTUs and monstrous pipes; 100% useless. We use other models for security and don't rely on LDAP/TLS to encrypt data in motion. – zerobane Jan 14 at 16:23
    
I'm not getting into a pissing contest with a hot headed writer on the Internet. But if you're only pushing a gig per second and running 100-500 hosts I really don't see the issue here. Sure TLS does require more CPU load but there are ways to optimize this and restructure the network (sounds like this might be needed anyway if the marginal overhead from TLS affects it this much). It is also not forced upon you, go with a less secure library than sssd for instance. – Torxed Jan 14 at 16:30
    
No reason for derogatory remarks and attacks; lets stick with facts. Going guess you submitted the forced security model or supported the model. Just a FYI; 1-2% in HPC world is considered tremendous. Its not 100-500 hosts; if you consider hosts = cpu; you are talking 10,000+ hosts. We will probably end up branching code or going back to nslcd instead. The issue with using a "less" secure model is net-groups support. Optimize and restructure network; lol; only the leading super computer company; sure let us know how to do it and show us the patent. – zerobane Jan 14 at 18:13

According to the every man page I've seen (but I am not a CentOS user) there is no such thing as LDAPTLS_CACERTDIR. The correct variable to set is TLS_CACERTDIR. You should set it permanently in /etc/openldap/ldap.conf or wherever CentOS keeps the LDAP library configuration file. Also, you may need to configure pam-ldap itself to look for the CA certs. In CentOS this is /etc/pam_ldap.conf, I think, and the variable to set is tls_cacertdir.

share|improve this answer
    
I attempted the file method first, but elected to use the shell variable for brevity. If you read the man pages Environmental variables may also be used to augment the file based defaults. The name of the variable is the option name with an added prefix of LDAP. For example, to define BASE via the environment, set the variable LDAPBASE to the desired value. – 84104 Oct 11 '12 at 23:52
    
You are right of course, my bad. I never read that part of the man page since I always use the configuration file. I was scanning the man page for occurrences of LDAPTLS_CACERTDIR and didn't find any, so I assumed you mixed up your variables. Sorry. – daff Oct 12 '12 at 0:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.