For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Radius Accounting Interim Update

Problem this snippet solves:

This iRule generates a Radius Accounting logging event with the status-type of Interim-Update when a user establishes a VPN Tunnel with APM.

How to use this snippet:

Apply this iRule to the HTTPS virtual that has the APM Profile applied to it that you want to generate Radius Accounting events for.

Code :

######################################################################
    ##
    ## See the RFC page for additional information on Accounting-Request
    ## http://tools.ietf.org/html/rfc2866#section-4
    ##
    ######################################################################

    when HTTP_REQUEST {
        ## Check to see if the user is currently authenticated
        ## If the HTTP path starts with /isession than most of the time 
        ## the user is trying to initiate a Network Access tunnel
        if { [ACCESS::policy result] eq "allow" && [HTTP::path] eq "/isession"} {

            ## Wait a little bit so the variable can be populated
            after 1000 -periodic {
                ## If the variable was populated than generate the Radius message
                if {[ACCESS::session data get session.assigned.clientip] ne ""}{
                    after cancel -current
                
                    ## Since the iRule doesn't have access to the AAA radius section
                    ## the variables need to be populated with the correct information
                    set __secret"123"
                    set __destination"1.1.1.1"
                    set __port"1813"
                
                    ##
                    set __code[format %02x 4]
                    set __id[format %02x [expr { int(255 * rand()) }]]
                
                    ## Accounting Session ID
                    set NA_SessionID[ACCESS::session data get session.user.sessionid]
                    binary scan $NA_SessionID H* __sid
                    set __asiLENGTH[expr {[string length $__sid] /2 + 2}]
                    set __asi[format %02x 44][format %02x $__asiLENGTH]$__sid
                
                    ## Accounting Status Type
                    set __ast[format %02x 40][format %02x 6][format %08x 3]
                
                    ## Accounting Authentication
                    set __aa[format %02x 45][format %02x 6][format %08x 1]
                
                    ## Service Type
                    set __st[format %02x 06][format %02x 6][format %08x 8]
                
                    ## NAS Port
                    set __np[format %02x 05][format %02x 6][format %08x 0]
                
                    ## Tunnel Client Endpoint
                    binary scan [IP::client_addr] H* __cip
                    set __tceLENGTH[expr {[string length $__cip] /2 + 2}]
                    set __tce[format %02x 66][format %02x $__tceLENGTH]$__cip
                
                    ## User-Name
                    set NA_UserName[ACCESS::session data get session.logon.last.username]
                    binary scan $NA_UserName H* __username
                    set __unLENGTH[expr {[string length $__username] /2 + 2}]
                    set __un[format %02x 1][format %02x $__unLENGTH]$__username
                
                    ## Framed-IP-Address
                    set NA_ClientIP[ACCESS::session data get session.assigned.clientip]
                    scan $NA_ClientIP %d.%d.%d.%d t__ip1 t__ip2 t__ip3 t__ip4
                    set __vpn[format %02x $t__ip1][format %02x $t__ip2][format %02x $t__ip3][format %02x $t__ip4]
                
                    set __fiaLENGTH[expr {[string length $__vpn] /2 + 2}]
                    set __fia[format %02x 8][format %02x $__fiaLENGTH]$__vpn
                
                    ## Combine the attributes above into a single string
                    set __attributes${__asi}${__ast}${__aa}${__st}${__np}${__tce}${__un}${__fia}
                
                    ## Calculate the lenght of the attribute string and then device by 2 to get octet count
                    set __attributesL[expr {[string length  $__attributes]/2}]
                
                    ## Combine the attributes length with the radius header length
                    set __length[expr {$__attributesL + 20}]
                
                    ## The length value needs to be stored in HEX when the MD5 attribute is calculated
                    set __length_HEX[format %04x $__length]
                
                    ## The Request Authenticator field contatins 16 zero octets
                    set __zero [format %032x 0]
                
                    ## Generate the Request Authenticator value
                    set __md5_auth [md5 [binary format H* ${__code}${__id}${__length_HEX}${__zero}${__attributes}]${__secret}]
                
                    ## Convert the MD5 value into binary
                    binary scan $__md5_auth H* __auth
                
                    ## Populate the Radius Information
                    set __radiusPayload[binary format cH2SH32H* $__code $__id $__length $__auth $__attributes] 
                
                    ## Create the sideband connection and send the data
                    set sb_conn[connect -protocol UDP -timeout 100 -idle 30 -status conn_status $__destination:$__port]
                    set sb_send[send -timeout 100 -status send_status $sb_conn $__radiusPayload]
                    set sb_recv [recv -peek -status peek_status -timeout 1000 $sb_conn]
                
                    ## After the data is sent close the connection
                    close $sb_conn
                }
            }
        }
    }
Published Oct 06, 2015
Version 1.0
No CommentsBe the first to comment