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.

Friday 24 January 2014

Ruby spec a ffi-rzmq project

Intro

When working with async messaging, tests are more difficult. ffi-rzmq library is special because messages are received in a weird way:
receiver.recv_string(buffer = "")
The message payload is in the buffer variable, which is passed as a parameter. To achieve testing I had to turn buffer to a instance variable (@buffer) and I resorted to the mock results Arbitrary Handling
    # e is a Emitter instance, my fictionary zeromq-based class
    @endpoint.should_receive(:recv_string) do
      e.instance_variable_set("@buffer", my_data)
    end
    @endpoint.should_receive(:recv_string) do 
      e.instance_variable_set("@buffer", "__END_OF_DATA__")
    end
@endpoint is a mocked socket: when it receives the recv_string method, it replaces @buffer instance variable on e. Please have a look at the example code.

Tuesday 7 January 2014

Protect your Hawt.IO ActiveMQ-5.9.0 console with LDAP

Starting from version 5.9.0, activemq is shipped with the hawt.io web console.

Out-of-the-box the credentials to access are admin:admin, istructions are at: $ACTIVEMQ_HOME/docs/WebConsole-README.txt.

In order to enable a LDAP based authorization, you need to modify the jaas conf file (default is: $ACTIVEMQ_HOME/conf/login.config) and a couple of Java Additional Parameters ($ACTIVEMQ_OPTS) which can be specified in various places, wrapper.conf, for example.

You also need a java LDAP library: ldaptive. Please copy the newest ldaptive jar file from http://www.ldaptive.org/download in your $ACTIVEMQ_HOME/lib.

login.config

The login.config should look like:
The cn=hawtio,ou=agents,dc=example,dc=org is a principal allowed to browse the groups' memberships.
Users allowed to access to hawt.io have to be members of the cn=the_admins_group,ou=groups,dc=example,dc=org group.

The LDAP server is ldap.example.org and it is contacted over TLS.

Java Additional Parameters

The relevant Java Additional Parameters are:
  • hawtio.realm=activemq: should match the key if config.login (activemq in the previous example);
  • hawtio.role=admins: group membership required. As the defaultRole membership is granted to the users found in the roleFilter, you need to match the defaultRole;
  • hawtio.rolePrincipalClasses=org.ldaptive.jaas.LdapRole: the java class of the role. The given value is correct for a ldaptive-granted role;
  • java.security.auth.login.config=%ACTIVEMQ_CONF%/login.config: location of the jaas config file.
These parameters can be specified in ./bin/activemq, in wrapper.conf or in /etc/default/activemq (Linux GNU/Debian).

Enable logging

This couple of lines in logback.xml can help you a lot: