Hi, we have been using the exec module with version 2 to run an external PHP script that (for example) assigns a VLAN depending on the user's location [1] - this is done post-auth. We have migrated to freeradius version 3. I note from http://networkradius.com/doc/3.0.10/raddb/mods-available/exec.html that "The exec module may look like it works for one or two tests, but in a live situation it can cause the server to become unresponsive under load. The perl module is recommended for general-purpose computing." Now if I had read that four years ago I'd not have gone down the exec route... anyway. So it seems to me we need to rewrite the exec module using one of the scripting modules. So I am wondering how the python module compares to the perl module. I found and read a great post from Herwin Weststrate <herwin@quarantainenet.nl> from November 2016 that explains some of the differences. I'd rather use python than perl, all else being equal. Lua is an outlier of an option. Any thoughts? Apologies if any of the above is unclear. [] which we get from the access-point identifier string.
On Feb 27, 2018, at 8:28 AM, Dom Latter <freeradius-users@latter.org> wrote:
we have been using the exec module with version 2 to run an external PHP script that (for example) assigns a VLAN depending on the user's location [1] - this is done post-auth.
We have migrated to freeradius version 3.
That's good...
I note from http://networkradius.com/doc/3.0.10/raddb/mods-available/exec.html that "The exec module may look like it works for one or two tests, but in a live situation it can cause the server to become unresponsive under load. The perl module is recommended for general-purpose computing."
Now if I had read that four years ago I'd not have gone down the exec route... anyway.
Yeah.
So it seems to me we need to rewrite the exec module using one of the scripting modules.
So I am wondering how the python module compares to the perl module.
Both work.
I found and read a great post from Herwin Weststrate <herwin@quarantainenet.nl> from November 2016 that explains some of the differences.
I'd rather use python than perl, all else being equal.
Python is fine.
Lua is an outlier of an option.
There's no lua module in v3. Alan DeKok.
On 27/02/18 13:54, Alan DeKok wrote:
On Feb 27, 2018, at 8:28 AM, Dom Latter <freeradius-users@latter.org> wrote:
I'd rather use python than perl, all else being equal.
Python is fine.
Thanks for the swift reply Alan. So performance wise it's similar? I should perhaps have mentioned that the script needs to connect to the database to check against known MAC addresses, send emails to new users, that sort of thing.
On Feb 27, 2018, at 8:57 AM, Dom Latter <freeradius-users@latter.org> wrote:
So performance wise it's similar?
TBH, Python is probably slower than Perl. The Perl interpreter is threaded, Python isn't. There's a "Big Interpreter Lock" that essentially prevents most multi-threading. That makes a BIG difference. Which means that the speed of running Perl or Python code itself doesn't matter, since Python spends most of it's time waiting for a lock.
I should perhaps have mentioned that the script needs to connect to the database to check against known MAC addresses, send emails to new users, that sort of thing.
Use the native DB query functions in FreeRADIUS. It's MUCH faster that way. i.e. do any and all DB queries via "update" sections, and assign the values to temporary attributes. Then, run the *logic* in Python. i.e. have the python code do if / then / else checks, but don't have it to DB connectivity. And if you're sending email, you're MUCH better off doing that out of band. i.e. have FR write the information to a file / DB, etc. Then, another process can read that file and send the email. Sending the email fro Python code inside of FreeRADIUS means that your RADIUS server will go down as soon as there's a problem with email. If you're getting no more than 10-20 packets a second, you're probably OK with a "brute-force" approach. But if the traffic spikes much higher than that, you could quickly take your RADIUS server down with "brute-force" programming. Alan DeKok.
On 27/02/18 14:09, Alan DeKok wrote:
That makes a BIG difference. Which means that the speed of running Perl or Python code itself doesn't matter, since Python spends most of it's time waiting for a lock.
So for anything that might scale to lots of users - perl is the way to go.
Use the native DB query functions in FreeRADIUS. It's MUCH faster that way.
i.e. do any and all DB queries via "update" sections, and assign the values to temporary attributes. Then, run the *logic* in Python. i.e. have the python code do if / then / else checks, but don't have it to DB connectivity.
Sounds, err, interesting....
And if you're sending email, you're MUCH better off doing that out of band. i.e. have FR write the information to a file / DB, etc. Then, another process can read that file and send the email.
Sending the email fro Python code inside of FreeRADIUS means that your RADIUS server will go down as soon as there's a problem with email.
Right.... seems to have worked reasonably well with the exec module but I guess that's because it's in another process.
On 27/02/18 14:09, Alan DeKok wrote:
Use the native DB query functions in FreeRADIUS. It's MUCH faster that way.
i.e. do any and all DB queries via "update" sections, and assign the values to temporary attributes. Then, run the *logic* in Python. i.e. have the python code do if / then / else checks, but don't have it to DB connectivity.
And if you're sending email, you're MUCH better off doing that out of band. i.e. have FR write the information to a file / DB, etc. Then, another process can read that file and send the email.
Hi, I have looked into our current script and ascertained that the vast majority of auth requests can be handled by a single SELECT query and some logic in perl. It is (essentially) only when we see a device for the first time that we need to update database tables and send emails. I imagine that it will be easy enough to create a non-blocking mechanism for sending email, but out of interest, if we use perl, would it be such a big problem to send mail from the perl script given that the perl interpreter is threaded? As for the database updates I think we can take the performance hit of running them from within the script as they are infrequent - I don't have a metric immediately to hand but one every few minutes sounds about right. Or would you still strongly recommend making these DB updates "native" as well? thanks dom
On Mar 1, 2018, at 11:45 AM, Dom Latter <freeradius-users@latter.org> wrote:
Hi, I have looked into our current script and ascertained that the vast majority of auth requests can be handled by a single SELECT query and some logic in perl.
That's good.
It is (essentially) only when we see a device for the first time that we need to update database tables and send emails.
I imagine that it will be easy enough to create a non-blocking mechanism for sending email, but out of interest, if we use perl, would it be such a big problem to send mail from the perl script given that the perl interpreter is threaded?
Yes. As soon as anything goes wrong with the email subsystem, the threads will lock one by one, and then the RADIUS server will go down. If you can write the Perl script so that it *always* runs within (say ) 1/10s, then it's probably OK. i.e. try to send the email, and if it doesn't successfully send immediately, bail out with an error. The alternative is to write the email details to a queue, and then have the mailer pick up messages. If the mail subsystem can poll a directory for queued messages, you can just place messages there, and rely on the mailer to eventually pick them up. The key thing to realize is that if mail is delayed, no one cares that much. If the RADIUS server goes down, then everyone complains.
As for the database updates I think we can take the performance hit of running them from within the script as they are infrequent - I don't have a metric immediately to hand but one every few minutes sounds about right. Or would you still strongly recommend making these DB updates "native" as well?
If it's one every few minutes, it's probably OK. Alan DeKok.
On 02/27/18 14:09, Alan DeKok wrote:
Use the native DB query functions in FreeRADIUS. It's MUCH faster that way.
i.e. do any and all DB queries via "update" sections, and assign the values to temporary attributes. Then, run the *logic* in Python. i.e. have the python code do if / then / else checks, but don't have it to DB connectivity.
Hi, we are trying to pursue this approach. I am trying to figure out how to get multiple values out of the database. I have got this: update control { DL-Device-Vendor := "%{sql:SELECT devicevendor FROM userinfo \ WHERE username='%{request:User-Name}' }" } (NB no line break in reality). working inside a post-auth block inside /etc/freeradius/sites-enabled /default. (In that I run freeradius -X and see the query running in the debug output). Now what I want is to run a longer and more complicated query and set up multiple attributes. (Our current post-auth script pulls some 13 items out of the database). The only thing I have found on this so far is this page on github: https://github.com/FreeRADIUS/freeradius-server/issues/984 So I tried this : map sql "SELECT devicevendor FROM userinfo WHERE \ username='{request:User-Name}'" { XL-Device-Vendor := 'devicevendor' } and got this error: Expecting section start brace '{' after "map sql" (Also tried with 'mysql' rather than 'sql' - which should it be, anyway?) How do I go about this?
On Apr 12, 2018, at 9:14 AM, Dom Latter <freeradius-users@latter.org> wrote:
we are trying to pursue this approach. I am trying to figure out how to get multiple values out of the database.
v3 doesn't really support that well.
The only thing I have found on this so far is this page on github: https://github.com/FreeRADIUS/freeradius-server/issues/984
Which as the comments say, was done in 3.1.x (now v4). It's not available in v3.
How do I go about this?
You might need to just keep using Python. Alan DeKok.
On 12/04/18 14:53, Alan DeKok wrote: Thanks for the swift repsonse.
On Apr 12, 2018, at 9:14 AM, Dom Latter <freeradius-users@latter.org> wrote:
we are trying to pursue this approach. I am trying to figure out how to get multiple values out of the database.
v3 doesn't really support that well.
The only thing I have found on this so far is this page on github: https://github.com/FreeRADIUS/freeradius-server/issues/984
Which as the comments say, was done in 3.1.x (now v4). It's not available in v3.
Ah, I made the rash assumption that anything mentioned then would by now be current - but I now understand that v4 is a big rewrite.
How do I go about this?
You might need to just keep using Python.
Well, we are currently using exec to run a PHP script which doesn't seem to be a great idea. So the plan was to move to Perl; but if we did that and ran our mysql queries inside a perl script would we still have the performance issues? I am beginning to think that we can construct a (rather complicated) query that will return the VLAN that needs to be assigned, or 0 to indicate rejection, or a magic number that will indicate further processing required, and use unlang to act appropriately (and call either a PHP script or in due course a perl script). The vast majority of requests would fall into the first two camps. So roughly speaking it would look a bit like this (consider this pseudo-code!) update control { Vlan-Value := "%{sql:SELECT .... as vlan FROM .... WHERE username='%{request:User-Name}' }" } if ( &Vlan-Value == 9999 ) { custom_module } else if ( &Vlan-Value > 0 ) { update reply { Tunnel-Private-Group-Id := Vlan-Value # some more attributes here } } else { reject } Although rather than a select statement I think it would be a stored procedure.
On Apr 12, 2018, at 11:15 AM, Dom Latter <freeradius-users@latter.org> wrote:
Ah, I made the rash assumption that anything mentioned then would by now be current - but I now understand that v4 is a big rewrite.
Yeah. Lots and lots and lots of things are changed. The good news is that the server is a lot more capable. The bad news is that it isn't done yet.
So the plan was to move to Perl; but if we did that and ran our mysql queries inside a perl script would we still have the performance issues?
It would be much better than forking a PHP script.
I am beginning to think that we can construct a (rather complicated) query that will return the VLAN that needs to be assigned, or 0 to indicate rejection, or a magic number that will indicate further processing required, and use unlang to act appropriately (and call either a PHP script or in due course a perl script).
That makes sense.
Although rather than a select statement I think it would be a stored procedure.
That's a common solution to this problem. Alan DeKok.
On 12/04/18 16:25, Alan DeKok wrote:
So the plan was to move to Perl; but if we did that and ran our mysql queries inside a perl script would we still have the performance issues?
It would be much better than forking a PHP script.
Okay.
I am beginning to think that we can construct a (rather complicated) query that will return the VLAN that needs to be assigned, or 0 to indicate rejection, or a magic number that will indicate further processing required, and use unlang to act appropriately (and call either a PHP script or in due course a perl script).
That makes sense.
Does the pseudo-code look sensible then? I am very much a noob with regards to unlang.
On Apr 12, 2018, at 11:29 AM, Dom Latter <freeradius-users@latter.org> wrote:
Does the pseudo-code look sensible then? I am very much a noob with regards to unlang.
It looks fine. Unlang is a simple language. A bit weird, but simple. Alan DeKok.
On 12/04/18 16:45, Alan DeKok wrote:
On Apr 12, 2018, at 11:29 AM, Dom Latter <freeradius-users@latter.org> wrote:
Does the pseudo-code look sensible then? I am very much a noob with regards to unlang.
It looks fine.
Unlang is a simple language. A bit weird, but simple.
<grin> Ah - another quick question. Is there something available similar to '%{request:User-Name} which will give me the current date? (Reason - some wifi accounts have an expiry date so we need to check that. Use of time functions in sql stops the query cache being used, so it's better to have '2018-04-12' in the query than curdate().)
On Apr 12, 2018, at 11:56 AM, Dom Latter <freeradius-users@latter.org> wrote:
Ah - another quick question. Is there something available similar to '%{request:User-Name} which will give me the current date?
https://wiki.freeradius.org/config/run_time_variables Alan DeKok.
On 12/04/18 17:13, Alan DeKok wrote:
On Apr 12, 2018, at 11:56 AM, Dom Latter <freeradius-users@latter.org> wrote:
Ah - another quick question. Is there something available similar to '%{request:User-Name} which will give me the current date?
Brilliant, thanks!
Hi, My choice is Python. But I like Ruby too. IMHO Ruby is one of the prettiest languages. Don't forget one moment - if you will use python - use freeradius 3.0.17 version. more info here: http://freeradius.1045715.n5.nabble.com/Incorrect-reply-rlm-python-with-tagg... ________________________________ От: Freeradius-Users <freeradius-users-bounces+format_hub=outlook.com@lists.freeradius.org> от имени Dom Latter <freeradius-users@latter.org> Отправлено: 27 февраля 2018 г. 15:28 Кому: FreeRadius users mailing list Тема: Perl vs. python vs. Lua? Hi, we have been using the exec module with version 2 to run an external PHP script that (for example) assigns a VLAN depending on the user's location [1] - this is done post-auth. We have migrated to freeradius version 3. I note from http://networkradius.com/doc/3.0.10/raddb/mods-available/exec.html that "The exec module may look like it works for one or two tests, but in a live situation it can cause the server to become unresponsive under load. The perl module is recommended for general-purpose computing." Now if I had read that four years ago I'd not have gone down the exec route... anyway. So it seems to me we need to rewrite the exec module using one of the scripting modules. So I am wondering how the python module compares to the perl module. I found and read a great post from Herwin Weststrate <herwin@quarantainenet.nl> from November 2016 that explains some of the differences. I'd rather use python than perl, all else being equal. Lua is an outlier of an option. Any thoughts? Apologies if any of the above is unclear. [] which we get from the access-point identifier string. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
participants (3)
-
Alan DeKok -
Dom Latter -
Юрий Иванов