Showing posts with label openldap. Show all posts
Showing posts with label openldap. Show all posts

Tuesday, 9 September 2014

SASL/DIGEST-MD5 with OpenLDAP-2.4.39

In order to authenticate users with Digest-MD5 the first choice to do is either store passwords in a file (sasldb2) on ldap server or into directory. The olcSaslAuxprops attribute in cn=config defines the path to follow.

Passwords in salsdb2

Start with:
sudo apt-get install sasl2-bin
than create a user:
sudo saslpasswd2 -c francesco
(script prompts for password and confirm password)
sudo chown openldap /etc/sasldb2
Modify cn=config with the following:
dn: cn=config
changetype: modify
replace: olcSaslAuxprops
olcSaslAuxprops: sasldb
create a map for the user:
dn: cn=config
changetype: modify
delete: olcAuthzRegexp
olcAuthzRegexp: "uid=francesco,cn=digest-md5,cn=auth" "cn=joe,dc=example,dc=org"
The entry cn=joe,dc=example,dc=org can be created later, or not created at all, if you simply need a principal to fulfill a ACL rule.
Restart OpenLDAP in order to apply olcAuthzRegexp (required by mine experience on Debian, OpenLDAP-2.4.39).
Test with:
ldapwhoami -U francesco -H ldapi:/// -Y DIGEST-MD5
SASL/DIGEST-MD5 authentication started
Please enter your password: 
SASL username: francesco
SASL SSF: 128
SASL data security layer installed.
dn:cn=joe,dc=example,dc=org
Type the password choosed in the saslpasswd2 step. If by chance you are logged is as 'francesco', the -U francesco switch can be omitted.

Passwords in directory

Create the joe user:
dn: cn=joe,dc=unimore,dc=it
objectClass: inetOrgPerson
cn: joe
sn: user
uid: joe
description: Just plain Joe
userPassword: joesecret
Rollback the olcSaslAuxprops if you changed it (if not, this step is not necessary as it is the default):
dn: cn=config
changetype: modify
replace: olcSaslAuxprops
olcSaslAuxprops: slapd
Add the olcAuthzRegexp rules to map the MD5-DIGEST username to a directory entry, and you are ready:
ldapwhoami -U francesco -H ldapi:/// -Y DIGEST-MD5
then type the joe's password (joesecret in this example).
  • "client response doesn't match what we generated (tried bogus)" means you typed the wrong password.
  • "generic failure: unable to canonify user and get auxprops" could be either userPassword is not CLEARTEXT or userPassword is not readable by joe user (because of ACLs).
You are not going to do much with MD5-DIGEST without reading: OpenLDAP docs about Mapping Authentication Identities

Monday, 8 September 2014

DIGEST-MD5 what is good for?

DIGEST-MD5 sasl auth mech require OpenLDAP to store clear text passwords in the directory.

So you could wonder if it is worth implementing it.

DIGEST-MD5 protects passwords from sniffing even if an attacker could dump the whole network traffic. On the other hand, if network traffic is not ciphered a sniffer could eavesdrop the directory data.

The use case can't be about sensible data because if you plan to store in directory data which is supposed to be read only by authorized people, you are going anyhow to implement SSL or StartTLS. So you have no need to protect passwords on the wire as the traffic on the wire is encrypted.

Odd are good that if you have public data you are not asking authentication (anonymous access is enough). So DIGEST-MD5 is useless either.

What about a directory holding public data (work telephone number, for instance), with anonymous read access but authenticated update by selected people only?

I think this is the great use case for DIGEST-MD5: a directory that can be read by anonymous readers, without SSL nor StartTLS. Authorized users can update directory with plain text data but still userpassword is safe from sniffing.

Thursday, 1 August 2013

OpenLDAP ldap backend: SASL authentication

The problem

The OpenLDAP ldap backend acts as a reverse proxy to a LDAP server containing real data. The simple binds are simply verbatim transferred to the data server and users don't even feel there is a proxy in-between.
The problem is with SASL. With a SASL bind the proxy doesn't have a password to forward to the data server. Even if proxy authenticates user with GSSAPI or EXTERNAL, proxy obtains a dn but no password. So it has to perform an anonymous bind which is different from an authenticated one. This behaviour is warned by the log line:
ldap_back_dobind_int: DN="cn=admin,dc=example,dc=org" without creds, binding anonymously

Overview

