8.4 FreeRadius
The FreeRadius
server project (http://www.freeradius.org/) is the
implementation of the Remote
Authentication Dial-In User Service (RADIUS) protocol used by many
corporations and Internet service providers to authenticate users
connecting from remote locations. Complete coverage of FreeRadius or
RADIUS servers goes beyond the scope this chapter. RFC 2865 explains
the details of the protocol. For a more practical look at RADIUS, you
should refer to the FreeRadius web site as well as
RADIUS, by Jonathon Hassel
(O'Reilly).
The FreeRadius server daemon,
radiusd, can use an LDAP directory in two
different ways. First, it can use LDAP as a data store for RADIUS
attribute values. RADIUS attributes are defined by the RADIUS
protocol and should not be confused with LDAP attributes.[4] The only similarity between the two types of attributes
is that both have names and are used to store values. The FreeRadius
administrator defines the mapping between RADIUS attributes and the
LDAP attributes used to represent them. We'll look
at the configuration details after we have compiled a working RADIUS
server. The second option is to use the directory as an
authentication service by binding to the LDAP
server on behalf of a user. In this way, radiusd
can determine whether to accept or reject incoming connection
requests.
[4] A list of RADIUS attributes linked with the corresponding RFCs
can be found at http://www.freeradius.org/rfc/attributesl.
In the 0.8 release, the rlm_ldap module used by
radiusd to access a directory is included in a
default installation. No additional flags are required to enable LDAP
support at compile time. Running the basic configure
&& make && /bin/su -c "make install" is
enough to achieve a working radiusd in most
environments.
Without getting too bogged down in the specifics of the FreeRadius
configuration file,
radiusd.conf, it is worth explaining the general
layout. Configuration options can be described as either existing
within the scope of a section bounded by { }s or global. Global
parameters define information such as the location of directories
necessary to the general operation of radiusd or
the number of threads that the main server should spawn. Scoped
parameters can be subdivided into module settings and component
implementations.
FreeRadius modules are shared libraries defined by the
project's RLM interface. The
modules block in radiusd.conf
contains parameters specific to each library. The RLM interface
describes several different components that a module can implement.
The two components of interest to us are
authorize and
authenticate.
The authorization component is used by radiusd
to look up information about a user account. The
authorize section can contain several different
module names. Each module is queried in order for an entry matching
the login name of the user in question until a record is located or
all modules have reported failure. Part of the authorization
component's responsibility is to describe the
authentication method used to validate this account. The
authenticate section defines possible
authentication mechanisms. The method actually used for a specific
request is determined by the information returned by the
authorize section.
Here is the working configuration file for a basic server to
authenticate connections against the list of local accounts:
## radiusd.conf: FreeRADIUS server configuration file
##
## Global parameters: directory/logfile locations, etc.
##
prefix = /opt/radius
exec_prefix = ${prefix}
sysconfdir = ${prefix}/etc
localstatedir = ${prefix}/var
sbindir = ${exec_prefix}/sbin
logdir = ${localstatedir}/log/radius
raddbdir = ${sysconfdir}/raddb
radacctdir = ${logdir}/radacct
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/radiusd
log_file = ${logdir}/radius.log
libdir = ${exec_prefix}/lib
pidfile = ${run_dir}/radiusd.pid
# CLIENTS CONFIGURATION
$INCLUDE ${confdir}/clients.conf
##
## MODULE CONFIGURATION
##
modules {
## Unix /etc/passwd-style authentication
unix {
passwd = /etc/passwd
shadow = /etc/shadow
group = /etc/group
radwtmp = ${logdir}/radwtmp
}
## Local files. The user's file contains a single entry to default all
## authentication to the local system.
## DEFAULT Auth-Type := System
files {
usersfile = ${confdir}/users
acctusersfile = ${confdir}/acct_users
compat = no
}
}
##
## Authorization: obtain information about the user
##
authorize {
files
}
##
## Authentication: validate the user request
##
authenticate {
unix
}
To test your server, you must make sure that the following entry is
defined in radiusd's
clients.conf file to allow connections over the
loopback interface:
## Allow connection requests from localhost.
client 127.0.0.1 {
secret = testing123
shortname = localhost
nastype = other
}
You can test your configuration by starting
radiusd in debug mode. This will produce a large
amount of log information printed to standard output.
root# radiusd -X -A
< . . . preceding output omitted . . . >
Ready to process requests.
Using radtest(1), you can verify that the local user
guest1 with password test1
can be successfully authenticated:
$ radtest guest1 test1 localhost 0 testing123
Sending Access-Request of id 50 to 127.0.0.1:1812
User-Name = "guest1"
User-Password = "\263\033\037\2760@3\022X\327\334\343\025\265\347}"
NAS-IP-Address = garion
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=50, length=20
Now that you have a working RADIUS configuration, it is time to move
on and integrate the new server with your directory.
8.4.1 FreeRadius and OpenLDAP
If you want the RADIUS server to utilize
the directory for authentication only, no schema modifications to
your existing LDAP server are necessary. You can
simply use the posixAccount entry for a user, as
you did with the ProFTPD server.
The first step is to define the parameters for the rlm_ldap module
instance. All of the parameters shown here should be intuitive. The
module will perform an anonymous bind to our
LDAP server and search for a
posixAccount entry whose uid
attribute matches the username of the connecting user. Once this
entry is found, the library will attempt to bind to the directory as
the user to verify the user's credentials. All of
the communication takes place after the StartTLS command has been
executed to ensure privacy.
ldap {
server = "ldap.plainjoe.org"
port = "389"
basedn = "ou=people,dc=plainjoe,dc=org"
filter = "(&(objectclass=posixAccount)(uid=%{Stripped-User-Name:-%{User-Name}}))"
start_tls = yes
}There are many more parameters that can be defined for the rlm_ldap
module. A complete list is given, along with descriptions, in Table 8-4.
The next step required to put this new module instance into play is
adding a definition to the authenticate section
that can be used as a value for the Auth-Type
attribute in the users file:
authenticate {
authtype LDAP {
ldap
}
}Now you can change the authentication default in
raddb/users to LDAP:
## raddb/users file defined by the files authorize component
##
## Authenticate all users by binding to the LDAP directory.
DEFAULT Auth-Type := LDAP
After restarting radiusd (again in debug mode),
test the new configuration using a preexisting LDAP user entry
(uid=kristi and
userPassword=testpass):
$ ./radtest kristi testpass localhost 0 testing123
Sending Access-Request of id 147 to 127.0.0.1:1812
User-Name = "kristi"
User-Password = "1q\325\026\020\315p\214X\310\227\376\014]F\332"
NAS-IP-Address = garion
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=147, length=20
From the client's point of view, nothing appears to
be different. The server, however, yields much more information. You
should be able to locate a line where the module binds to the
directory on behalf of the user.
auth: type "LDAP"
modcall: entering group authtype
< . . . reminaing output omitted . . . >
rlm_ldap: bind as uid=kristi,ou=people,dc=plainjoe,dc=org/test to
ldap.plainjoe.org:389
rlm_ldap: waiting for bind result ...
rlm_ldap: user kristi authenticated successfully
modcall[authenticate]: module "ldap" returns ok
This is definitely the least intrusive way to integrate
FreeRadius with an existing
directory and will work with any LDAPv3 server. The next step is to
use your directory as a data store for the information currently
stored in FreeRadius's users
file. This, however, will require that you learn about some new
schema items.
The FreeRadius project provides an LDAP schema file for use with
OpenLDAP 2.x servers. The
RADIUS-LDAPv3.schema file can be found in the
doc/ directory of the FreeRadius source code
distribution. The schema defines many new attributes used to store
RADIUS attribute values and a single structural object class named
radiusprofile, shown in Figure 8-5, which is used to represent RADIUS users. To
keep our focus on LDAP and not RADIUS, we will only concern ourselves
with how radiusAuthType maps the
Auth-Type RADIUS attribute. Descriptions of the
other attributes can be found in the RADIUS RFC.
Figure 8-5. The radiusprofile object class used by the FreeRadius server

First, copy the new schema file to
/usr/local/etc/openldap/schema/:
root# cp RADIUS-LDAPv3.schema /usr/local/etc/openldap/schema/
Next, you must include a reference to this file in
slapd.conf. Because a
radiusprofile object includes the
lmPassword and ntPassword
attributes from the samba.schema file, it must
be placed after the latter file has been parsed:
## /usr/local/etc/openldap/slapd.conf
## core.schema is required for all servers.
include /usr/local/etc/openldap/schema/core.schema
## Included from Chapter 6
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/nis.schema
## Included from Chapter 7
include /usr/local/etc/openldap/schema/inetorgperson.schema
## Dependencies for samba.schema: cosine.schema and inetorgperson.schema needed to
## support --with-ldapsam in Samba
include /usr/local/etc/openldap/schema/samba.schema
## Support for FreeRadius depends on samba.schema for LM/NT password attributes.
include /usr/local/etc/openldap/schema/RADIUS-LDAPv3.schema
The mapping between
LDAP attributes and RADIUS
attributes is stored in a text file named
ldap.attrmap by default. Conventionally, this
file is stored in the raddb/ directory, but both
the name and location are configurable via the rlm_ldap
module's dictionary_mapping
parameter. Because we will be using the default schema file, the
corresponding attribute dictionary is sufficient. If you decide to
use a custom schema, you may have to modify the dictionary as well.
Your next hurdle is decide where to store the
radiusprofile entries in the
directory. Your first choice might be to store them with the other
user account information below the people
ou. The problem is that you cannot add the
radiusprofile object to your existing
users' accounts. You can either change the
radiusprofile definition to an auxiliary object or
choose to store objects of this type somewhere else. Following the
trend of using provided schemas whenever possible, we will create a
new organizational unit to hold FreeRadius users and establish a link
between the posixAccount and the
radiusprofile objects.
First, create a new ou=radius entry below the
services ou (created in Chapter 7 for Sendmail):
dn: ou=radius,ou=services,dc=plainjoe,dc=org
objectclass: organizationalUnit
ou: radius
Next, create a profile for the user kristi. The
difficulty with this is choosing the RDN for the entry. You have
already chosen the uid attribute as the unique
naming convention for entries below ou=people.
However, the radiusprofile object includes only
the cn attribute. The informational RFC 2377
defines an auxiliary uidObject class for
situations such as this one. This allows you to include the
uid attribute as the RDN for new entries
regardless of the structural object class and still maintain your
internal naming conventions. You could just use an
extensibleObject, but the
uidObject is a cleaner approach. Here is the
resulting RADIUS user entry:
dn: uid=kristi,ou=radius,ou=services,dc=plainjoe,dc=org
objectclass: radiusprofile
objectclass: uidObject
uid: kristi
cn: Kristi Carter
radiusAuthType: LDAP
Finally, link the posixAccount entry for
kristi to her RADIUS information by storing the
DN of the radiusprofile object in
uid=kristi,ou=people,dc=plainjoe,dc=org. This time
we will use the extensibleObject to add the extra
attribute. To make the new attributes easier to see, most of the
existing optional attributes have been omitted from this LDIF
excerpt. Added attributes are shown in bold.
## Existing optional attributes have been omitted from the display.
dn: uid=kristi,ou=people,dc=plainjoe,dc=org
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: sambaAccount
objectclass: extensibleObject
cn: Kristi Carter
cn: Kristi W. Carter
sn: Carter
loginShell: /bin/bash
uidNumber: 781
gidNumber: 100
homeDirectory: /home/kristi
uid: kristi
rid: 2570
radiusprofileDN: uid=kristi,ou=radius,ou=services,dc=plainjoe,dc=org
The two module configuration changes to be made are changing the
locations of the dictionary file for LDAP/RADIUS attributes
(dictionary_mapping) and specifying the LDAP
attribute containing the DN of the user's RADIUS
information (profile_attribute):
ldap {
server = "ldap.plainjoe.org"
port = "389"
basedn = "ou=people,dc=plainjoe,dc=org"
filter = "(&(objectclass=posixAccount)(uid=%{Stripped-User-Name:-%{User-Name}}))"
start_tls = yes
profile_attribute = "radiusProfileDn"
dictionary_mapping = ${raddbdir}/ldap.attrmap
}You can now remove the local copy of the users
file from the RADIUS server and add the ldap module to the authorize
block in radiusd.conf. The files module is still
listed because it also contains directives affecting local accounting
policies.
##
## Authorization: obtain information about the user
##
authorize {
files
ldap
}
This example brings up two important points:
Relationships between entries in a directory can be represented by
storing the DNs as reference links.
Using auxiliary objects such as the uidObject to
maintain a standard naming convention can help reduce the management
costs associated with locating related entries.
I'll leave it up to you to use the
radtest tool to verify that the server is
working correctly.
•
Table of Contents
•
Index
•
Reviews
•
Reader Reviews
•
Errata
LDAP System Administration
By
Gerald Carter
Publisher
: O''''Reilly
Pub Date
: March 2003
ISBN
: 1-56592-491-6
Pages
: 308
If you want to be a master of your domain, LDAP
System Administration will help you get up and
running quickly regardless of which LDAP version you use.
After reading this book, even with no previous LDAP
experience, you''''ll be able to integrate a directory server
into essential network services such as mail, DNS, HTTP, and
SMB/CIFS.