Yohoo!

Ok, I got it running. My freeradius authenticates vs. our ActiveDirectory (MS 
Win  2003 Server).

Here is a short summary, written as HowTo. It's version 0.0.1beta ;-)

_*Mini HowTo*_

*Authenticate freeradius vs. ActiveDirectory*
Nov. 2005

*Author:*
Christian Völker, c.voelker "at/@" knebb "dot/." de
Feel free to contact.

This is only a very mini and small version to help you getting the freeradius- 
server authenticating vs. ActiveDirectory.

*Disclaimer:*
I'm not responsible for anything if you follow these instructions. Do it at 
your own risk. I'm a linux specialist (RHCE, Novell CNI and CLP,...) and don't 
have much knowledge about the windows stuff. So I can't explain any of these 
things going on there ;)

*Situation:*
We want to authenticate administrators of our network-devices against our 
existing ActiveDirectory. ActiveDirectory can communicate via the 
LDAP-protocol. But the user attributes of the MS-users aber different from the 
"normal" Unix-UIDs in (Open)LDAP. So you can't easily switch between OpenLDAP 
and AD.
Additionally, there should be a failover if one of our AD servers is going down.

*Prerequisites:*
_freeradius_
Here I used 1.0.1-1.RHEL on a RedHat Enterprise Linux AS release 3, running in 
a virtual machine under VMWare (don't care, a real machine would be fine also 
;-))
_ActiveDirectory_
Of course, you will need AD running. Here, is it an MS-Windows 2003 Server.
_Linux_
I've installed it on a RedHat Enterprise Linux AS release 3 system, any other 
system would be ok also.

What we don't need is ntlm_auth, winbindd or kerberos.

*Preface:*
_PAP/CHAP..._
Alan DeKok wrote in the mailing list:
-----------mail-----------
This is done via simple LDAP bind, which AD supports.
It works for PAP authentication.  It doesn't work for CHAP, MSCHAP,
or PEAP.
-----------end mail-----------
Don't assk me for any disadvantages, my knowledge about the MS products is very 
low.
_failover_
Another statement from Alan DeKok (Dec, 15, 2004)
-----------mail-----------
> However, when I am using redundant, I cannot have this redundancy for  
> Ldap-Group lookups.  
Yes.  That's an issue.  
-----------end mail-----------
So there is no functionality for Ldap-groups with failover. Below I can show 
you a workaround from Dustin Doris.

*How-To*
_/etc/raddb/radiusd.conf_
I don't understand all of the features. All I changed were the ldap parms. So 
take a look at my /etc/raddb/radius.conf. Some explanations are commented with 
"#": I only changed parts in the ldap section. So the rest should be left as 
default.

-----------file-----------
ldap {
        # servername or ip
        # should be resolvable with dns and reverse DNS
        server = "ads2.example.com"

        # Usually AD doesn't allow anonymous requests
        # so you have to create a proxy users for the requests
        # you should enter the full DN here
        identity = "cn=proxy,ou=service,dc=example,dc=com"

        # also the password for the proxy user should be given here
        # It's cleartext, so it could be a security flaw
        password = 'password'

        # this is the basedn, where freeradius starts with it's search
        # without the "ou=" it didn't work here (don't know why!)
        basedn = "ou=all_users,dc=example,dc=com"

        # the filterparm tells radius where to look for the username
        # due of AD it's not the usual OpenLDAP, you have to 
        # use the login name of AD. It's called "sAMAaccountname"
        # if you don't trust, take a look at AD with a ldap browser
        # Our AD is very huge, the servers are very slow
        # I encoutered problems by checking the groupmembership when users
        # are member in many groups
        # so I added the AND (&) and filtered against objectClass=person
        # additionally I increased again the timeout values
        # Now everything runs fine
        filter = 
"(&(sAMAccountname=%{Stripped-User-Name:-%{User-Name}})(objectClass=person))"

        # the groupname_attribute describes, which object type the
        # groups are. In my case all groups are stored as
        # cn=...
        # I'm not sure about this, but it's working here
        groupname_attribute = "cn"

        # Also I had to check the meaning of the filters. 
        # I hadn't found any explanation of this parm
        # so I will explain my understanding of this parm
        # "|" and "&" are logical operators  for "OR" and "AND"
        # %{Ldap-UserDn} is a variable, self-explanation
        # The following statement looks only for the objectClasses group 
        # and top which I figured out in our AD setup for the groups
        groupmembership_filter = 
"(|(&(objectClass=group)(member=%{Ldap-UserDn}))(&(objectClass=top)(uniquemember=%{Ldap-UserDn})))"

        # Here freeradius becomes the info at which attribute he should
        # take a look for the group membership
        # In AD it's called "memberOf", not "LDAP-Group"
        groupmembership_attribute = memberOf

        # For debugging purposes, set it to 0xFFFF, default is 0x0000
        ldap_debug = 0xFFFF
        
        # We want to use secure transactions
        # I don't know, if we need to configure openssl for this feature
        start_tls = yes

        # default, unchanged
        dictionary_mapping = ${raddbdir}/ldap.attrmap

        # we have many users, so I increased this value
        # match it to your situation
        ldap_connections_number = 50
        
        # I had to increase the timeout about a multiple of 10
        # Our AD servers aren't very fast, but perhaps it's normal
        # If you run in problems, increase it
        timeout = 40
        timelimit = 30
        net_timeout = 10

        # Our AD is very huge, the servers are very slow
        # I encoutered problems by checking the groupmembership when users
        # are member in many groups
        # take a look at the "filter" statement
        # additionally I increased again the timeout values
        # Now everything runs fine
        # timeout = 400
        # timelimit = 300
        # net_timeout = 100
}
-----------end file-----------

