I'm trying to design an environment that does not allow anonymous binds, and the users that require authentication reside across multiple OU's. It seems common practice among authentication modules to take a cn, bind anonymously to scan for the full dn, and then check password with full dn to authenticate. What I'd like to avoid is the anonymous bind, or storing a name and password with read access to bind, to increase security.
I think what would be ideal is to somehow map all objects across multiple ou's to a single ou. Something along the lines of : all objects in ou=Department1,dc=example,dc=com + ou=Department2,dc=example,dc=com + ou=Department3,dc=example,dc=com to be linked to ou=Everyone,dc=example,dc=com. If something like that were in place, new users created in Department3 could be authenticated with cn=username,ou=Everyone,dc=example,dc=com. All modules designed to check authentication would not need to bind first to search the directory for the full dn.
I've seen references to aliasing, but that applies only to a single object, and also mentions of mapping, but I can't tell if that would do what I expect it to do.
Has anyone else built something similar? Can what I explain even be done with OpenLDAP? What should I be looking in to for direction on setting this up?
Thanks in advance -Joe Comeaux
On 31/01/11 10:35 -0600, Joe Comeaux wrote:
I'm trying to design an environment that does not allow anonymous binds, and the users that require authentication reside across multiple OU's. It seems common practice among authentication modules to take a cn, bind anonymously to scan for the full dn, and then check password with full dn to authenticate. What I'd like to avoid is the anonymous bind, or storing a name and password with read access to bind, to increase security.
It depends on the software doing the authentication. Could you elaborate on what your environment might look like?:
Will there be client software which performs the LDAP authentication directly to the LDAP server?
Are you developing that software, or will you be using existing software?
Can you support SASL binds in your environment?
In some parts of our network (like with FreeRADIUS), we don't have any other good option other than to stick a DN and password into its LDAP configuration.
In the parts of our network that allow us to perform SASL authentication, such as postfix/cyrus/php that link against cyrus sasl, we use Kerberos authentication (or EXTERNAL over ldapi:///), along with the ldapdb auxprop plugin, which does not require storing passwords in config files.
For 'unifying' your different OUs, you could specify a 'sub' scope which encompasses all your OUs. For example, if you were configuring a authz-regexp, you could do:
authz-regexp "uid=([^,]+),cn=([^,]+),cn=auth" ldap:///dc=example,dc=com??sub?(uid=$1)
Thanks for the direction. It seems as though authz-regexp might be exactly what I'm looking for.
On Mon, Jan 31, 2011 at 2:19 PM, Dan White wrote:
It depends on the software doing the authentication. Could you elaborate on what your environment might look like?:
Environment consists of linux apps, OpenVPN, Postfix/Courier, PAM ( for SSH ), and a custom PHP application.
Will there be client software which performs the LDAP authentication directly to the LDAP server? Can you support SASL binds in your environment?
I was under the impression that most all the software would be attempting to authenticate directly with the LDAP server ( my understanding of SASL may be a bit unclear ). I'm pretty sure the linux apps listed above can use SASL. I will need to research SASL connections a bit more before deciding if that's what I need or not.
Are you developing that software, or will you be using existing software?
Existing software, PHP and OpenVPN have pre built libraries for authenticating LDAP, etc.
In the parts of our network that allow us to perform SASL authentication, such as postfix/cyrus/php that link against cyrus sasl, we use Kerberos authentication (or EXTERNAL over ldapi:///), along with the ldapdb auxprop plugin, which does not require storing passwords in config files.
This sounds like what I need, will research this.
For 'unifying' your different OUs, you could specify a 'sub' scope which encompasses all your OUs. For example, if you were configuring a authz-regexp, you could do:
authz-regexp "uid=([^,]+),cn=([^,]+),cn=auth" ldap:///dc=example,dc=com??sub?(uid=$1)
This also sounds like what I need, will research this.
Thanks again -Joe
On Mon, Jan 31, 2011 at 04:04:15PM -0600, Joe Comeaux wrote:
Will there be client software which performs the LDAP authentication directly to the LDAP server? Can you support SASL binds in your environment?
I was under the impression that most all the software would be attempting to authenticate directly with the LDAP server ( my understanding of SASL may be a bit unclear ). I'm pretty sure the linux apps listed above can use SASL. I will need to research SASL connections a bit more before deciding if that's what I need or not.
You might be able to get some ideas from here: http://mailman.mit.edu/pipermail/kerberos/2011-January/016989.html
You should bear in mind that ultimately you're going to have some sort of "password" stored in a file somewhere on the client machine - whether it be a Kerberos keytab, or the private key for a TLS certificate, or something else. Anyone who has root on the client box will be able to use those credentials.
(Or, if you don't store it in the filesystem, you'll have to prompt the user to type it in every time the system starts up)
When you realise this, perhaps a fixed bindDN+password doesn't seem so bad after all. You only need to grant it just enough access to do searches to map username to DN, after all.
The big advantage of Kerberising is that the LDAP traffic is encrypted, and hence protected against both sniffing and tampering, without needing to deploy TLS and certificates.
Regards,
Brian.
On 01/02/11 12:40 +0000, Brian Candler wrote:
You might be able to get some ideas from here: http://mailman.mit.edu/pipermail/kerberos/2011-January/016989.html
You should bear in mind that ultimately you're going to have some sort of "password" stored in a file somewhere on the client machine - whether it be a Kerberos keytab, or the private key for a TLS certificate, or something else. Anyone who has root on the client box will be able to use those credentials.
Yes, but you can protect the keytab file from the service making the LDAP client connection, so that a particular service getting compromised does not obtain access to the keytab file.
If a service were to be compromised then the attacker would have access to the server for the remainder of the life of the kerberos tgt only.
We do the following in root's crontab for all of our services running on remote servers (heimdal-kcm might be another option):
0 */1 * * * ( KRB5CCNAME=FILE:/tmp/krb5cc_33 kinit --keytab=/etc/krb5.keytab-HTTP HTTP/lokai.example.net ; chown www-data:www-data /tmp/krb5cc_33 )
And for services running on the same system, EXTERNAL over ldapi is ideal.
You might be able to get some ideas from here: http://mailman.mit.edu/pipermail/kerberos/2011-January/016989.html You should bear in mind that ultimately you're going to have some sort of "password" stored in a file somewhere on the client machine - whether it be a Kerberos keytab, or the private key for a TLS certificate, or something else. Anyone who has root on the client box will be able to use those credentials. (Or, if you don't store it in the filesystem, you'll have to prompt the user to type it in every time the system starts up)
When you realise this, perhaps a fixed bindDN+password doesn't seem so bad after all. You only need to grant it just enough access to do searches to map username to DN, after all.
I think I may end up just storing a name+password on workstations that need any kind of search access to the directory. But if I can get authz-regexp working I may not need to store passwords on anything.
I'm having a lot of trouble just getting just a basic regexp example working though. I dont have any kind of slapd.conf set up, so I'm injecting the updates through ldapmodify. Here's what I've tried : #ldapmodify -Y EXTERNAL -H ldapi:/// SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 dn: cn=config add: olcAuthzRegexp olcAuthzRegexp: uid=jrambo,ou=users,dc=example,dc=com uid=jrambo,ou=it,ou=users,dc=example,dc=com
modifying entry "cn=config"
#ldapsearch -x -H "ldap://voss.worleyco.com/" -b "dc=worleyco,dc=com" -D "uid=jrambo,ou=Users,dc=example,dc=com" -W Enter LDAP Password: ldap_bind: Invalid credentials (49)
I'm assuming that with the above instruction, requests to bind with uid=jrambo,ou=users,dc=example,dc=com should translate to uid=jrambo,ou=it,ou=users,dc=example,dc=com, but it doesnt appear to be working for me. Am I missing something simple? I've restarted slapd, verify that the object exists, credentials are valid, etc.
# rambo, IT, Users, example.com dn: uid=jrambo,ou=IT,ou=Users,dc=example,dc=com uid: jrambo objectClass: account objectClass: posixAccount cn: jrambo loginShell: /bin/bash homeDirectory: /home/jrambo uidNumber: 10000 gidNumber: 548
-Joe
On 01/02/11 10:28 -0600, Joe Comeaux wrote:
I'm having a lot of trouble just getting just a basic regexp example working though. I dont have any kind of slapd.conf set up, so I'm injecting the updates through ldapmodify. Here's what I've tried : #ldapmodify -Y EXTERNAL -H ldapi:/// SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 dn: cn=config add: olcAuthzRegexp olcAuthzRegexp: uid=jrambo,ou=users,dc=example,dc=com uid=jrambo,ou=it,ou=users,dc=example,dc=com
modifying entry "cn=config"
#ldapsearch -x -H "ldap://voss.worleyco.com/" -b "dc=worleyco,dc=com" -D "uid=jrambo,ou=Users,dc=example,dc=com" -W Enter LDAP Password: ldap_bind: Invalid credentials (49)
As far as I know, authz-regexp mappings only apply to SASL binds, and in a special case in the nssov backend pam processing.
There was some discussion of using it with simple binds here:
http://www.openldap.org/lists/openldap-software/200507/msg00027.html
Given a mapping of
uid=jrambo,cn=([^,]+),cn=auth uid=jrambo,ou=it,ou=users,dc=example,dc=com
or
uid=([^,]+),cn=([^,]+),cn=auth uid=$1,ou=it,ou=users,dc=example,dc=com
or the rule I showed in my earlier email... you should then be able to do:
ldapwhoami -H "ldap://voss.worleyco.com/" -U jrambo
to see if your mapping is working correctly.
You'll want to have a SASL mechanism installed with some level of security (such as DIGEST-MD5).
You may also be able to do:
ldapwhoami -Y EXTERNAL -H ldapi:/// -X u:jrambo
to test your mappings.
On Tue, Feb 01, 2011 at 10:23:21AM -0600, Dan White wrote:
You should bear in mind that ultimately you're going to have some sort of "password" stored in a file somewhere on the client machine - whether it be a Kerberos keytab, or the private key for a TLS certificate, or something else. Anyone who has root on the client box will be able to use those credentials.
Yes, but you can protect the keytab file from the service making the LDAP client connection, so that a particular service getting compromised does not obtain access to the keytab file.
If a service were to be compromised then the attacker would have access to the server for the remainder of the life of the kerberos tgt only.
That's true. They may only get 10 hours to complete their attack - if they take the credentials away. If they stay on the machine then they'll get the refreshed ones.
And for services running on the same system, EXTERNAL over ldapi is ideal.
In that case you're using the Unix uid/gid to authenticate the user - so anyone who breaks into the service will automatically get the same rights as that service, for as long as they're still on the system.
But I agree that having a single BindDN/Password and sharing it between all machines is a bad idea, because they can be re-used from elsewhere on the network, and it's hard to recover from a compromise.
With Kerberos, you've already got a distinct host key per machine, so you might as well leverage it.
Regards,
Brian.
openldap-technical@openldap.org