RADIUS update NAS-IP-Address
Problem this snippet solves:
You have a F5 device in front of a pair of Microsoft Network Policy Server (NPS) and you are load-balancing RADIUS Authentication/Accounting requests. Imagine that you want to create a specific NPS policy and NAS-IP-Address is the only RADIUS attribute that is available to catch on. But NAS-IP-Address attribute in RADIUS packet is set by the RADIUS client device. You have a simple way to use iRule to manipulate RADIUS attributes as described in F5 CloudDocs. According to F5 docs you have to use RADIUS::avp replace command to modify RADIUS attributes. This is not so easy as described. According to RFC 3579 there is a Message-Authenticator attribute which must be properly filled if used. And if you update NAS-IP-Address attribute with the new value on F5 then RADIUS server will reject this message because Message-Authenticator code will not be valid anymore
Real world example:
Cisco AnyConnect SSL VPN configuration on Cisco ASA sends Vendor-Specific attributes ASA-TunnelGroupName and ASA-ClientType to the RADIUS server. Microsoft NPS server is one of the servers that do not support policy selection based on Vendor-Specific attributes. However there is an option to create policy selection based on constant text strings from CLI (netsh), but ASA-TunnelGroupName and ASA-ClientType are not constant strings, so policy match is not possible. Special values for NAS-IP-Address attribute were selected to be used for NPS policy selection by customer
How to use this snippet:
To avoid this problem you can use this workaround:
- Attach radiusLB profile to your virtual server
- Create and attach iRule below to your virtual server
Code :
when RULE_INIT priority 500 { # RADIUS secret set static::radius_secret {supersecretcode} # RADIUS NAS-IP-Address values set static::radius_nas_old {192.0.2.1} set static::radius_nas_new {198.51.100.1} } when CLIENT_DATA priority 500 { if { [RADIUS::code] == 1 } { # Request type is Access-Request if { [IP::addr [RADIUS::avp NAS-IP-ADDRESS ip4] equals $static::radius_nas_old] } { # Request is from trusted client, update NAS-IP-Address attribute RADIUS::avp replace NAS-IP-ADDRESS $static::radius_nas_new ip4 if { [string length [RADIUS::avp 80 string]] == 16 } { # Message-Authenticator is present and need to be recalculated RADIUS::avp replace 80 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" string RADIUS::avp replace 80 [CRYPTO::sign -alg hmac-md5 -key $static::radius_secret [UDP::payload]] string } } } }
Tested this on version:
13.0