The solution uses the id_assert directive in the ldap badabase section on the proxy in order to bind to the data server with a defined principal who then proxies to the original client identity thanks to the authzTo attribute.
The OpenLDAP need three modifies:
  • id_assert section in ldap database (proxy server)
  • creation of the id_assert principal with the authzTo attribute (data server)
  • enable authzPolicy to in cn=config (data server)

ldifs needed

To enable authzPolicy on the data server: This is necessary because OpenLDAP disregards authzTo attribute in a entry unless the global olcAuthzPolicy is set.
To enable id_assert on ldap database on proxy server: The id_assert is in effect only for authenticated users to avoid using a privileged bind for anonymous users.
The proxy user is defined as follow:

Check log entries

This is a log entry for the user "a_user" bound with GSSAPI requesting his own entry:
Log on proxy:
Log on data server: Note bind is performed by cn=proxy,ou=agents,dc=example,dc=org but then authorization is performed on behalf to "a_user".

Wednesday, 24 July 2013

OpenLDAP ldap backend as a proxy

Ldap backend works as a proxy: when a client searches data, proxy forwards request to ldap servers with real data, which are served to client. This is useful for:
  • high availability: ldap backend spots faulty servers and picks the first working in a list
  • firewalling: clients connect to a single IP no matter how many ldap server are involved.
Before using ldap backend, you have to enable it: create a ldif named 'add_module_ldap.ldif' and apply with: sudo ldapadd -H ldapi:/// -Y EXTERNAL -f add_module_ldap.ldif Now you are ready to create to database by inserting the following ldif. Now queries matching the basename "dc=example,dc=org" are forwarded to the first available server between ldap1.example.org or ldap2.example.org. The proxy might take some time to spot faulty server (maybe it has to wait for a timeout), but since the next call it forwards to the last used server, the first working one. Please note:
  • the "allow all" acl is required because ldap backend perform authorization. A request is fulfilled if both the proxy and the data server allow it. Serious acl are supposed to be on the data server only (it helps sanity);
  • remember to encrypt connection between proxy and data server with 'olcDbStartTLS: start'

Tuesday, 2 July 2013

Basic setup in Debian slapd package

After issuing apt-get install slapd a few steps are required in order to:
  • change basename suffix;
  • enable logging;
  • speed up admin authentication.
The Debian version is release 7 Wheezy.

Change basename suffix

Package creates a database with suffix aligned to domain name. Domain name is read from /etc/resolv.conf or the like. If you want to change it, the dpkg command can help you:
sudo dpkg-reconfigure slapd
The second time you can choose the domain name.

Enable logging

To enable logging, create a ldif modify file:
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: Stats
name it enable_log.ldif and apply to openLDAP with:
sudo ldapmodify -H ldapi:/// -Y EXTERNAL -f enable_log.ldif
Next ensure slapd sends log to a facility, for example local6. This is done in /etc/default/slapd:
# Additional options to pass to slapd
SLAPD_OPTIONS="-l local6"
(then restart slapd). By the way, to avoid filling the hard drive with openldap log, instruct logrotate to handle them: drop in /etc/logrotate.d/ a file called 'ldap':
/var/log/ldap.log
{
       rotate 90
       daily
       missingok
       notifempty
       delaycompress
       compress
}

Speed up admin authentication

In order to avoid typing admin password to populate directory, authorize SASL/EXTERNAL with root access to do that. Create a ldif file (enable_sasl_acl.ldif):
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
 ,cn=auth manage by * break
and switch it on with:
sudo ldapmodify -H ldapi:/// -Y EXTERNAL -f enable_sasl_acl.ldif
Now you are able to add ou, users and groups without password as long you are root, with '-H ldapi:/// -Y EXTERNAL' switch.

Friday, 21 September 2012

Openldap2.4 performance boosting

According to my experience, the single directive you should add to db section to improve performance is:

olcDbCacheSize

OpenLDAP tuning guide covers that in section: 21.4.2.

To enable a 200000 entries cachesize use this ldif:

The enumeration of the whole directory (150000 entries) took 15 seconds without cachesize and less than 6 seconds with it.

Tuesday, 4 September 2012

Ppolicy overlay password checking module

How about having openldap-2.4 checking whether the changed password is digit-only or alpha-only and than rejecting it?

It could be done with the non-standard password checking module openldap extension, which requires to create a C file with your rules, compile as a shared object and put in a well-known location.

I wrote a step-by-step recipe with a template C file at:
https://github.com/francescm/ppolicy-check-password

Friday, 30 January 2009

openldap24: schema replica with syncrepl

Store configuration in the directory itself



