debugging Active Directory LDAP authentication in Redmine

What else does a geek do on Christmas eve? How about some ruby on rails debugging, especially when I don’t really know anything other than the basics of Ruby on Rails. :-)

So here’s what I’ve done and what I’ve learned, for the great search engine in the sky and the next time I find myself in this pickle.

I’ve installed Redmine on a CentOS box, which worked out really well. I cribbed the install notes from http://blog.itsmine.co.uk/2009/01/22/howto-install-subversion-and-redmine-on-centos5-rhel5/, which is a fantastic walk-through to the process.

So first is getting authentication working with Redmine. It includes a nice LDAPS:// based built-in mechanism, but there’s little detail around configuring it. The best is the wiki page RedmineLDAP on the Redmine wiki. If you’re doing LDAP authentication, you probably want LDAPS – otherwise you’re shipping passwords in clear over the wire. The default port of LDAPS on Active Directory is 636.

The other key thing you need to know is that even though you configure an LDAP connection in the redmine application (under http://YourRedmineHost/auth_sources/list), when you test it – it’ll test positive even if it isn’t binding into Active Directory and returning a result. Why? Now that another story – and one I don’t have clearly nailed.

To start, I enabled debugging in Redmine by editing /var/www/rails/redmine/config/environments/production.rb and inserting the line:

1
config.log_level = :debug

(the default, if you’re curious, is config.log_level = :info)

Restarted the service and now I’m getting a lot more detail. Turns out the LDAP authentication pieces really only trigger useful logging if the search mechanism that looks for the ID is successful. I found the ruby code doing the lifting at redmine/app/models/auth_source_ldap.rb – and starting adding in additional debugging methods. What I found was that the system wasn’t throwing any exceptions, but the result of a call to ldap_con.search() wasn’t returning any values.

What I haven’t been able to solve is why that search wasn’t returning any values.

Since I’m not super conversant on hacking on ruby (yet – I think I’m about to learn the hard way), I switched to a different tactic to see what was happening: tcpdump.

The command line to watch the LDAP protocol stream in plain-text as it flows is:

1
tcpdump -l -s 1024 -A -vv port 389

(you’ll need to run that as root, and turn of LDAPS so you can actually see the darned protocol). Wireshark would be a hell of a lot easier, but I’m doing this on a remote RHEL server and didn’t have a GUI to wrap into the darn thing. What I saw from that was a string embedded in the protocol noise:

LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece.

Why this wasn’t propagating an exception or error in Rails is not clear to me (which is why I think I’m about to learn more rails hacking, the hard way). I’ve tweaked things around to get different exceptions, but what it all amounts to is that I’m not yet getting a good/successful bind on LDAP from which I can do searches.

I’ve managed to get LDAP authentication working from python (and Django) within my environment, so I’m familiar with the proper base DN and some of the attributes that are available for use from our Active Directory – but so far, no love in the ruby world.

When you’re configuring the LDAP, the code is written so that Redmine has to have an account and password that will bind with LDAPS properly and be able to return search results. If you’re doing this against active directory, make sure you include the domain in the account you’re binding (i.e. YOURDOMAIN\youraccount). That made the difference in getting a successful bind to LDAP. Using the correct domain is what got me past the bind issue. The fact that it wasn’t successfully binding and not propogating an error seems like a bug – that’s been logged today as issue 4483

(by the way – the time when I want more screen real estate is when I have 5 terminal consoles and two different web browsers open debugging something like the redmine application)

More later… still debugging, but now I’m diving into using ruby script/console to interactively figure out this LDAP code in ruby.

UPDATE: So the final solution was all about having the right configuration entries in the fields to make it work. I ended up using ruby script/console to manually drive values until I had a success, and then the results were really clear as to what I needed to use.

For anyone else coming along and trying to same thing, here’s what worked for me (minus my password…) to learn what attributes were being passed back from LDAP:

1
ruby script/console
1
2
3
4
5
6
7
8
require 'net/ldap'
options = { :host => 'my.adhost.com', :port => 389, :encryption => nil, :method => :simple, :username => 'DOMAIN\jheck', :password => 'mypassword' }
ldap_conn = Net::LDAP.new options
ldap_conn.open { }
ldap_conn.auth('DOMAIN\jheck','mypassword')
ldap_conn.bind
filter = Net::LDAP::Filter.eq('sAMAccountName','jheck')
ldap_conn.search(:base => 'DC=MYDOMAIN1,DC=MYDOMAIN2', :filter => filter)

A related update/patch submitted to Redmine a few months ago is issue 4283 which solves a quandry I have about needing a separate account to authenticate through LDAP. I’ll be trying out that patch next monday.

This entry was posted in Geekstuff, rails. Bookmark the permalink.

One Response to debugging Active Directory LDAP authentication in Redmine

  1. Giovanisp says:

    Man, thank you so much for this walk-through. I was going mad about my LDAP setup! By using tcpdump I was able to track the issues and fix the LDAP parameters… works like a charm :-)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">