Forum Discussion
Peter_Z
Cirrus
Nov 08, 2010Radius Loadbalancing with iRule
Hello,
We need to write an iRule to loadbalance the RADIUS traffic. The users are authenticating with RADIUS servers which are load balanced on the F5 LTM. The ISP is doing a NAT so that every user UDP datagram is comming with the same source IP and source UDP port.
We are thinking to write an iRule to load balance the traffic based on the username so we could distribute those RADIUS requests evenly among multiple servers. The username value is basically in the following format:
XXXXXX@YYY
where XXXX is the username - it varies in value and length for different users, YYY is a domain (i.e. company.com).
We were thinking to build the iRule which reads the username value from the beginning up to '@' sign and depending on the ending character of that username will send the traffic to specific pool member and possibly create a persistence record (uie persistence).
We found some information on the following devcentral links:
http://devcentral.f5.com/tutorials/techtips/tabid/63/articletype/articleview/articleid/187/radius-load-balancing-with-irules.aspx
http://devcentral.f5.com/tutorials/techtips/tabid/63/articletype/articleview/articleid/149/radius-aware-load-balancing-via-irules.aspx
The first article seems to be not useful based on the comments below, so we tried to build an iRule based on the latter but we were not successful. We're seeing some errors in the logs.
Could you assist us to build such an iRule? We are in hurry and have to provide a solution to customer very soon. We are running v9.4.8.
Thank you
7 Replies
- Nat_Thirasuttakorn
Employee
if you dont need persistent based on Radius username, could you just use UDP datagram LB? (enable one option in UDP profile that say something like "datagram LB")
Nat - Peter_Z
Cirrus
If the client <-> AAA server handshake contains more than 2 packets, it would probably mean that the second packet from the client can be sent to different server which we want to avoid. - Peter_Z
Cirrus
This doesn't seem to solve the issue. The traffic is sent to single server only. I've added some lines to log which server was selected and it is always the same one:
when CLIENT_DATA {
if { [UDP::payload length] > 4 } {
binary scan [UDP::payload] c@20a* hdr_code 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_
binary scan $rest_string $ff attr_value rest_string
persist uie $attr_value
set SERVER [LB::server addr]
log "Username: $attr_value Sent to member $SERVER"
break
}
default {
binary scan $rest_string $ff attr_value rest_string
}
}
}
}
}
}
And this is the log file excerpt:
Nov 10 22:55:31 local/tmm info tmm[3356]: 01220002:6: Rule RADIUS_LB_2 : Username: admin@home Sent to member 10.20.0.201
Nov 10 22:56:10 local/tmm info tmm[3356]: 01220002:6: Rule RADIUS_LB_2 : Username: root Sent to member 10.20.0.201
Nov 10 23:00:51 local/tmm info tmm[3356]: 01220002:6: Rule RADIUS_LB_2 : Username: roii Sent to member 10.20.0.201
Nov 10 23:00:57 local/tmm info tmm[3356]: 01220002:6: Rule RADIUS_LB_2 : Username: rsdsds Sent to member 10.20.0.201 - Nat_Thirasuttakorn
Employee
not sure if you have the UDP datagram LB option enabled?
you may also try changing CLIENT_DATA to CLIENT_ACCEPTED - Peter_Z
Cirrus
Yes, we have datagram LB enabled and idle timeout set to immediate under UDP profile. When I changed event in the iRule from CLIENT_DATA to CLIENT_ACCEPTED, the rule seemed to pick up no server (or at least no server appeared in the logs):
Nov 11 15:06:05 local/tmm info tmm[3377]: 01220002:6: Rule RADIUS_LB_2 : Username: abcd Sent to member
Nov 11 15:06:15 local/tmm info tmm[3377]: 01220002:6: Rule RADIUS_LB_2 : Username: abcd Sent to member
When changed back the server is logged again:
Nov 11 15:07:02 local/tmm info tmm[3377]: 01220002:6: Rule RADIUS_LB_2 : Username: abcdwee Sent to member 10.20.0.201
Nov 11 15:07:12 local/tmm info tmm[3377]: 01220002:6: Rule RADIUS_LB_2 : Username: abcdwee Sent to member 10.20.0.202 - Peter_Z
Cirrus
I'm trying to build similar iRule (starting from the switch command, rest is ommited):
switch $attr_id {
1 { if the type of attrbuite is RADIUS_ATTR_USER_NAME
binary scan $rest_string $ff attr_value rest_string
set USER_NAME [substr $attr_value 0 "@"]
log "AAA ID: $attr_value User: $USER_NAME"
persist uie $USER_NAME
if { ($USER_NAME ends_with "a") or ($USER_NAME ends_with "b") }
{
log "Username $USER_NAME ends with a|b"
pool RADIUS_POOL member 10.20.0.201
}
elseif { $USER_NAME ends_with "t"}
{
log "Username $USER_NAME ends with t"
pool RADIUS_POOL member 10.20.0.202
}
else {log "Username $USER_NAME"}
}
default { binary scan $rest_string $ff attr_value rest_string }
}
}
}
}
The problem is, that if we remove the default pool from the VS configuration, the traffic is never sent to the backend server. - Nat_Thirasuttakorn
Employee
i think when you move rule to CLIENT_ACCEPTED, it just hasn't pick server yet so log show nothing. you may try splitting those part... (move that log to client_data or lb_selected event instead. here is an example.when CLIENT_ACCEPTED { if { [UDP::payload length] > 4 } { binary scan [UDP::payload] c@20a* hdr_code 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_ binary scan $rest_string $ff attr_value rest_string persist uie $attr_value break } default { binary scan $rest_string $ff attr_value rest_string } } } } } } when CLIENT_DATA { set SERVER [LB::server addr] log "Username: $attr_value Sent to member $SERVER" }
one thing to note, if you choose timeout immediate, if src port of radius request has been changed, when server reply with radius response, LTM may not have information to transform src port back to original. (if your radius client does not care about the destination port of returning packet, you may ignore this)
I would suggest UDP datagram LB with at least a few seconds timeout (or timeout which is long enough for your server to process the packet).
Nat
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
