Setup FreeRADIUS: LDAP Authentication and Authorization

Introduction to FreeRADIUS: LDAP Authentication and Authorization

In this article, we will create a scenario in which there will be two user groups who have different privileges for managing the network. When one of the users login to the router (NAS), a RADIUS request will be created and sent to the FreeRADIUS server. Then the RADIUS server will query the LDAP (Lightweight Directory Access Protocol) server if this user is existed and has the right credentials.

These are the summarized steps. I will cover the details later in this article with packet capture by Wireshark. Following shows the network topology.


Setup FreeRADIUS: LDAP Authentication and Authorization

I assume you have already installed FreeRADIUS server with the default configuration and its utility packages. If not please visit here (FreeRADIUS PART 1). Since I configured NAS for authentication and authorization before in this article (, I will not include the configuration here.


Configure FreeRADIUS for LDAP

Step-1: FreeRADIUS comes with a lot of modules and configuration files. We will not use all the files and modules. Fore sake of learning, I will use couple of them. Let’s continue with virtual server files which are stored under "/etc/freeradius/3.0/sites-enabled" directory. Two virtual servers are configured in default when you install a FreeRADIUS server. Following shows the path and the list of the servers.

root@freeradius:/home/celal# ls -l /etc/freeradius/3.0/sites-enabled/
total 0
lrwxrwxrwx 1 freerad freerad 26 Şub 16 14:36 default -> ../sites-available/default
lrwxrwxrwx 1 freerad freerad 31 Şub 16 14:36 inner-tunnel -> ../sites-available/inner-tunnel

Notice that when I list the files under the directory, it points to another directory. It is called a symbolic link. "default" and "inner-tunnel" servers are not present in "/etc/freeradius/3.0/sites-enabled" directory. Instead, they are stored in "/etc/freeradius/3.0/sites-available". It is a concept borrowed from Apache server. It will make no difference if you store them in "sites-enabled" directory or create a symbolic link to another folder. I will go for creating the server under "sites-enabled".


Step-2: Since the default servers contain a tone of configuration, I will back them up, then remove them from the folder.

root@freeradius:/home/celal# mkdir backup
root@freeradius:/home/celal# cp /etc/freeradius/3.0/sites-enabled/default  /home/celal/backup/
root@freeradius:/home/celal# cp /etc/freeradius/3.0/sites-enabled/inner-tunnel  /home/celal/backup/


Step-3: Remove the default virtual servers.

root@freeradius:/home/celal# rm /etc/freeradius/3.0/sites-enabled/default
root@freeradius:/home/celal# rm /etc/freeradius/3.0/sites-enabled/inner-tunnel


Step-4: Create a new virtual server with your preferred text editor. I will use nano.

root@freeradius:/home/celal# nano /etc/freeradius/3.0/sites-enabled/my_server

Then add the lines below.

server my_server {
listen {
        type = auth
        ipaddr = *
        port = 1812
authorize {
        if (ok || updated)  {
        update control {
        Auth-Type := ldap
authenticate {
        Auth-Type LDAP {

I will use ldap module in the the "Authorization" block to search for users and groups in the LDAP database. It is similar to "files" module which uses the local "users" file as source of the credentials. Since there is no authentication type set in the lines below "ldap" module, we need to set the "Auth-Type" in the "if" block. When a module is executed (in this case "ldap"), it returns a code. I will use that code as condition for setting the authentication type. Following shows the list of available return codes.

Module return code Description
notfound Information was not found
noop The module did nothing
ok The module succeeded
updated The module updated the request
fail The module failed
reject The module rejected the request
userlock The user was locked out


With "Authentication" module, LDAP database will be used for confirming the user’s credentials.


Step-5: FreeRADIUS runs the modules in "/etc/freeradius/3.0/mods-enabled/" directory. We need to copy ldap module to that directory. Do it as below.

root@freeradius:/home/celal# cp /etc/freeradius/3.0/mods-available/ldap /etc/freeradius/3.0/mods-enabled/

Step-6: Open ldap module with your preferred text editor an modify it as it suits you.

ldap {
   server = ''
   base_dn = 'CN=Users,DC=mydomain,DC=com'
   identity = 'CN=celal,CN=Users,DC=mydomain,DC=com'
   password = ' PassWord123'

   user {
      filter = "(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})"  


Before a client sends a ldap search request to the ldap server, it needs to bind, which is almost equivalent of authentication. Because of that, I need to define a ldap sever, a user for binding and a base_dn where to search users. Since I will use a Windows LDAP, I will specify "sAMAccountName" in the user section which is a user object attribute that holds username.


Step-7: In this step, I will define a RADIUS client with IP address and shared secret. Open "client" file.

root@freeradius:/home/celal# nano /etc/freeradius/3.0/clients.conf

And add the lines below, modifying for yourself.

client cisco_router {
   ipaddr =
   secret = celaldogan


Step-8: Run FreeRADIUS in debug mode with "freeradius -X"

Setup FreeRADIUS: LDAP Authentication and Authorization


As you see I got an error about eap module, because I deleted default virtual servers in the beginning. I do not need eap module, thus I will delete that module and launch it again.

root@freeradius:/home/celal# rm /etc/freeradius/3.0/mods-enabled/eap


Testing FreeRADIUS for LDAP Authentication and Authorization

There are two ways to test the FreeRADIUS server, with ssh loging to the router or using "radtest" tool. I prefer the second one this time.

Step-1: Apply the command below for testing.

root@freeradius:/home/celal# radtest jane PassWord123 1812 testing123
Sent Access-Request Id 240 from to length 74
        User-Name = "jane"
        User-Password = "PassWord123"
        NAS-IP-Address =
        NAS-Port = 1812
        Message-Authenticator = 0x00
        Cleartext-Password = "PassWord123"
Received Access-Accept Id 240 from to length 20

Following screenshot shows debug output from the FreeRADIUS server when it receives the request.

Setup FreeRADIUS: LDAP Authentication and Authorization

The authentication for jane is working, but notice that there is not anything related to authorization in the screenshot above. We need to add some configuration for that.


Step-2: First we need to pull the group information from the ldap server.

Open "dictionary" file and define an attribute for ldap group.

root@freeradius:/home/celal# nano /etc/freeradius/3.0/dictionary


And add "ATTRIBUTE My_Group 3000 string" line to the file as below.

Setup FreeRADIUS: LDAP Authentication and Authorization


Open ldap module.

root@freeradius:/home/celal# nano /etc/freeradius/3.0/mods-enabled/ldap


and add the line below and save the module.

control:My_Group                ='memberOf'


Step-3: Configure the virtual server to check the group information and send authorization information accordingly.

post-auth {
if (&control:My_Group =~ /Network Admin/) {
        update reply {
                Cisco-AVPair = "shell:priv-lvl=15"
if (&control:My_Group =~ /Network Operator/) {
        update reply {
                Cisco-AVPair = "shell:priv-lvl=7"

"post-auth" module is executed after a successful authentication. I am setting the privilege level based on the user’s group. I am checking the groups in the "if" condition with a regex.


Step-4: Capture the packets while testing with "radtest jane PassWord123 1812 testing123" command.

Setup FreeRADIUS: LDAP Authentication and Authorization


The debug output from FreeRADIUS is below.

Setup FreeRADIUS: LDAP Authentication and Authorization


Analyzing the packets between the FreeRADIUS and the LDAP server

Packet Number 1: Before we query the ldap server, we need to bind (authenticate).

Setup FreeRADIUS: LDAP Authentication and Authorization


We specify that we would like to use "simple binding", which carry the credentials in clear text.

Packet Number 2: It is a "bindResponse" packet, which informs that the binding has been successful.

Setup FreeRADIUS: LDAP Authentication and Authorization


Packet Number 3: It is a "searchRequest" packet. We are asking ldap server to send us the user information in the attributes. Now we only need "memberOf" attribute. The other ones are the default attributes FreeRADIUS adds.

Setup FreeRADIUS: LDAP Authentication and Authorization


Packet Number 4: The ldap server sends the user information to the radius server in this packet.

Setup FreeRADIUS: LDAP Authentication and Authorization


Packet Number 5: After gathering the user’s information, we bind (authenticate) with the user (jane) in this packet.

Setup FreeRADIUS: LDAP Authentication and Authorization


Packet Number 6: The provided credentials are verified with this packet.

Setup FreeRADIUS: LDAP Authentication and Authorization


Final thoughts

LDAP database can be used for authentication and authorization. We kept the configuration files as simple as we can for learning purpose in this article.


Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment