modify NAS-Port in incoming messages
Hi colleagues, I'm trying to use Freeradius with Strongswan and have an issue with "registering" user sessions. In short, upon IPSec session reconfiguring (to be more precise - IKE_SA rekeying) Strongswan changes NAS-Port attribute and, thus, FreeRadius upon receiving of next Interim-Update with another NAS-Port value, consider it as a new session and create new entry in radutmp db, so finally I have the following (TTY is NAS-Port received from NAS): root@vpn01:/etc/freeradius/3.0# radwho Login Name What TTY When From Location doka doka shell S3 Sun 22:44 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S4 Sun 22:53 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S5 Sun 23:03 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S6 Sun 23:12 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S12 Sun 23:27 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S15 Sun 23:35 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S18 Sun 23:40 xxx.xxx.xx.xx 100.100.2.1 doka doka shell S19 Sun 23:51 xxx.xxx.xx.xx 100.100.2.1 which makes it impossible to use Simultaneous-Use. There is attribute which do not change during IKE_SA rekey - Acct-Session-Id and I'd like to use it instead of Nas-Port to identify this session, but have two issues: - the statement (added to preacct section of 'default' site): update request { NAS-Port = %{integer:%{base64:&Acct-Session-Id}} } gives an error: /etc/freeradius/3.0/sites-enabled/default[610]: Unknown or invalid value "%{integer:%{base64:&Acct-Session-Id}}" for attribute NAS-Port while if using double quotes `... = "%{integer...}"` converts the value improperly: (3) # Executing section preacct from file /etc/freeradius/3.0/sites-enabled/default (3) preacct { (3) [preprocess] = ok (3) update request { *(3) EXPAND %{integer:%{base64:&Acct-Session-Id}}* (3) --> *(3) NAS-Port = 0* (3) } # update request = noop - and nevertheless, in second case accounting records in 'details' file contains the original NAS-Port value: Mon Dec 26 00:17:19 2022 Acct-Status-Type = Interim-Update Acct-Session-Id = "1672007843-24" Class = 0x70667367726f7570 NAS-Port-Type = Virtual Service-Type = Framed-User *NAS-Port = 25* and radutmp continues to expand the list of connections with original NAS-Port value: doka doka shell *S24* Mon 00:14 xxx.xxx.xx.xx 100.100.2.1 doka doka shell *S25* Mon 00:24 xxx.xxx.xx.xx 100.100.2.1 So, there are two questions: - what is correct way to uniquely convert string to integer? - whether it's possible to mangle NAS-Port attribute to achieve what I need? Thank you! Have a nice holidays and happy next year :-) -- Volodymyr Litovka "Vision without Execution is Hallucination." -- Thomas Edison
On Dec 25, 2022, at 7:37 PM, Volodymyr Litovka via Freeradius-Users <freeradius-users@lists.freeradius.org> wrote:
I'm trying to use Freeradius with Strongswan and have an issue with "registering" user sessions. In short, upon IPSec session reconfiguring (to be more precise - IKE_SA rekeying) Strongswan changes NAS-Port attribute and, thus, FreeRadius upon receiving of next Interim-Update with another NAS-Port value, consider it as a new session and create new entry in radutmp db, so finally I have the following (TTY is NAS-Port received from NAS):
The real solution is to fix Strongswan so that it sends the same NAS-Port in all accounting packets.
which makes it impossible to use Simultaneous-Use. There is attribute which do not change during IKE_SA rekey - Acct-Session-Id and I'd like to use it instead of Nas-Port to identify this session, but have two issues:
- the statement (added to preacct section of 'default' site):
update request { NAS-Port = %{integer:%{base64:&Acct-Session-Id}} }
gives an error:
/etc/freeradius/3.0/sites-enabled/default[610]: Unknown or invalid value "%{integer:%{base64:&Acct-Session-Id}}" for attribute NAS-Port
Yes... The documentation says expansions belong in a double-quoted string. You can't just invent syntax and make it work.
while if using double quotes `... = "%{integer...}"` converts the value improperly:
Well, no. I think that the real problem is that the base64 expansion isn't doing anything useful. For reasons which don't matter here.
- and nevertheless, in second case accounting records in 'details' file contains the original NAS-Port value:
Yes. The '=' operator doesn't overwrite existing attributes. This is documented. See "man unlang".
- what is correct way to uniquely convert string to integer?
Make sure that the string is a valid integer.
- whether it's possible to mangle NAS-Port attribute to achieve what I need?
You can rewrite the NAS-Port to any value you want. But that rewrite has to make sense, and has to follow the documentation on how the server works. The problem here is that StrongSwan is sending the server garbage data, and you're trying to figure out a way to "fix" it in FreeRADIUS. While this might work sometimes, it's not really a long-term solution. The correct fix is to make StrongSwan behave properly. So the solution here is really to figure out how to get a consistent NAS-Port value for a particular session, AND a value which is different for every session. If the Acct-Session-Id value is the same across all packets for one session, then you can use that. I'd suggest this: preacct { update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}%{User-Name}" NAS-Port := %{integer:Tmp-Octets-0} } ... That should work. Alan DeKok.
Hi Alan, On 26.12.2022 15:26, Alan DeKok wrote:
You can rewrite the NAS-Port to any value you want. But that rewrite has to make sense, and has to follow the documentation on how the server works.
The problem here is that StrongSwan is sending the server garbage data, and you're trying to figure out a way to "fix" it in FreeRADIUS. While this might work sometimes, it's not really a long-term solution. The correct fix is to make StrongSwan behave properly.
Yes, of course, I will talk to Strongswan developers as well, but at the moment the fastest way is to use FreeRadius to do the job.
I'd suggest this:
preacct { update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}%{User-Name}" NAS-Port := %{integer:Tmp-Octets-0} }
...
I tried with this: update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}}" NAS-Port := "%{integer:Tmp-Octets-0}" } and received the following errors: "ERROR: Type 'octets' of length 32 cannot be converted to integer" which is correct because md5 produces 128 bits while documentation says that integer operates with 64-bit values, but this code: update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}}" Tmp-Octets-1 := "%{lpad:&Tmp-Octets-0 19}" NAS-Port := "%{integer:Tmp-Octets-1}" } does the job - it truncates md5 hash to 64-bit representation which can be converted to integer. The result is: root@vpn01:/etc/freeradius/3.0# radwho -r doka,doka,shell,S859124016,Mon 17:40,xxx.xxx.xx.xx,100.100.2.1 Thanks, Alan, for the quick help! Very appreciate! -- Volodymyr Litovka "Vision without Execution is Hallucination." -- Thomas Edison
On Dec 26, 2022, at 1:32 PM, Volodymyr Litovka via Freeradius-Users <freeradius-users@lists.freeradius.org> wrote:
I tried with this:
update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}}" NAS-Port := "%{integer:Tmp-Octets-0}" }
and received the following errors: "ERROR: Type 'octets' of length 32 cannot be converted to integer" which is correct because md5 produces 128 bits while documentation says that integer operates with 64-bit values, but this code:
The MD5 output is coming in as 22 hex characters. The "integer" expansion should grab the lowest bytes, and ignore the rest, but OK.
update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}}" Tmp-Octets-1 := "%{lpad:&Tmp-Octets-0 19}" NAS-Port := "%{integer:Tmp-Octets-1}" }
does the job - it truncates md5 hash to 64-bit representation which can be converted to integer. The result is:
root@vpn01:/etc/freeradius/3.0# radwho -r doka,doka,shell,S859124016,Mon 17:40,xxx.xxx.xx.xx,100.100.2.1
That's good. Alan DeKok.
Hi, just an addition to the thread - after adding ippool to the configuration, the same mangle with NAS-Port also required in post-auth section, to allow ippool match requests during authentication and then accounting stop events. Thank you. On 26.12.2022 19:52, Alan DeKok wrote:
On Dec 26, 2022, at 1:32 PM, Volodymyr Litovka via Freeradius-Users <freeradius-users@lists.freeradius.org> wrote:
I tried with this:
update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}}" NAS-Port := "%{integer:Tmp-Octets-0}" }
and received the following errors: "ERROR: Type 'octets' of length 32 cannot be converted to integer" which is correct because md5 produces 128 bits while documentation says that integer operates with 64-bit values, but this code: The MD5 output is coming in as 22 hex characters. The "integer" expansion should grab the lowest bytes, and ignore the rest, but OK.
update request { Tmp-Octets-0 := "%{md5:%{Acct-Session-ID}}" Tmp-Octets-1 := "%{lpad:&Tmp-Octets-0 19}" NAS-Port := "%{integer:Tmp-Octets-1}" }
does the job - it truncates md5 hash to 64-bit representation which can be converted to integer. The result is:
root@vpn01:/etc/freeradius/3.0# radwho -r doka,doka,shell,S859124016,Mon 17:40,xxx.xxx.xx.xx,100.100.2.1
That's good.
Alan DeKok.
-- Volodymyr Litovka "Vision without Execution is Hallucination." -- Thomas Edison
participants (2)
-
Alan DeKok -
Volodymyr Litovka