_/etc/raddb/users_
Next, you have to edit the /etc/raddb/users file. Freeradius will go through 
this file to check what to do with special users or requests. 

All entries have the following syntax. 

<username>      <items to check>
        [<item to do>,]
        <item to do>

If the request from the client matches the first line, radius will do the 
following line(s). At the moment, I told freeradius to recognize the groups and 
did not configure with the right priv-level. 

My file looks like this:
-----------file-----------
DEFAULT     Ldap-Group == "Cisco_RO", NAS-Identifier =~ "^as5300"
                Auth-Type := LDAP,
                Service-Type = Login,
                Cisco-AVPair = "shell:priv-lvl=7"

DEFAULT     Ldap-Group == "Cisco_RW", NAS-IP-Address =~ "^192\.168\.21\.[0-9]+$"
                Auth-Type := LDAP,
                Service-Type = Login,
                Cisco-AVPair = "shell:priv-lvl=15"

DEFAULT         Auth-Type := Reject
                Reply-Message = "Access denied." 
-----------end file-----------

"DEFAULT" matches all users. First match counts. In my example, all users are 
checked if they are member of the group "Cisco-RO". If so, other items will not 
be checked (you have to add "PassTrough = yes"). In the above example it's not 
a good idea to put members of "Cisco_RW" also in the group "Cisco_RO". In this 
case, radius will never come to "Cisco_RW". Again, first match.

First entry only matches NAS-devices which begin with as5300, in the second 
only devices from 192.168.21.0 up to 192.168.21.9. If you need assistance in 
the regular expressions, take a look at "man grep".


_/etc/raddb/clients.conf_
-----------file-----------
client 127.0.0.1 {
        secret          = default_secret
        shortname       = localhost
}

client 192.168.0.0/16 {
        secret          = secret
        shortname       = network
 }
-----------end file-----------

All clients authenticating against freeradius need to have the (shared) secret 
as the server. You have to configure your clients.

*Test it*
Now start your freeradius server with the appropriate command and start some 
tests. Use user from your AD. Pay attention on your groups.
-----------shell-----------
radtest cv 'ADpassword' localhost 0 default_secret
Sending Access-Request of id 227 to 127.0.0.1:1812
        User-Name = "cv"
        User-Password = "ADpassword"
        NAS-IP-Address = ldaptest
        NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=227, length=51
        Service-Type = Login-User
        Cisco-AVPair = "shell:priv-lvl=15"
-----------end shell-----------


When you see the "Access-Accept", everything is fine :)

If not, you have to start your server with the "-X" parameter for debugging. 
You can change the call in the script under /etc/init.d. Perhaps it's a good 
idea to enable the ldap-debug in the radiusd.conf.

*failover*
If you need some explanation, take a look at the "configurable_failover" doc.

You have to enable two ldap modules:
        ldap ldap1 {
                server = "server1..."
                [...]
        }
        ldap ldap2 {
                server = "server2..."
                [...]
        }
instantiate {
        [...]
        ldap1
        ldap2
}
authorize {
        [...]
        #ldap
        redundant {
                ldap1 {
                        fail = 1
                        ok = return
                }
                ldap2 {
                        fail = 1
                        ok = return
                }
        }
authenticate {
        [...]
        Auth-Type LDAP {
                redundant {
                        ldap1 {
                                fail = 1
                                ok = return
                        }
                        ldap2 {
                                fail = 1
                                ok = return
                        }
                }
        }

This config runs fine, even with ldap groups as long as the second server is 
reachable. If it fails, the request will fail. So it's not that what we want. 
You have to use the following workaround:

In your users file you have to add an prefix for each ldap group like this:

DEFAULT         ldap1-Ldap-Group == "cisco-users"
                [...]

DEFAULT         ldap2-Ldap-Group == "cisco-users"
                [...]


In this case everything works fine. But you have to add two entries in the 
users.

- 
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

Reply via email to