Re: Is it possible to automate a Disconnect-Request based on exceeded Monthly-Usage?
Hi Alan and Jorge, Sorry, I should have explained that I'm using StrongSwan as my NAS, which is supporting CoA : --- StrongSwan Release 4.6.3 <https://wiki.strongswan.org/projects/strongswan/wiki/463> introduces support for the RADIUS Session-Timeout attribute and the Dynamic Authorization extension, RFC 5176. A received Session-Timeout from the RADIUS backend is enforced using Repeated Authentication, RFC 4478. The Dynamic Authorization Extension allows a RADIUS backend to actively terminate a session using a Disconnect-Request, or change the timeout of a session using a Session-Timeout attribute in a CoA-Request. The extension is enabled using a *dae* section in the *eap-radius* configuration --- I can see when I send a Disconnect-Request manually like this: echo User-Name=houman | radclient -x 127.0.0.1:3799 disconnect ''secret123'' The NAS is able to see the CoA packet and disconnects the user already. I have found the home server example in sites-available/originate-coa. I think I have to set it up under /etc/freeradius/3.0/proxy.cnf. Alan, I'm a bit lost here when you said:
That's what "originate-com" is for. The documentation isn't perfect, but it should be good. When you receive an accounting >request packet, check for over the limit, and if so, send a Disconnect-Request packet.
I think you mean I have to do that in /etc/freeradius/3.0/sites-enabled/default under the section: update request { ... } In what programming language do I have to do that? I think it has to be in SQL right? I already do this to capture the monthly usage upon each request: update request { Monthly-Usage = "%{sql:SELECT COALESCE((SUM(`acctoutputoctets`)), 0) FROM radacct WHERE `username`='%{User-Name}' AND Month(acctupdatetime)=(Month(NOW())) AND Year(acctupdatetime)=Year(NOW())}" } Now I need to add another line underneath to compare the Monthly-Usage against a value and then send the Disconnect-Request if it's greater than the value. How Do I raise the Disconnect-Request? Many Thanks, Houman
On Sep 11, 2019, at 3:05 AM, Houman <houmie@gmail.com> wrote:
Sorry, I should have explained that I'm using StrongSwan as my NAS, which is supporting CoA :
That's nice, but sort of assumed. If the NAS doesn't support CoA, then there's no point in sending it CoA packets.
I have found the home server example in sites-available/originate-coa. I think I have to set it up under /etc/freeradius/3.0/proxy.cnf.
I'm not sure what that means. Set "it" up? Set *what* up? If you read the "originate-coa" virtual server, you will see what you have to set up. So did you do that?
Alan, I'm a bit lost here when you said:
That's what "originate-com" is for. The documentation isn't perfect, but it should be good. When you receive an accounting >request packet, check for over the limit, and if so, send a Disconnect-Request packet.
I think you mean I have to do that in /etc/freeradius/3.0/sites-enabled/default under the section:
update request { ... }
In the "preacct" or "accounting" sections.
In what programming language do I have to do that? I think it has to be in SQL right?
If your users are in SQL, you check their usage via SQL queries.
I already do this to capture the monthly usage upon each request:
update request {
Monthly-Usage = "%{sql:SELECT COALESCE((SUM(`acctoutputoctets`)), 0) FROM radacct WHERE `username`='%{User-Name}' AND Month(acctupdatetime)=(Month(NOW())) AND Year(acctupdatetime)=Year(NOW())}"
}
OK.
Now I need to add another line underneath to compare the Monthly-Usage against a value and then send the Disconnect-Request if it's greater than the value. How Do I raise the Disconnect-Request?
The "originate-coa" virtual server explains that in detail. Read the comments at the top of that file. See also "man unlang". There *is* extensive documentation on this, that I already pointed you to. If you have questions about the documentation, ask. But asking a question *answered in the documentation*, then it looks like you haven't read it. Alan DeKok.
Hi Alan, Alright, let's go through the steps. 1) Based on sites-available/originate-coa I have inserted the following into /etc/freeradius/3.0/sites-enabled/default I have added the home_server after the server default like this: server default { ... } home_server example-coa { type = coa ipaddr = 127.0.0.1 port = 3799 secret = secret123 coa { irt = 2 mrt = 16 mrc = 5 mrd = 30 } } Looking at "man unlang", In the server default I have added this section to the preacct: preacct { preprocess if (Monthly-Usage > 300000000000) { update coa { &User-Name = "%{User-Name}" &Acct-Session-Id = "%{Acct-Session-Id}" &NAS-IP-Address = "%{NAS-IP-Address}" } } This should now send the Disconnect-Request, based on the usage greater than 300 GB. Does this make sense what I have done so far? Thanks, Houman On Wed, 11 Sep 2019 at 12:15, Alan DeKok <aland@deployingradius.com> wrote:
On Sep 11, 2019, at 3:05 AM, Houman <houmie@gmail.com> wrote:
Sorry, I should have explained that I'm using StrongSwan as my NAS, which is supporting CoA :
That's nice, but sort of assumed. If the NAS doesn't support CoA, then there's no point in sending it CoA packets.
I have found the home server example in sites-available/originate-coa. I think I have to set it up under /etc/freeradius/3.0/proxy.cnf.
I'm not sure what that means. Set "it" up? Set *what* up?
If you read the "originate-coa" virtual server, you will see what you have to set up. So did you do that?
Alan, I'm a bit lost here when you said:
That's what "originate-com" is for. The documentation isn't perfect, but it should be good. When you receive an accounting >request packet, check for over the limit, and if so, send a Disconnect-Request packet.
I think you mean I have to do that in /etc/freeradius/3.0/sites-enabled/default under the section:
update request { ... }
In the "preacct" or "accounting" sections.
In what programming language do I have to do that? I think it has to be in SQL right?
If your users are in SQL, you check their usage via SQL queries.
I already do this to capture the monthly usage upon each request:
update request {
Monthly-Usage = "%{sql:SELECT COALESCE((SUM(`acctoutputoctets`)), 0) FROM radacct WHERE `username`='%{User-Name}' AND Month(acctupdatetime)=(Month(NOW())) AND Year(acctupdatetime)=Year(NOW())}"
}
OK.
Now I need to add another line underneath to compare the Monthly-Usage against a value and then send the Disconnect-Request if it's greater than the value. How Do I raise the Disconnect-Request?
The "originate-coa" virtual server explains that in detail. Read the comments at the top of that file. See also "man unlang".
There *is* extensive documentation on this, that I already pointed you to. If you have questions about the documentation, ask. But asking a question *answered in the documentation*, then it looks like you haven't read it.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Sep 11, 2019, at 2:15 PM, Houman <houmie@gmail.com> wrote:
Alright, let's go through the steps.
1) Based on sites-available/originate-coa I have inserted the following into /etc/freeradius/3.0/sites-enabled/default
I have added the home_server after the server default like this:
That works... but it's generally recommended to put home servers into proxy.conf. That way you can find them later, as they're all in a consistent place.
server default { ... } home_server example-coa { type = coa ipaddr = 127.0.0.1
Uh... is your NAS on localhost? Or is your NAS elsewhere in the network? You probably *don't* want to send CoA packets to FreeRADIUS. As I explained before, this will NOT kick the user offline.
Looking at "man unlang", In the server default I have added this section to the preacct:
preacct { preprocess if (Monthly-Usage > 300000000000) { update coa { &User-Name = "%{User-Name}" &Acct-Session-Id = "%{Acct-Session-Id}" &NAS-IP-Address = "%{NAS-IP-Address}" } }
That's good.
This should now send the Disconnect-Request, based on the usage greater than 300 GB.
No, it will send a "coa" packet. Because you've used the word "coa". If you want a disconnect, use "disconnect", as is documented in the originate-coa file I said to read, AND in "man unlang" I said to read.
Does this make sense what I have done so far?
Mostly. See the comments above. And read the NAS documentation to see which attributes are needed in a Disconnect-Request packet. We don't know which ones are relevant. If you get the list wrong, then then the NAS will send a Disconnect-NAK response. And won't tell you which attributes it was looking for. Alan DeKok.
Hi Alan, Great news, It almost works now. The issue I get is now the conditional here: preacct { preprocess if (Monthly-Usage > 300000000000) { update disconnect { &User-Name = "%{User-Name}" } } (5) NAS-Identifier = "strongSwan" (5) # Executing section preacct from file /etc/freeradius/3.0/sites-enabled/default (5) preacct { (5) [preprocess] = ok (5) if (Monthly-Usage > 300000000000) { (5) ERROR: Failed retrieving values required to evaluate condition (5) policy acct_unique { If I comment out the conditional there, it disconnects the user after 300 seconds when the next preacct is due. So fairly happy that this part works. preacct { preprocess #if (Monthly-Usage > 300000000000) { update disconnect { &User-Name = "%{User-Name}" } #} Now I wonder why the attribute is not seen? I have set it like this: echo 'ATTRIBUTE Monthly-Usage 3001 integer64' >> /etc/freeradius/3.0/dictionary update request { Monthly-Usage = "%{sql:SELECT COALESCE((SUM(`acctoutputoctets`)), 0) FROM radacct WHERE `username`='"'"'%{User-Name}'"'"' AND Month(acctupdatetime)=(Month(NOW())) AND Year(acctupdatetime)=Year(NOW())}" } When updating the request, the Monthly-Usage attribute should be already set, so how comes it doesn't recognise the variable within preacct? Many Thanks, Houman On Wed, 11 Sep 2019 at 22:40, Alan DeKok <aland@deployingradius.com> wrote:
On Sep 11, 2019, at 2:15 PM, Houman <houmie@gmail.com> wrote:
Alright, let's go through the steps.
1) Based on sites-available/originate-coa I have inserted the following into /etc/freeradius/3.0/sites-enabled/default
I have added the home_server after the server default like this:
That works... but it's generally recommended to put home servers into proxy.conf. That way you can find them later, as they're all in a consistent place.
server default { ... } home_server example-coa { type = coa ipaddr = 127.0.0.1
Uh... is your NAS on localhost? Or is your NAS elsewhere in the network?
You probably *don't* want to send CoA packets to FreeRADIUS. As I explained before, this will NOT kick the user offline.
Looking at "man unlang", In the server default I have added this section to the preacct:
preacct { preprocess if (Monthly-Usage > 300000000000) { update coa { &User-Name = "%{User-Name}" &Acct-Session-Id = "%{Acct-Session-Id}" &NAS-IP-Address = "%{NAS-IP-Address}" } }
That's good.
This should now send the Disconnect-Request, based on the usage greater than 300 GB.
No, it will send a "coa" packet. Because you've used the word "coa". If you want a disconnect, use "disconnect", as is documented in the originate-coa file I said to read, AND in "man unlang" I said to read.
Does this make sense what I have done so far?
Mostly. See the comments above.
And read the NAS documentation to see which attributes are needed in a Disconnect-Request packet. We don't know which ones are relevant. If you get the list wrong, then then the NAS will send a Disconnect-NAK response. And won't tell you which attributes it was looking for.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Sep 12, 2019, at 3:09 PM, Houman <houmie@gmail.com> wrote:
Hi Alan,
Great news, It almost works now.
The issue I get is now the conditional here:
preacct { preprocess if (Monthly-Usage > 300000000000) {
And where does "Monthly-Usage" come from? Not from the Accounting-Request packet.
(5) preacct { (5) [preprocess] = ok (5) if (Monthly-Usage > 300000000000) { (5) ERROR: Failed retrieving values required to evaluate condition
Yup.
Now I wonder why the attribute is not seen?
Because it doesn't exist.
I have set it like this:
echo 'ATTRIBUTE Monthly-Usage 3001 integer64' >> /etc/freeradius/3.0/dictionary
update request { Monthly-Usage = "%{sql:SELECT COALESCE((SUM(`acctoutputoctets`)), 0) FROM radacct WHERE `username`='"'"'%{User-Name}'"'"' AND Month(acctupdatetime)=(Month(NOW())) AND Year(acctupdatetime)=Year(NOW())}" }
And where is that set?
When updating the request, the Monthly-Usage attribute should be already set, so how comes it doesn't recognise the variable within preacct?
If it WAS already set, then the debug output would show it being set. Odds are that your'e setting it when the Access-Request is received. The server does *not* magically track attributes across multiple packets. That's what a database is for. Or, you're setting it in the "accounting' section, which (according to the debug output) runs AFTER the "preacct" section. If you want to set Monthly-Usage, the you need to *actually set it* :: preacct { preprocess update request { Monthly-Usage = "%{sql:SELECT COALESCE((SUM(`acctoutputoctets`)), 0) FROM radacct WHERE `username`='"'"'%{User-Name}'"'"' AND Month(acctupdatetime)=(Month(NOW())) AND Year(acctupdatetime)=Year(NOW())}" } if (Monthly-Usage > 300000000000) { update disconnect { &User-Name = "%{User-Name}" } ... Then it will work. Alan DeKok.
participants (2)
-
Alan DeKok -
Houman