One of the hot feature of openldap24 is to store configuration in the same ldap directory. Advantages are:

  • runtime modification of configuration with ldapmodify without service restart;

  • leverage of the syncprov replica of configuration branches, as schema or acl.



To enable storage of configuration in the directory itself, just start slapd with the -F switch, which points to a slapd.d directory, owned by ldap:ldap, usually located ad /etc/ldap/slapd.d (debian):

/usr/local/libexec/slapd -u ldap -g ldap -f slapd.conf -F slapd.d -d-1

(later remove the -f switch; older debian startup scripts do require -f so it could be necessary modify them).

How to replicate schema branch



First of all enable overlay syncprov over cn=config on the master server: this is the needed ldif to achieve that:

dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
changetype: add
objectClass: olcOverlayConfig
olcOverlay: syncprov

Or, if the configuration has not yet been migrated, edit slapd.conf:


database config
rootpw {SSHA}WGWXrWf/RG99aVWs3VBMn5nyJGzhCfkS
overlay syncprov

Than add to master server a acl to enable a user to read cn=config like:

access to dn.subtree="cn=config" by dn="cn=confreplica,dc=example,dc=com" read

slapd.conf on the slave should look:


#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/local/etc/openldap/schema/core.schema
#core.schema has to be included anyhow
#include /usr/local/etc/openldap/schema/cosine.schema
#include /usr/local/etc/openldap/schema/inetorgperson.schema
#include /usr/local/etc/openldap/schema/openldap.schema

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org

pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args

# Load dynamic backend modules:
modulepath /usr/local/libexec/openldap
moduleload back_bdb
# moduleload back_hdb
# moduleload back_ldap

[...] acl go here

loglevel stats ACL sync

database config
rootdn "cn=admin,cn=config"
rootpw {SSHA}WGWXrWf/RG99aVWs3VBMn5nyJGzhCfkS
syncrepl rid=002
provider=ldap://master.example.com:389
type=refreshAndPersist
interval=00:00:10:00
searchbase="cn=schema,cn=config"
filter="objectClass=olcSchemaConfig"
scope="sub"
binddn="cn=confreplica,dc=example,dc=com"
bindmethod=simple
credentials="secret"
# next database sections


Than, migrate configuration on slave from slapd.conf to slapd.d as usual.

Wednesday, 14 January 2009

SASL/EXTERNAL with openldap

SASL EXTERNAL mechanism allows passwordless authentication with x509 user certificates.

I believe it could prove very useful for replication, where, with simple bind, bind_dn and bind_pw were to be written in cleartext in slapd.conf.

This mechanism is also very handy because it requires encryption to work, and a clear text connection can't work.

Steps are:

  • apt-get install libsasl2-modules-ldap on the server;

  • modify slapd.conf to use TLS and to try verify peer;

  • modify user .ldaprc to include user certificate.



slapd.conf should include:

TLSCACertificateFile /etc/ssl/certs/ca-cert.pem
TLSCertificateFile /etc/ssl/certs/server.pem
TLSCertificateKeyFile /etc/ssl/private/server.key
TLSVerifyClient try

where server.pem and server.key and server certificate and unprotected key, while ca-cert.pem is the certificate file of the CA under which is issued the client user certificate.

.ldaprc:

TLS_CACERT /etc/ssl/certs/server-ca-chain.pem
TLS_CACERTDIR /etc/ssl/certs
TLS_CERT /home/user/client.pem
TLS_KEY /home/user/client.key
SASL_MECH EXTERNAL

where client.key can be protected or unprotected key and server-ca-chain is cert file of the CA which issued the server cert.

An error like this one:

ldapsearch -x -ZZ -h server.test.com 'uid=user'
ldap_start_tls: Connect error (-11)
additional info: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

means the client is using a certificate with a different CA from TLSCACertificateFile.

If everything is in order:

ldapsearch -x -ZZ -H ldap://server.test.com -b "" -LLL -s base supportedSASLMechanisms
dn:
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: CRAM-MD5
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: EXTERNAL

And it possible to launch:

ldapsearch -ZZ -h server.test.com 'uid=user'

to read in /var/log/ldap.log:

Jan 14 12:08:12 server slapd[15308]: conn=38 op=1 BIND authcid="cn=bacedifo,dc=test,dc=com" authzid="cn=bacedifo,dc=test,dc=com"
Jan 14 12:08:12 server slapd[15308]: conn=38 op=1 BIND dn="cn=bacedifo,dc=test,dc=com" mech=EXTERNAL ssf=0