Forum Discussion

scott_sams_8256's avatar
scott_sams_8256
Icon for Nimbostratus rankNimbostratus
Jan 29, 2010

radius selection based on username format

i see some iRules that parse information from Radius packets here. we currently load balance radius servers for system management access. i have a need to parse the user name based on a format and if that format does not match, direct to a different radius pool. not sure if this is real easy or real complex since i am a complete novice with iRules.

 

 

i.e. if user name format in packet starts with a_ or n_ use pool a, if not use pool b.

 

 

easy?

 

 

thanks
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    That doesn't sound too difficult. The only trick would be understanding the Radius protocol well enough to write the logic to actually find the data you want to compare. The tools are definitely there though, in iRules. Do you have an example of what the data you're trying to parse might look like?

     

     

    Colin
  • thanks Colin.

     

     

    here is what i have from an example and just inserted my info into it. does not work. i was getting ready to do a tcpdump to see if i can tell.

     

     

    when i insert my logic, it does not even log to the F5. it does prior too.

     

     

    here is what i inserted down below.

     

     

    if {[$attr_value] starts_with "n_"} then {

     

    pool radius_prod

     

    log "$attr_value"

     

    }

     

    else {

     

    pool radius_test

     

     

     

     

    when RULE_INIT {

     

    array set ::msg_types {

     

    1 "Access-Request"

     

    2 "Access-Accept"

     

    3 "Access-Reject"

     

    4 "Accounting-Request"

     

    5 "Accounting-Response"

     

    11 "Access-Challenge"

     

    12 "Status-Server"

     

    13 "Status-Client"

     

    255 "Reserved"

     

    }

     

     

    array set ::attr_types {

     

    1 "RADIUS_ATTR_USER_NAME"

     

    2 "RADIUS_ATTR_USER_PASSWORD"

     

    4 "RADIUS_ATTR_NAS_IP_ADDRESS"

     

    5 "RADIUS_ATTR_NAS_PORT"

     

    6 "Service-Type"

     

    7 "Framed-Protocol"

     

    8 "Framed-IP-Address"

     

    9 "Framed-IP-Netmask"

     

    10 "Framed-Routing"

     

    11 "Filter-Id"

     

    12 "RADIUS_ATTR_FRAMED_MTU"

     

    13 "Framed-Compression"

     

    14 "Login-IP-Host"

     

    15 "Login-Service"

     

    16 "Login-TCP-Port"

     

    24 "RADIUS_ATTR_STATE"

     

    25 "RADIUS_ATTR_CLASS"

     

    26 "RADIUS_ATTR_VENDOR_SPECIFIC"

     

    27 "RADIUS_ATTR_SESSION_TIMEOUT"

     

    28 "RADIUS_ATTR_IDLE_TIMEOUT"

     

    29 "RADIUS_ATTR_TERMINATION_ACTION"

     

    30 "RADIUS_ATTR_CALLED_STATION_ID"

     

    31 "RADIUS_ATTR_CALLING_STATION_ID"

     

    32 "RADIUS_ATTR_NAS_IDENTIFIER"

     

    40 "RADIUS_ATTR_ACCT_STATUS_TYPE"

     

    41 "RADIUS_ATTR_ACCT_DELAY_TIME"

     

    42 "RADIUS_ATTR_ACCT_INPUT_OCTETS"

     

    43 "RADIUS_ATTR_ACCT_OUTPUT_OCTETS"

     

    44 "RADIUS_ATTR_ACCT_SESSION_ID"

     

    45 "RADIUS_ATTR_ACCT_AUTHENTIC"

     

    46 "RADIUS_ATTR_ACCT_SESSION_TIME"

     

    47 "RADIUS_ATTR_ACCT_INPUT_PACKETS"

     

    48 "RADIUS_ATTR_ACCT_OUTPUT_PACKETS"

     

    49 "RADIUS_ATTR_ACCT_TERMINATE_CAUSE"

     

    50 "RADIUS_ATTR_ACCT_MULTI_SESSION_ID"

     

    51 "RADIUS_ATTR_ACCT_LINK_COUNT"

     

    52 "RADIUS_ATTR_ACCT_INPUT_GIGAWORDS"

     

    53 "RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS"

     

    55 "RADIUS_ATTR_EVENT_TIMESTAMP"

     

    61 "RADIUS_ATTR_NAS_PORT_TYPE"

     

    64 "RADIUS_ATTR_TUNNEL_TYPE"

     

    65 "RADIUS_ATTR_TUNNEL_MEDIUM_TYPE"

     

    77 "RADIUS_ATTR_CONNECT_INFO"

     

    79 "RADIUS_ATTR_EAP_MESSAGE"

     

    80 "RADIUS_ATTR_MESSAGE_AUTHENTICATOR"

     

    81 "RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID"

     

    85 "RADIUS_ATTR_ACCT_INTERIM_INTERVAL"

     

    95 "RADIUS_ATTR_NAS_IPV6_ADDRESS"

     

    }

     

    }

     

    when CLIENT_DATA {

     

    if { [UDP::payload length] > 4 } {

     

    log "UDP::payload length [UDP::payload length]"

     

    binary scan [UDP::payload] c hdr_code

     

    log "radius type $::msg_types($hdr_code)"

     

    binary scan [UDP::payload] @20a* rest_string

     

    while { [string length $rest_string] >4} {

     

    binary scan $rest_string cca* attr_id attr_length rest_string

     

    scan $attr_length %i length

     

    set ff [format "a%da*" [expr {$length} - 2]]

     

    switch $attr_id {

     

    1 { if the type of attrbuite is RADIUS_ATTR_USER_NAME

     

    binary scan $rest_string $ff attr_value rest_string

     

     

    log "attribute id: $::attr_types($attr_id); attribute length: $length; value: $attr_value"

     

    persist uie $attr_value

     

    if {[$attr_value] starts_with "n_"} then {

     

    pool radius_prod

     

    log "$attr_value"

     

    }

     

    else {

     

    pool radius_test

     

    }

     

    }

     

     

     

     

     

     

     

     

     

    4 { if the type of attrbuite is RADIUS_ATTR_NAS_IP_ADDRESS

     

    binary scan $rest_string c4a* IPtmp rest_string

     

    set IP {}

     

    foreach num $IPtmp {

     

    lappend IP [expr ($num + 0x100) % 0x100]

     

    }

     

    set attr_value [join $IP .]

     

    log "$::attr_types($attr_id) value $attr_value"

     

    }

     

    default {

     

    binary scan $rest_string $ff attr_value rest_string

     

    log "attribute id: $::attr_types($attr_id); attribute length: $length; filed value: $attr_value"

     

    }

     

    }

     

    }

     

    }

     

    }