RADIUS authentication using iRulesLX

Problem this snippet solves:

This snippet allows you to authenticate the user via RADIUS auth. It is an iRules procedure that calls an iRulesLX script. The benefit of this as opposed to AAA::auth_send is that you can send user attributes from the RADIUS server and use them in your iRule eg Session-Timeout

Add it as an iRules LX workspace and plugin and then add the iRule to the virtual server. Change the iRule to suit your own needs. Uses an Internal Virtual Server to communicate to the RADIUS server.

How to use this snippet:

Call the procedure with

call /Common/radius-auth/radius-auth::radius-auth <IVS name> <Attribute String>
. Attribute String is URL-encoded eg a=1&b=2 and must contain
secret
,
User-Name
and
User-Password
. You may find that your RADIUS server requires NAS-IP-Address and NAS-Port as well.

response
is a list of the RADIUS code and the returned attributes in URL-encoded format. Use URI::query to extract these attributes.

Example:

set attrString "secret=${static::secret}&User-Name=${USERNAME}&User-Password=${PASSWORD}&NAS-IP-Address=${static::NAS_IP_Address}&NAS-Port=[TCP::client_port]"
set response [ call /Common/radius-auth/radius-auth::radius-auth $static::authVsName $attrString ]

Instructions

  • Download the file from this page, unzip and upload radius-auth.tgz to /var/tmp on the BIG-IP
  • Create the workspace

    tmsh create ilx workspace radius-auth from-archive /var/tmp/radius-auth.tgz
  • Create the plugin

    tmsh create ilx plugin radius-auth from-workspace radius-auth
  • Add the iRule

    when RULE_INIT {
        # Set the name of the IVS
        set static::authVsName "RADIUS_IVS"
        # Set the name of the login page
        set static::loginPage "/myPath/myForm"
        # Set the maximum payload to collect. Default is 1024
        set static::maxPayload 1024
        ####### RADIUS Attributes ##########
        set static::NAS_IP_Address "10.20.30.40"
        set static::secret "abcd1234"
    }
    
    when HTTP_REQUEST {
        if { ([HTTP::method] == "POST") && ([HTTP::path] == $static::loginPage) } {
            if { [HTTP::header Content-Length] != "" || [HTTP::header Content-Length] > $static::maxPayload } {
                HTTP::collect $static::maxPayload
            }
        }
    }
    when HTTP_REQUEST_DATA {
        set USERNAME [findstr [HTTP::payload] "username=" 9 "&"]
        set PASSWORD [findstr [HTTP::payload] "password=" 9 "&"]
        set attrString "secret=${static::secret}&User-Name=${USERNAME}&User-Password=${PASSWORD}&NAS-IP-Address=${static::NAS_IP_Address}&NAS-Port=[TCP::client_port]"
        set response [ call /Common/radius-auth/radius-auth::radius-auth $static::authVsName $attrString ]
        log local0. "Response: $response"
        if { [lindex $response 0] == 2 } {}
            log local0. "User $USERNAME authenticated"
            log local0. "Session-Timeout: [ URI::query "?[lindex $response 1]" Session-Timeout ]"
            return
        } else {
            log local0. "User $USERNAME NOT authenticated"
            drop
        }
    }
    

Code :

90622
Updated Jun 06, 2023
Version 2.0

Was this article helpful?

No CommentsBe the first to comment