Weird behaviour of sqlcounter / dailycounter
Hi all, tonight I've seen some weird behaviour during tests of sqlcounter module. Please see the output below. The situation is that the station trying to connect is allowed a Max- Daily-Session of 300 seconds. The counter is at 299, so sqlcounter correctly sets Session-Timeout = 1, and the station is allowed access for one second remaining... However, this connection is terminated immediately by the Wifi AP (running hostapd 2.due to Session-Timeout = 1. The counter never gets increased, the station retries and is allowed access, and every 5 seconds or so this repeats and repeats and repeats... The logs get flooded and there's useless load on the AP and freeradius. The station (Linux machine with NetworkManager) stopped trying to connect after half an hour or so... This behaviour is reproduceable. Every time the station's Max-Daily- Session value is reached and it get's kicked off by the AP, it get's into this loop. The number of retries until the station finally is giving up is significantly higher if more than one AP with the same SSID is reachable (>30 minutes). This behaviour also occurs if the "counter" module is used rather than the "sqlcounter" module. Freeradius version is 3.0.21, hostapd version is 2.10-8. Did I configure something wrong, or what happens here? Thank you for help! Robert freeradius -X output: <...> (3090) dailycounter: EXPAND %{User-Name} (3090) dailycounter: --> testtesttest (3090) dailycounter: SQL-User-Name set to 'testtesttest' rlm_sql (sql): Reserved connection (297) (3090) dailycounter: Executing select query: SELECT SUM(acctsessiontime - GREATEST((1685484000 - UNIX_TIMESTAMP(acctstarttime)), 0)) FROM radacct WHERE username = 'testtesttest' AND UNIX_TIMESTAMP(acctstarttime) + acctsessiontime > '1685484000' rlm_sql (sql): Released connection (297) (3090) dailycounter: EXPAND %{sql:SELECT SUM(acctsessiontime -GREATEST((1685484000 - UNIX_TIMESTAMP(acctstarttime)), 0)) FROM radacct WHERE username = '%{User-Name}' AND UNIX_TIMESTAMP(acctstarttime) + acctsessiontime > '1685484000'} (3090) dailycounter: --> 299 (3090) dailycounter: Allowing user, &control:Max-Daily-Session value (300) is greater than counter value (299) (3090) dailycounter: Setting &reply:Session-Timeout value to 1 (3090) [dailycounter] = ok (3090) [expiration] = noop <...> (2499) Login OK: [testtesttest] (from client pherkad_ipv6 port 1 cli A0-88-B4-B5-47-C0) (2499) Sent Access-Accept Id 250 from [fd10:2842:f0d1:101::2]:1812 to [fd10:2842:f0d1:101:20d:b9ff:fe0d:c9c0]:56722 length 0 (2499) MS-MPPE-Recv-Key = 0x5006b02549aab2d72a020f8a17a16052e8c967bf253791d93f8a904d72bc8ec8 (2499) MS-MPPE-Send-Key = 0x98b138434cfd1cc09198086179c52dce065bde4d2634520098c6bf70e92aa0c2 (2499) EAP-Message = 0x03a90004 (2499) Message-Authenticator = 0x00000000000000000000000000000000 (2499) User-Name = "testtesttest" (2499) Session-Timeout += 1 (2499) Acct-Interim-Interval = 600 <...> -- Robert Senger
On May 30, 2023, at 8:37 PM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
The situation is that the station trying to connect is allowed a Max- Daily-Session of 300 seconds. The counter is at 299, so sqlcounter correctly sets Session-Timeout = 1, and the station is allowed access for one second remaining...
That is very much not going to work. Most NASes will not deal well with Session-Timeouts that small. It's more common to set Session-Timeout to larger values, like 5 minutes.
However, this connection is terminated immediately by the Wifi AP (running hostapd 2.due to Session-Timeout = 1.
i.e. the *used* session time is zero. So the server never gets an accounting packet with Acct-Session-Time = 1, and the counter is never changed. So the next time the user tries to log in, he will get Session-Timeout = 1 again.
The counter never gets increased, the station retries and is allowed access, and every 5 seconds or so this repeats and repeats and repeats... The logs get flooded and there's useless load on the AP and freeradius. The station (Linux machine with NetworkManager) stopped trying to connect after half an hour or so...
So... don't set Session-Timeout = 1? This isn't really a FreeRADIUS issue. The RADIUS protocol can only handle times based on seconds. Sub-second resolution isn't supported.
This behaviour is reproduceable. Every time the station's Max-Daily- Session value is reached and it get's kicked off by the AP, it get's into this loop. The number of retries until the station finally is giving up is significantly higher if more than one AP with the same SSID is reachable (>30 minutes). This behaviour also occurs if the "counter" module is used rather than the "sqlcounter" module.
Freeradius version is 3.0.21, hostapd version is 2.10-8.
Did I configure something wrong, or what happens here? Thank you for help!
The solution is a post-processing state, say in the "post-auth" section: post-auth { if (&reply:Session-Timeout < 30) { reject } ... } i.e. "if they have less than 30 seconds of time remaining, just reject them". There is no good way to allow sub-second session timeouts, or sub-second Acct-Session-Time. The RADIUS protocol doesn't support that. So you're left with a time resolution of one second. And even then, the RADIUS client is likely to not deal well with very small values in Session-Timeout. Alan DeKok.
Hi Alan, thank you! I did not set a time resolution of one second, this is done by the sqlcounter module with it's default settings. I was looking for a configuration option like "Min-Session-Timeout" or something like that, but there is none.
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
This looks good, just tried that (in the sites-available/default file), but won't work: (342) post-auth { (342) if (&reply:Session-Timeout < 30) { (342) ERROR: Failed retrieving values required to evaluate condition ? :) Robert Am Dienstag, dem 30.05.2023 um 22:52 -0400 schrieb Alan DeKok:
On May 30, 2023, at 8:37 PM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
The situation is that the station trying to connect is allowed a Max- Daily-Session of 300 seconds. The counter is at 299, so sqlcounter correctly sets Session-Timeout = 1, and the station is allowed access for one second remaining...
That is very much not going to work. Most NASes will not deal well with Session-Timeouts that small.
It's more common to set Session-Timeout to larger values, like 5 minutes.
However, this connection is terminated immediately by the Wifi AP (running hostapd 2.due to Session-Timeout = 1.
i.e. the *used* session time is zero. So the server never gets an accounting packet with Acct-Session-Time = 1, and the counter is never changed.
So the next time the user tries to log in, he will get Session- Timeout = 1 again.
The counter never gets increased, the station retries and is allowed access, and every 5 seconds or so this repeats and repeats and repeats... The logs get flooded and there's useless load on the AP and freeradius. The station (Linux machine with NetworkManager) stopped trying to connect after half an hour or so...
So... don't set Session-Timeout = 1?
This isn't really a FreeRADIUS issue. The RADIUS protocol can only handle times based on seconds. Sub-second resolution isn't supported.
This behaviour is reproduceable. Every time the station's Max- Daily- Session value is reached and it get's kicked off by the AP, it get's into this loop. The number of retries until the station finally is giving up is significantly higher if more than one AP with the same SSID is reachable (>30 minutes). This behaviour also occurs if the "counter" module is used rather than the "sqlcounter" module.
Freeradius version is 3.0.21, hostapd version is 2.10-8.
Did I configure something wrong, or what happens here? Thank you for help!
The solution is a post-processing state, say in the "post-auth" section:
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
i.e. "if they have less than 30 seconds of time remaining, just reject them".
There is no good way to allow sub-second session timeouts, or sub- second Acct-Session-Time. The RADIUS protocol doesn't support that.
So you're left with a time resolution of one second. And even then, the RADIUS client is likely to not deal well with very small values in Session-Timeout.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- -- Robert Senger
Hey Robert, Is that not saying that there is no 'Session-Timeout' attribute in the reply in this circumstance? Do you see the attribute set within the reply packet from the auth request? "(342) ERROR: Failed retrieving values required to evaluate condition" Perhaps you need to check the attribute is present within the check condition first? Thanks Martin. -----Original Message----- From: Freeradius-Users <freeradius-users-bounces+medge=neverathome.net@lists.freeradius.org> On Behalf Of Robert Senger Sent: Wednesday, May 31, 2023 3:44 PM To: FreeRadius users mailing list <freeradius-users@lists.freeradius.org> Subject: Re: Weird behaviour of sqlcounter / dailycounter Hi Alan, thank you! I did not set a time resolution of one second, this is done by the sqlcounter module with it's default settings. I was looking for a configuration option like "Min-Session-Timeout" or something like that, but there is none.
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
This looks good, just tried that (in the sites-available/default file), but won't work: (342) post-auth { (342) if (&reply:Session-Timeout < 30) { (342) ERROR: Failed retrieving values required to evaluate condition ? :) Robert Am Dienstag, dem 30.05.2023 um 22:52 -0400 schrieb Alan DeKok:
On May 30, 2023, at 8:37 PM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
The situation is that the station trying to connect is allowed a Max- Daily-Session of 300 seconds. The counter is at 299, so sqlcounter correctly sets Session-Timeout = 1, and the station is allowed access for one second remaining...
That is very much not going to work. Most NASes will not deal well with Session-Timeouts that small.
It's more common to set Session-Timeout to larger values, like 5 minutes.
However, this connection is terminated immediately by the Wifi AP (running hostapd 2.due to Session-Timeout = 1.
i.e. the *used* session time is zero. So the server never gets an accounting packet with Acct-Session-Time = 1, and the counter is never changed.
So the next time the user tries to log in, he will get Session- Timeout = 1 again.
The counter never gets increased, the station retries and is allowed access, and every 5 seconds or so this repeats and repeats and repeats... The logs get flooded and there's useless load on the AP and freeradius. The station (Linux machine with NetworkManager) stopped trying to connect after half an hour or so...
So... don't set Session-Timeout = 1?
This isn't really a FreeRADIUS issue. The RADIUS protocol can only handle times based on seconds. Sub-second resolution isn't supported.
This behaviour is reproduceable. Every time the station's Max- Daily- Session value is reached and it get's kicked off by the AP, it get's into this loop. The number of retries until the station finally is giving up is significantly higher if more than one AP with the same SSID is reachable (>30 minutes). This behaviour also occurs if the "counter" module is used rather than the "sqlcounter" module.
Freeradius version is 3.0.21, hostapd version is 2.10-8.
Did I configure something wrong, or what happens here? Thank you for help!
The solution is a post-processing state, say in the "post-auth" section:
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
i.e. "if they have less than 30 seconds of time remaining, just reject them".
There is no good way to allow sub-second session timeouts, or sub- second Acct-Session-Time. The RADIUS protocol doesn't support that.
So you're left with a time resolution of one second. And even then, the RADIUS client is likely to not deal well with very small values in Session-Timeout.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- -- Robert Senger - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Hi Martin, okay, got it, of course it's not there if a user connects without a Max-Daily-Session check applied... That's what I've seen, thanks. My fault... ;) But, even if it is there (user with Max-Daily-Session := <something>), I get a different error: (157) } # server inner-tunnel (157) Virtual server sending reply (157) Fall-Through = Yes (157) Session-Timeout = 1 (157) eap_ttls: Got tunneled Access-Accept (157) eap_ttls: No information to cache: session caching will be disabled for session 99925447ddd1b6d230ee229d03136f0f53460a71d1ca71a68d8c51d4bf835f53 (157) eap: Sending EAP Success (code 3) ID 105 length 4 (157) eap: Freeing handler (157) [eap] = ok (157) } # authenticate = ok (157) # Executing section post-auth from file /etc/freeradius/3.0/sites-enabled/default (157) post-auth { (157) if (&reply:Session-Timeout < 30) { (157) ERROR: Failed retrieving values required to evaluate condition (157) if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { (157) if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) -> FALSE (157) update { <...> (157) Login OK: [testtesttest] (from client pherkad_ipv6 port 1 cli A0-88-B4-B5-47-C0) (157) Sent Access-Accept Id 20 from [fd10:2842:f0d1:101::2]:1812 to [fd10:2842:f0d1:101:20d:b9ff:fe0d:c9c0]:37790 length 0 (157) MS-MPPE-Recv-Key = 0x41bce82171e811b2edb2af62f6049e1e3b6ef9c3de3792d30cf0fae1e511e028 (157) MS-MPPE-Send-Key = 0x4eddbed50ffa74919ff3baf962511f64679f591f1675fcb9fbb395adaf96f1c9 (157) EAP-Message = 0x039c0004 (157) Message-Authenticator = 0x00000000000000000000000000000000 (157) User-Name = "testtesttest" (157) Session-Timeout += 1 (157) Acct-Interim-Interval = 600 Hm... ??? Regards, Robert Am Mittwoch, dem 31.05.2023 um 15:55 +1000 schrieb Martin Edge: Hey Robert, Is that not saying that there is no 'Session-Timeout' attribute in the reply in this circumstance? Do you see the attribute set within the reply packet from the auth request? "(342) ERROR: Failed retrieving values required to evaluate condition" Perhaps you need to check the attribute is present within the check condition first? Thanks Martin. -----Original Message----- From: Freeradius-Users <freeradius-users-bounces+medge=neverathome.net@lists.freeradius.org> On Behalf Of Robert Senger Sent: Wednesday, May 31, 2023 3:44 PM To: FreeRadius users mailing list <freeradius-users@lists.freeradius.org> Subject: Re: Weird behaviour of sqlcounter / dailycounter Hi Alan, thank you! I did not set a time resolution of one second, this is done by the sqlcounter module with it's default settings. I was looking for a configuration option like "Min-Session-Timeout" or something like that, but there is none.
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
This looks good, just tried that (in the sites-available/default file), but won't work: (342) post-auth { (342) if (&reply:Session-Timeout < 30) { (342) ERROR: Failed retrieving values required to evaluate condition ? :) Robert Am Dienstag, dem 30.05.2023 um 22:52 -0400 schrieb Alan DeKok:
On May 30, 2023, at 8:37 PM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
The situation is that the station trying to connect is allowed a Max- Daily-Session of 300 seconds. The counter is at 299, so sqlcounter correctly sets Session-Timeout = 1, and the station is allowed access for one second remaining...
That is very much not going to work. Most NASes will not deal well with Session-Timeouts that small.
It's more common to set Session-Timeout to larger values, like 5 minutes.
However, this connection is terminated immediately by the Wifi AP (running hostapd 2.due to Session-Timeout = 1.
i.e. the *used* session time is zero. So the server never gets an accounting packet with Acct-Session-Time = 1, and the counter is never changed.
So the next time the user tries to log in, he will get Session- Timeout = 1 again.
The counter never gets increased, the station retries and is allowed access, and every 5 seconds or so this repeats and repeats and repeats... The logs get flooded and there's useless load on the AP and freeradius. The station (Linux machine with NetworkManager) stopped trying to connect after half an hour or so...
So... don't set Session-Timeout = 1?
This isn't really a FreeRADIUS issue. The RADIUS protocol can only handle times based on seconds. Sub-second resolution isn't supported.
This behaviour is reproduceable. Every time the station's Max- Daily- Session value is reached and it get's kicked off by the AP, it get's into this loop. The number of retries until the station finally is giving up is significantly higher if more than one AP with the same SSID is reachable (>30 minutes). This behaviour also occurs if the "counter" module is used rather than the "sqlcounter" module.
Freeradius version is 3.0.21, hostapd version is 2.10-8.
Did I configure something wrong, or what happens here? Thank you for help!
The solution is a post-processing state, say in the "post-auth" section:
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
i.e. "if they have less than 30 seconds of time remaining, just reject them".
There is no good way to allow sub-second session timeouts, or sub- second Acct-Session-Time. The RADIUS protocol doesn't support that.
So you're left with a time resolution of one second. And even then, the RADIUS client is likely to not deal well with very small values in Session-Timeout.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Robert Senger - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html -- Robert Senger
On May 31, 2023, at 1:43 AM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
I did not set a time resolution of one second,
Please read what I wrote. This isn't difficult. The *RADIUS PROTOCOL* has a time resolution of one second. I didn't ask if you set that. I was explaining to you that this is a fundamental limitation of how RADIUS works.
this is done by the sqlcounter module with it's default settings. I was looking for a configuration option like "Min-Session-Timeout" or something like that, but there is none.
Exactly. I gave you an example to set a minimum session timeout.
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
This looks good, just tried that (in the sites-available/default file), but won't work:
(342) post-auth { (342) if (&reply:Session-Timeout < 30) { (342) ERROR: Failed retrieving values required to evaluate condition
? :)
Read the debug output and think about it. The other debug output you posted shows it setting the Session-Timeout in the "inner-tunnel" virtual server. Which means it's not being set in the "default" virtual server. You can out the example config I posted in the inner-tunnel virtual server, instead of "default". I only suggested to put it in "default", because that's normally where it goes. But if you're running the counter module in the "inner-tunnel" virtual server, then the check for &reply:Session-Timeout needs to go there, too. Alan DeKok.
Hi Alan, okay, I assumed that if I have enabled the inner-tunnel to copy attributes to the outer reply (by setting "if (0)" to "if(1)" as documented), the attribute will be available as it is sent to the nas. That was a misunderstanding. Now, as I added the code to the inner- tunnel file, it works. However, I discovered that neither logintime nor dailycounter get checked if a station uses EAP-TLS. So, I've enabled the check-eap-tls module, activated it in mods-enabled/eap file, added "sql" (to get the Login-Time and Max-Daily-Session attributes), added "logintime" and "dailycounter" in the mods-enables/check-eap-tls file, and as far as I've tested this by now it seems to work. Is that a correct way to enable logintime and dailycounter for EAP-TLS? Thanks a lot for now for your help! Robert Am Mittwoch, dem 31.05.2023 um 09:29 -0400 schrieb Alan DeKok:
On May 31, 2023, at 1:43 AM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
I did not set a time resolution of one second,
Please read what I wrote. This isn't difficult.
The *RADIUS PROTOCOL* has a time resolution of one second. I didn't ask if you set that. I was explaining to you that this is a fundamental limitation of how RADIUS works.
this is done by the sqlcounter module with it's default settings. I was looking for a configuration option like "Min-Session-Timeout" or something like that, but there is none.
Exactly. I gave you an example to set a minimum session timeout.
post-auth { if (&reply:Session-Timeout < 30) { reject } ... }
This looks good, just tried that (in the sites-available/default file), but won't work:
(342) post-auth { (342) if (&reply:Session-Timeout < 30) { (342) ERROR: Failed retrieving values required to evaluate condition
? :)
Read the debug output and think about it.
The other debug output you posted shows it setting the Session- Timeout in the "inner-tunnel" virtual server. Which means it's not being set in the "default" virtual server.
You can out the example config I posted in the inner-tunnel virtual server, instead of "default". I only suggested to put it in "default", because that's normally where it goes.
But if you're running the counter module in the "inner-tunnel" virtual server, then the check for &reply:Session-Timeout needs to go there, too.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- -- Robert Senger
On May 31, 2023, at 12:43 PM, Robert Senger <robert.senger@lists.microscopium.de> wrote:
okay, I assumed that if I have enabled the inner-tunnel to copy attributes to the outer reply (by setting "if (0)" to "if(1)" as documented), the attribute will be available as it is sent to the nas. That was a misunderstanding. Now, as I added the code to the inner- tunnel file, it works.
That's good
However, I discovered that neither logintime nor dailycounter get checked if a station uses EAP-TLS. So, I've enabled the check-eap-tls module, activated it in mods-enabled/eap file, added "sql" (to get the Login-Time and Max-Daily-Session attributes), added "logintime" and "dailycounter" in the mods-enables/check-eap-tls file, and as far as I've tested this by now it seems to work. Is that a correct way to enable logintime and dailycounter for EAP-TLS?
If it works... Alan DeKok.
participants (3)
-
Alan DeKok -
Martin Edge -
Robert Senger