FreeRADIUS PAP Challenge Authentication using rlm_perl

Let's see how to configure the FreeRADIUS2.x application to respond with an Access-Challenge for incoming Access-Request messages using the rlm_perl module scripting

System Specifications:

Ubuntu 12.04 LTS (i686 i686 i386 GNU/Linux)
FreeRADIUS v2.1.10


Step 1:

Edit the “clients.conf” file in the /etc/freeradius directory and add the Client's IP details as below

client {
 secret = testing123   < -- Shared secret between Client and Radius server
 shortname = NodeToBeAuth
 netmask = 32

Step 2:

Edit the “users” file in the /etc/freeradius directory and add the users to be authenticated as below

user1 Auth-Type := Perl   < -- Use rlm_perl module for Authentication
user2 Cleartext-Password := "abc#123"  < -- Use plain text password for Authentication

Step 3:

Edit the “perl” file in the in the /etc/freeradius/modules directory and specify the script you would like to execute when the Auth Type is set to Perl as above in the users file

perl {
 module = ${confdir}/ < -- Perl script on the /etc/freeradius directory

Step 4:

Enable the rlm_perl module by editing the “inner-tunnel” and the “default” files in the /etc/freeradius/sites-available directory as follows. Add the perl module under the authenticate section so that the perl module will be included and loaded when FreeRADIUS is started

authenticate {
 Auth-Type Perl {

Script for Authentication:

Copy the example code posted on the official FreeRADIUS website and paste into a file named as in the /etc/freeradius directory

Edit the subroutine authenticate() as follows

# Function to handle authenticate
sub authenticate {
    # For debugging purposes only
    if ($RAD_REQUEST{'User-Name'} =~ /^baduser/i) {
            # Reject user and tell him why
             $RAD_REPLY{'Reply-Message'} = "Denied access by rlm_perl function";
             return RLM_MODULE_REJECT;
    } else {        < -- Any user except a bad user
            # Accept/Challenge user and set some attribute
  $RAD_REPLY{'State'} = "some state code here";
              $RAD_REPLY{'Reply-Message'} = "Enter the pin number";
  $RAD_CHECK{'Response-Packet-Type'} = "Access-Challenge"; < -- Send challenge back

The above logic can be extended for the case of a user responding to the Access-Challenge by handling the condition of verifying the user response to the challenge found in the RADIUS attributes of the response message


Start the RADIUS server in debug mode. Make sure that no freeradius daemon already running in the background before starting the server

# freeradius –X
#LD_PRELOAD=/usr/lib/ /usr/sbin/freeradius –X  < -- Ubuntu 12.04 bug

Now test plaintext password authentication for user 2 as below

# radtest user2 abc#123 0 testing123
Sending Access-Request of id 203 to port 1812
    User-Name = "user2"
    User-Password = "abc#123"
    NAS-IP-Address =
    NAS-Port = 0

rad_recv: Access-Accept packet from host port 1812, id=203, length=20

Now test challenge authentication for user 1 as below
# radtest user1 doesntmatter 0 testing123
Sending Access-Request of id 33 to port 1812
    User-Name = "user1"
    User-Password = "doesntmatter"
    NAS-IP-Address =
    NAS-Port = 0

rad_recv: Access-Challenge packet from host port 1812, id=33, length=60
    Reply-Message = "Enter pin number"
    State = 0x736f6d6520727461746524636f66652068657265

Please note that we are doing this testing using localhost ( and the NAS-IP-Address should point to the RADIUS server IP address for remote RADIUS server. Please refer to the wiki page of FreeRADIUS for configuration details of FreeRADIUS 3.x or higher



Post a Comment