allow WLAN-access in certain offices only
Dear Freeradius experts, I have just compiled Freeradius from source and red some of the documentation. WPA2-EAP works with username bob and password hello. radiusd -X shows no errors. Now here's what I would like to achive and maybe some of you can point me into the right direction: We have equipped all of our offices (approx 100) with seperate WLAN access points. Every employee should be able to access the access point in its own office and in some of our conference rooms. Every employee owns an OAuth token that generates a 6digit one time password. Whenever a user tries to access a WLAN access point with his username and his one time password the following should happen: 1) if the password is wrong access should be denied 2) if the access point is not located in the office of the employee or in one of the conference rooms of the employees department access should be denied Our central oracle database has information about the ip-address and location of every access point and the office rooms of every employee. My first idea was to write a php-script (because that's the scripting language I'm familiar with) and use that via rlm_exec. I will do this as a proof of concept. Since neither I nor any of my colleagues have perl-experience I'd rather write a new module in C than use perl. Is there a module that will send all parameters to a unix or inet socket and receives the results from that socket? How abount rlm_socket? Kind regards Peter
On Apr 20, 2021, at 1:04 PM, radius.pkoch@dfgh.net wrote:
I have just compiled Freeradius from source and red some of the documentation. WPA2-EAP works with username bob and password hello. radiusd -X shows no errors.
That's good.
Now here's what I would like to achive and maybe some of you can point me into the right direction:
We have equipped all of our offices (approx 100) with seperate WLAN access points. Every employee should be able to access the access point in its own office and in some of our conference rooms. Every employee owns an OAuth token that generates a 6digit one time password.
That's nice, but you really don't want to use OAuth with Wifi. I don't even know how that would work. i.e. WiFi is bad enough that devices end up re-authenticating multiple times a day. And you definitely don't want users to be asked 5-10 times a day for a new one-time password. Just use a password. Or, use EAP-TLS and client certificates.
Whenever a user tries to access a WLAN access point with his username and his one time password the following should happen:
Scratch all that. First, you should figure out how WiFi works. Then, figure out if your suggested process fits into that. If it doesn't, throw away your requirements about what "should happen", and go with something which is realistic.
1) if the password is wrong access should be denied
So... password checking like normal. But if this is for passwords which change multiple times a day, then it just won't work.
2) if the access point is not located in the office of the employee or in one of the conference rooms of the employees department access should be denied
So... check the source AP to see if it's allowed. How do you check that? Read the debug output to see what each AP sends, and then write rules to match those.
Our central oracle database has information about the ip-address and location of every access point and the office rooms of every employee.
Location is irrelevant. The only thing that matters is what's in the RADIUS packets, and what's shown in the debug logs. Does the term "Conference room 5" appear in the RADIUS packet? No? Then you'll have to figure out some other way which access point is which. Maybe by looking at host names (if they show up in the RADIUS packet), or IP addresses (if they should up in the RADIUS packet), or by MAC (well, you get the idea by now).
My first idea was to write a php-script (because that's the scripting language I'm familiar with) and use that via rlm_exec. I will do this as a proof of concept.
To do... what? You haven't said.
Since neither I nor any of my colleagues have perl-experience I'd rather write a new module in C than use perl.
Is there a module that will send all parameters to a unix or inet socket and receives the results from that socket? How abount rlm_socket?
To do... what? How is any token going to be checked? REST API? What? Your last comments here are really "how do I write a script to do stuff". The only answer is "I dunno, it depends on what stuff you want to do". Alan DeKok.
Dear Alan DeKok, Thanks for the quick reply Am 20.04.2021 um 21:46 schrieb Alan DeKok - aland@deployingradius.com:
On Apr 20, 2021, at 1:04 PM, radius.pkoch@dfgh.net wrote:
I have just compiled Freeradius from source and red some of the documentation. WPA2-EAP works with username bob and password hello. radiusd -X shows no errors. That's good.
Now here's what I would like to achive and maybe some of you can point me into the right direction:
We have equipped all of our offices (approx 100) with seperate WLAN access points. Every employee should be able to access the access point in its own office and in some of our conference rooms. Every employee owns an OAuth token that generates a 6digit one time password. That's nice, but you really don't want to use OAuth with Wifi. I don't even know how that would work.
i.e. WiFi is bad enough that devices end up re-authenticating multiple times a day. And you definitely don't want users to be asked 5-10 times a day for a new one-time password.
Just use a password. Or, use EAP-TLS and client certificates.
We are planning to use our time-based one time password OATH tokens just in the same way we are already doing this for IMAP authentication. When a user authenticates for the first time, he must generate a 6digit value with his token, append his own password to that value and use that combination. The IMAP server (and I was hoping the radius server could do as well) will send the password to our authentication server for validation. We do not use OAuth. Once a password was used successfully, the same value can be used again for a certain period of time that depends on the username. With our IMAP-server this period is 30 days, for a WiFi-guest account this would be 12 hours. The passwords we generate with our OATH-token are not used as ONE time passwords. Hence they must be kept secret and must not be sent over the network in clear.
Whenever a user tries to access a WLAN access point with his username and his one time password the following should happen: Scratch all that.
First, you should figure out how WiFi works. Then, figure out if your suggested process fits into that.
If it doesn't, throw away your requirements about what "should happen", and go with something which is realistic.
So here's what I figured out so far about how WiFi works: - accesspoint is configured for WPA-Enterprise - hence the supplicant is asked for a user / password combination or has to provide a client certificate - the accesspoint receives additional informations from the supplicant (i.e. its mac-address) - the accesspoint sends all the information it has received from the supplicant together with informations about itself to the radius server - the radius server decides wether to allow or deny access and answers the request In our case the radius server will get - among other informations - the username and password of the supplicant plus the IP-address of the accesspoint. This is all that is needed to decide wether the password is correct and wether the accesspoint is located within the office of the person with the given username. But the radius server cannot do this decision on its own. It cannot verify the password but has to delegate that decision. And it cannot query our central oracle database on its own about what accesspoint has the given IP-address and wether this accesspoint is physically located in the office of the person with the given username. I was hoping that the radius server could delegate this decisions to a script. And it seems to me, that there are (at least) the following two possibilities: - use a php-script via rlm_exec - use a perl-script via rlm_perl I don't like the rlm_exec option since it seems to have security issues (password is visible within the environment of the process) and might be slow since for every authentication the php-interpreter has to be started and a new oracle-database connection has to be created. But this is the easiest way to go. I don't like the rlm_perl option as well. I have never written a perl script, nor have I connected an oracle database from within a perl script. Performace would be a lot better since the perl-interpreter must not be started on every authentication. But it seems to me that maybe a database connection must be created on every authentication request. With oracle databases that is a lengthy process and takes more time than starting an interpreter.
1) if the password is wrong access should be denied So... password checking like normal. But if this is for passwords which change multiple times a day, then it just won't work.
see above - password is token generated but will not change until it expires
2) if the access point is not located in the office of the employee or in one of the conference rooms of the employees department access should be denied
So... check the source AP to see if it's allowed. How do you check that? Read the debug output to see what each AP sends, and then write rules to match those.
wether an accesspoint is allowed or not depends on the data within our central oracle database. If an employee moves to a new office (which happens a lot lately due to corona) our hotline changes the information within the oracle database. This should give the employee immediate access to the accesspoint in his new office without changing configuration data at additional places (neither manually nor automatically).
Our central oracle database has information about the ip-address and location of every access point and the office rooms of every employee. Location is irrelevant. The only thing that matters is what's in the RADIUS packets, and what's shown in the debug logs.
Does the term "Conference room 5" appear in the RADIUS packet? No? Then you'll have to figure out some other way which access point is which. Maybe by looking at host names (if they show up in the RADIUS packet), or IP addresses (if they should up in the RADIUS packet), or by MAC (well, you get the idea by now).
"Conference room 5" does not appear in the RADIUS packet but so does the IP-Adress of the accesspoint. And our central database has all the information that is needed to deduce the room number from that ip-address and wether the conference room belongs to the same department as the user.
My first idea was to write a php-script (because that's the scripting language I'm familiar with) and use that via rlm_exec. I will do this as a proof of concept. To do... what? You haven't said.
see above. The idea was to let the script verify the password and compare the physical location of the accesspoint with the office of the user, based on the information that the script got from the radius packet (username, password, ip-address).
Since neither I nor any of my colleagues have perl-experience I'd rather write a new module in C than use perl.
Is there a module that will send all parameters to a unix or inet socket and receives the results from that socket? How abount rlm_socket? To do... what?
How is any token going to be checked? REST API? What?
Your last comments here are really "how do I write a script to do stuff". The only answer is "I dunno, it depends on what stuff you want to do".
I'm not asking how a script should be written. This is our business and from Freeradiuses point of view it should make no difference wether the script uses a REST API to talk with our authentication server or connect an oracle database or do whatever is needed to allow or reject a request. My current understanding is that freeradius will feed a list of key-value pairs into such a script and will receive at least a status and maybe additional key-value pairs. Right now my plans are: 1: Create a php-script that will receive key-value data from Freeradius via evironment-variables and will return data via exit-code. This script has to create a database connection for every authentication request. This will be slow (approx 2 seconds) but my hope is, that Freeradius will start processes in parallel. 2: Create a perl-script with identical functionality. Maybe the first invocation of such a perl script can create a database connection that can be reused by future requests. That would improve performance. I have no idea wether Freeradiuses builtin perl-interpreter allows to store a database connection in a global variable and what happens if multiple invocations of such a perl sript are running in parallel. Any feedback on these ideas is welcome. Kind regard Peter
On Apr 21, 2021, at 7:38 AM, radius.pkoch@dfgh.net wrote:
We are planning to use our time-based one time password OATH tokens just in the same way we are already doing this for IMAP authentication. When a user authenticates for the first time, he must generate a 6digit value with his token, append his own password to that value and use that combination. The IMAP server (and I was hoping the radius server could do as well) will send the password to our authentication server for validation.
Mostly. It depends on a host of factors.
Once a password was used successfully, the same value can be used again for a certain period of time that depends on the username. With our IMAP-server this period is 30 days, for a WiFi-guest account this would be 12 hours.
As I said, that's likely a poor WiFi experience.
The passwords we generate with our OATH-token are not used as ONE time passwords. Hence they must be kept secret and must not be sent over the network in clear.
Which protocols send passwords over the network in the clear? Are you even sure you know what "in the clear" means? I suspect it doesn't mean what you think it means. We've had people worried about using TTLS + PAP, because it sends passwords "in the clear". This is despite the fact that TTLS uses TLS. So the passwords are secured "on the wire". Instead, all they see is PAP, and go "OMFG it's insecure!" Well, then logging into Google is insecure, because it *does* send passwords "in the clear" over an HTTPS connection.
In our case the radius server will get - among other informations - the username and password of the supplicant
Maybe. It depends on how the supplicant is configured. Again, you *cannot* just say "I want to do X". You *must* understand every bit of the process, down to supplicant configuration. Otherwise you will be unpleasantly surprised. For background, see: http://deployingradius.com/documents/protocols/compatibility.html That page has been explaining WiFi security issues to people for ~16 years. In many cases, the RADIUS server does NOT get a password. So what you want to do may very well be impossible, unless you change the supplicant configuration.
But the radius server cannot do this decision on its own. It cannot verify the password but has to delegate that decision.
How? That's what I was trying to get at when I asked "what does the script do". I don't mean that the answer should be "it delegates the decision to a script". I mean "what does the script do? What does it get as input? What steps does it take? What external systems does it check? How does it check external systems?"
And it cannot query our central oracle database on its own about what accesspoint has the given IP-address and wether this accesspoint is physically located in the office of the person with the given username.
Why? You later say that the script can query the Oracle database. So why can't FreeRADIUS query the Oracle database directly? The SQL module is capable of this.
I was hoping that the radius server could delegate this decisions to a script. And it seems to me, that there are (at least) the following two possibilities:
Those are solutions. You need a good problem statement first.
see above. The idea was to let the script verify the password and compare the physical location of the accesspoint with the office of the user, based on the information that the script got from the radius packet (username, password, ip-address).
Why not write those rules in FreeRADIUS? It will be simpler and faster.
I'm not asking how a script should be written. This is our business and from Freeradiuses point of view it should make no difference wether the script uses a REST API to talk with our authentication server or connect an oracle database or do whatever is needed to allow or reject a request.
You didn't understand my point. My point is that you need a *problem statement* before coming up with the solution. As in "I want to take X from the RADIUS packet, use it to do an SQL query for Y, and then compare X and Y. If they match, the user is allowed online". A large part of the contentious discussion on this list is people going "I want to know if I should use solution A or solution B", followed by me trying (in vain) to get them to explain what the underlying problem is. They get upset that I'm not helping them, and I get annoyed that they're ignoring my explicit requests for more information. I don't ask for more information because I'm trying to waste your time. I'm asking for more information because I need that information in order to help you. Replying with "I'm not asking how a script should be written. This is our business" is just unfriendly. I'm not asking you how the script should be written. I'm asking you "do you know what the script should do?". If you can't answer that question, then a statement of "FreeRADIUS calls the script via exec or Perl" is just not helpful. If you have a good problem description, then I can suggest a good solution. If you have just want to know "should I use exec or Perl", then I really can't help you. FreeRADIUS can do database queries. FreeRADIUS can do comparisons. FreeRADIUS can do if / then / else checks. The question for you is this: Do you want our help to create a solution? Or do you want to be told which of exec / Perl is better? Alan DeKok.
On 21/04/2021 13:44, Alan DeKok wrote:
Once a password was used successfully, the same value can be used again for a certain period of time that depends on the username. With our IMAP-server this period is 30 days, for a WiFi-guest account this would be 12 hours.
As I said, that's likely a poor WiFi experience.
Yeah, there's a few things here that sound bad from an experience view. Replace password every day. Likely nasty for anyone with a supplicant (so WPA-Enterprise). Configuring supplicants correctly can be difficult enough on its own, and they like to hold on to the password. Expect pain. It's different with the old web-redirect type login, but that's just nasty anyway (and less secure). Same experience having to re-login again, though - it's annoying. "Allowed to connect in their office and the conference room". Until their device holds on to the wifi connection in the next office down the corridor, is refused to connect, and dumps the wifi config because that SSID doesn't work any more. So they get prompted to log in again. Nasty experience, expect pain. Oh, you did that by changing passwords every day already. This seems to be the normal "let's lock everything down as much as possible" thought, which sounds good until people actually have to *use* it, then you just annoy your users. Visiting a colleague in their office to ask them a question? Uh oh, can't get on wifi any more, so have to use 4G to check up on whatever they need to. Just... ugh. How about an alternative - issue certificates to anyone allowed to use the network, permit people to connect anywhere and drop them into the correct VLAN so that they get access to the stuff they need?
And it cannot query our central oracle database on its own about what accesspoint has the given IP-address and wether this accesspoint is physically located in the office of the person with the given username.
Why? You later say that the script can query the Oracle database. So why can't FreeRADIUS query the Oracle database directly? The SQL module is capable of this.
Yeah. Don't think "I can write a script so let's get FreeRADIUS to run the script". Really we should put a big warning in all the language modules to *not* use them until no other method has proven workable. Query the database directly with rlm_sql and use unlang to do policy, unless there's a really good reason not to ("I don't know unlang" isn't a good reason).
If you have a good problem description, then I can suggest a good solution. If you have just want to know "should I use exec or Perl", then I really can't help you.
Neither :)
FreeRADIUS can do database queries. FreeRADIUS can do comparisons. FreeRADIUS can do if / then / else checks.
Exactly. In over 10 years doing FreeRADIUS I've never used any of the interpreted language modules, and the only times I've used rlm_exec we've hit performance problems. -- Matthew
On Apr 21, 2021, at 9:30 AM, Matthew Newton <mcn@freeradius.org> wrote:
How about an alternative - issue certificates to anyone allowed to use the network, permit people to connect anywhere and drop them into the correct VLAN so that they get access to the stuff they need?
That is exactly the solution which should be used. The difficulty with these kind of questions is that people are *extremely* stuck on a particular solution: They want to do X, and only X. No other solution is possible. It doesn't matter what the side effects are, or how complex it is. We have to do X. It's just frustrating for all parties. Alan DeKok.
Dear Alan, dear Matthew, first let me thank you for your replies. All your hints and informations are very valuable for me and far away from being frustrating. I'm trying not to waste your time. I would not dare to present a problem on this mailinglist without at least trying to figure out what a solution might be and give you a description of that "solution". That might have given you the impression that I'm already stuck with certain solutions (ie. rlm_perl vs. rlm_exec). I understand that you need precise information about what my problem is in order to point me into the 100% correct direction. But I don't know exactly what my problem is. Describing the problem seems to be part of the solution. So I will try to explain what I have understood so far. And I will try to reformulate my problem. What I have learned so far is: The rlm_sql module does not only read user-information from certain SQL-tables and store account information into other SQL-tables, but loading this model enables %{sql:select ....} variable expansions in the rlm_expr module. I wasn't aware of this functionality of rlm_sql and since the select-statement in %{sql:....} can fetch data from any table or view I can easily select both the room number of User-Name and the room number of %{Packet-SRC-IP-Address}. I tried that today and created file policy.d/check_rooms with content check_rooms { update request { &Tmp-Integer-0 = "%{sql:select nmi_nra_id from nav_mitarbeiter where nmi_kuerzel='%{User-Name}'}" &Tmp-String-0 = "%{sql:select nra_name from nav_raeume where nra_id=%{Tmp-Integer-0}}" &Tmp-Integer-1 = "%{sql:select egr.nra_id(egr_id) from edv_geraete where egr.ip_adresse(egr_id,7)='%{Packet-SRC-IP-Address}'}" &Tmp-String-1 = "%{sql:select nra_name from nav_raeume where nra_id=%{Tmp-Integer-1}}" } } Since the decision wether an accesspoint with a certain IP-address is located in the office of a user or not is completly based on information within our oracle database, I felt that instead of fetching multiple pieces of data from the database and then compare that with Unlang in FreeRadius, this logic should be better placed within the database. By the way - this is what I ment when I mentioned that it's "our business how this decision has to be taken". Sorry, if that sounded unfriendly. Hence I created an oracle database function check_rooms(user, ip) that does everything and my check_rooms policy now is just a one-liner. Tmp-String-0 will have either value "OK" or an error-message or will be empty if something went wrong within the database. And I extended this function so it takes care of our conference-rooms as well. check_rooms { update request { &Tmp-String-0 = "%{sql:select egr.check_rooms('%{User-Name}','%{Packet-SRC-IP-Address}') from dual}" } } I still have to figure out how to reject the request if Tmp-String-0 is not "OK". There are enough examples so I can figure that out on my own. I was unsure about where to place the check_rooms statement. My first try was at the beginning of the authorize section of default. But then freeradius would talk to the database on every packet during eap-tunnel-setup. I therefore moved check_rooms to inner-tunnel and placed it just before "files". So my problem "How do I restrict WiFi access to certain offices" seems to be solved. But you pointed me at a different problem, namely "How do I force our employees to use their OATH TOTP-token as a second factor when they authenticate against a WiFi accesspoint" I would appreciate your help with this problem very much. Here are some additional informations about the problem: - we are running an authentication server, that may verify a token values - the authentication server has - among others - a REST interface - the authentication server caches successful results for a certain period of time, so valid token-values can be reused - doing two-factor authentication is part of our security policy, using certificates will fullfill this requirement only if the private key of the certificate was created within a smart card It won't surprise you that I have already tried to figure out, what a solution might be. Since my original idea (i.e. delegating the validation of the password to a script via either rlm_exec or rlm_perl) was absolutely unrealistic, I spare you what I have in mind, now that I have realized that passwords are contained in radius packets in clear only when sent with radtest, but are missing, when eap is used. Let me know I you need more information (or have better things to do than free FreeRadius consulting for dummies :-) ) Kind regards Peter Am 20.04.2021 um 21:46 schrieb Alan DeKok - aland@deployingradius.com:
On Apr 20, 2021, at 1:04 PM, radius.pkoch@dfgh.net wrote:
I have just compiled Freeradius from source and red some of the documentation. WPA2-EAP works with username bob and password hello. radiusd -X shows no errors. That's good.
Now here's what I would like to achive and maybe some of you can point me into the right direction:
We have equipped all of our offices (approx 100) with seperate WLAN access points. Every employee should be able to access the access point in its own office and in some of our conference rooms. Every employee owns an OAuth token that generates a 6digit one time password. That's nice, but you really don't want to use OAuth with Wifi. I don't even know how that would work.
i.e. WiFi is bad enough that devices end up re-authenticating multiple times a day. And you definitely don't want users to be asked 5-10 times a day for a new one-time password.
Just use a password. Or, use EAP-TLS and client certificates.
We are planning to use our time-based one time password OATH tokens just in the same way we are already doing this for IMAP authentication. When a user authenticates for the first time, he must generate a 6digit value with his token, append his own password to that value and use that combination. The IMAP server (and I was hoping the radius server could do as well) will send the password to our authentication server for validation. We do not use OAuth. Once a password was used successfully, the same value can be used again for a certain period of time that depends on the username. With our IMAP-server this period is 30 days, for a WiFi-guest account this would be 12 hours. The passwords we generate with our OATH-token are not used as ONE time passwords. Hence they must be kept secret and must not be sent over the network in clear.
Whenever a user tries to access a WLAN access point with his username and his one time password the following should happen: Scratch all that.
First, you should figure out how WiFi works. Then, figure out if your suggested process fits into that.
If it doesn't, throw away your requirements about what "should happen", and go with something which is realistic.
So here's what I figured out so far about how WiFi works: - accesspoint is configured for WPA-Enterprise - hence the supplicant is asked for a user / password combination or has to provide a client certificate - the accesspoint receives additional informations from the supplicant (i.e. its mac-address) - the accesspoint sends all the information it has received from the supplicant together with informations about itself to the radius server - the radius server decides wether to allow or deny access and answers the request In our case the radius server will get - among other informations - the username and password of the supplicant plus the IP-address of the accesspoint. This is all that is needed to decide wether the password is correct and wether the accesspoint is located within the office of the person with the given username. But the radius server cannot do this decision on its own. It cannot verify the password but has to delegate that decision. And it cannot query our central oracle database on its own about what accesspoint has the given IP-address and wether this accesspoint is physically located in the office of the person with the given username. I was hoping that the radius server could delegate this decisions to a script. And it seems to me, that there are (at least) the following two possibilities: - use a php-script via rlm_exec - use a perl-script via rlm_perl I don't like the rlm_exec option since it seems to have security issues (password is visible within the environment of the process) and might be slow since for every authentication the php-interpreter has to be started and a new oracle-database connection has to be created. But this is the easiest way to go. I don't like the rlm_perl option as well. I have never written a perl script, nor have I connected an oracle database from within a perl script. Performace would be a lot better since the perl-interpreter must not be started on every authentication. But it seems to me that maybe a database connection must be created on every authentication request. With oracle databases that is a lengthy process and takes more time than starting an interpreter.
1) if the password is wrong access should be denied So... password checking like normal. But if this is for passwords which change multiple times a day, then it just won't work.
see above - password is token generated but will not change until it expires
2) if the access point is not located in the office of the employee or in one of the conference rooms of the employees department access should be denied
So... check the source AP to see if it's allowed. How do you check that? Read the debug output to see what each AP sends, and then write rules to match those.
wether an accesspoint is allowed or not depends on the data within our central oracle database. If an employee moves to a new office (which happens a lot lately due to corona) our hotline changes the information within the oracle database. This should give the employee immediate access to the accesspoint in his new office without changing configuration data at additional places (neither manually nor automatically).
Our central oracle database has information about the ip-address and location of every access point and the office rooms of every employee. Location is irrelevant. The only thing that matters is what's in the RADIUS packets, and what's shown in the debug logs.
Does the term "Conference room 5" appear in the RADIUS packet? No? Then you'll have to figure out some other way which access point is which. Maybe by looking at host names (if they show up in the RADIUS packet), or IP addresses (if they should up in the RADIUS packet), or by MAC (well, you get the idea by now).
"Conference room 5" does not appear in the RADIUS packet but so does the IP-Adress of the accesspoint. And our central database has all the information that is needed to deduce the room number from that ip-address and wether the conference room belongs to the same department as the user.
My first idea was to write a php-script (because that's the scripting language I'm familiar with) and use that via rlm_exec. I will do this as a proof of concept. To do... what? You haven't said.
see above. The idea was to let the script verify the password and compare the physical location of the accesspoint with the office of the user, based on the information that the script got from the radius packet (username, password, ip-address).
Since neither I nor any of my colleagues have perl-experience I'd rather write a new module in C than use perl.
Is there a module that will send all parameters to a unix or inet socket and receives the results from that socket? How abount rlm_socket? To do... what?
How is any token going to be checked? REST API? What?
Your last comments here are really "how do I write a script to do stuff". The only answer is "I dunno, it depends on what stuff you want to do".
I'm not asking how a script should be written. This is our business and from Freeradiuses point of view it should make no difference wether the script uses a REST API to talk with our authentication server or connect an oracle database or do whatever is needed to allow or reject a request. My current understanding is that freeradius will feed a list of key-value pairs into such a script and will receive at least a status and maybe additional key-value pairs. Right now my plans are: 1: Create a php-script that will receive key-value data from Freeradius via evironment-variables and will return data via exit-code. This script has to create a database connection for every authentication request. This will be slow (approx 2 seconds) but my hope is, that Freeradius will start processes in parallel. 2: Create a perl-script with identical functionality. Maybe the first invocation of such a perl script can create a database connection that can be reused by future requests. That would improve performance. I have no idea wether Freeradiuses builtin perl-interpreter allows to store a database connection in a global variable and what happens if multiple invocations of such a perl sript are running in parallel. Any feedback on these ideas is welcome. Kind regard Peter
On Apr 22, 2021, at 2:11 PM, radius.pkoch@dfgh.net wrote:
I understand that you need precise information about what my problem is in order to point me into the 100% correct direction. But I don't know exactly what my problem is. Describing the problem seems to be part of the solution.
You know that location-specific and time-specific passwords give a very bad experience. So you should drop that. For OTP authentication, you know you have a 6-digit token. You know you have some API to check that. You haven't said *what* that API is. We've asked...
The rlm_sql module does not only read user-information from certain SQL-tables and store account information into other SQL-tables, but loading this model enables %{sql:select ....} variable expansions in the rlm_expr module. I wasn't aware of this functionality of rlm_sql and since the select-statement in %{sql:....} can fetch data from any table or view I can easily select both the room number of User-Name and the room number of %{Packet-SRC-IP-Address}.
Yes.
I tried that today and created file policy.d/check_rooms with content
check_rooms { update request { &Tmp-Integer-0 = "%{sql:select nmi_nra_id from nav_mitarbeiter where nmi_kuerzel='%{User-Name}'}" &Tmp-String-0 = "%{sql:select nra_name from nav_raeume where nra_id=%{Tmp-Integer-0}}" &Tmp-Integer-1 = "%{sql:select egr.nra_id(egr_id) from edv_geraete where egr.ip_adresse(egr_id,7)='%{Packet-SRC-IP-Address}'}" &Tmp-String-1 = "%{sql:select nra_name from nav_raeume where nra_id=%{Tmp-Integer-1}}" } }
Since the decision wether an accesspoint with a certain IP-address is located in the office of a user or not is completly based on information within our oracle database, I felt that instead of fetching multiple pieces of data from the database and then compare that with Unlang in FreeRadius, this logic should be better placed within the database. By the way - this is what I ment when I mentioned that it's "our business how this decision has to be taken". Sorry, if that sounded unfriendly.
It's your *decision* to put logic in one place or another. If I ask "what does the logic do", I don't expect to get an answer which comes across as "none of your business".
Hence I created an oracle database function check_rooms(user, ip) that does everything and my check_rooms policy now is just a one-liner. Tmp-String-0 will have either value "OK" or an error-message or will be empty if something went wrong within the database. And I extended this function so it takes care of our conference-rooms as well.
That's good.
check_rooms { update request { &Tmp-String-0 = "%{sql:select egr.check_rooms('%{User-Name}','%{Packet-SRC-IP-Address}') from dual}" } }
I still have to figure out how to reject the request if Tmp-String-0 is not "OK". There are enough examples so I can figure that out on my own.
Do this: if ("%{sql:select egr.check_rooms('%{User-Name}','%{Packet-SRC-IP-Address}') from dual}" != "ok") { reject } It's that easy.
But you pointed me at a different problem, namely "How do I force our employees to use their OATH TOTP-token as a second factor when they authenticate against a WiFi accesspoint"
The answer is pretty much "you don't, it's a terrible idea. It will annoy your uses to no end".
- we are running an authentication server, that may verify a token values - the authentication server has - among others - a REST interface - the authentication server caches successful results for a certain period of time, so valid token-values can be reused - doing two-factor authentication is part of our security policy, using certificates will fullfill this requirement only if the private key of the certificate was created within a smart card
It won't surprise you that I have already tried to figure out, what a solution might be. Since my original idea (i.e. delegating the validation of the password to a script via either rlm_exec or rlm_perl) was absolutely unrealistic, I spare you what I have in mind, now that I have realized that passwords are contained in radius packets in clear only when sent with radtest, but are missing, when eap is used.
You didn't read the web page I pointed you to about protocol and password compatibility. You're not reading the debug output. You didn't pay attention when I said you would need to change the supplicant configuration. The passwords are not "missing" when EAP is used. The users *credentials* come across as MS-CHAP, or PAP, or CHAP, or ... many other forms. Only one of those sends a clear-text password. Only the clear-text password will work with OTP systems. What you are trying to do is likely (a) horrifically frustrating for end users, and/or (b) impossible to implement. Stop trying to force a solution. Instead, make sure you understand what is going on. WHAT do you see when EAP is used? Is that compatible with OTP? Can you change the supplicant configuration to send clear-text passwords? You're still stuck on a particular set of requirements. We know you're trying to do OTP. We're trying to convince you that you need to understand more about the system before deciding if the solution will work. You can't just say "passwords are missing when EAP is used". You have to understand WHY they're "missing". Otherwise you're randomly changing configuration options, hoping that one will magically fix the problem. This is very much not an efficient approach. Alan DeKok.
Dear Alan thanks very much again for your last reply. It contained almost everyhing I needed to solve my problem. I feel I must emphazise that FreeRadius is free software at its best: Very easy installation. Whatever a Radius Server might be able to do - FreeRadius can do it. If one needs 100% precice information about what's going on, the source code will show you. It even has functionality that I did not expect. For example beeing a DHCP-server that reads its configuration data dynamically from an SQL database. Or OTP-support via a an easy to use interface. With all that functionality I would not wonder if FreeRadius-configuration was very time-consuming. But it isn't and the default configration supports most use cases out of the box. Very impressive! And - most remarkable - your are giving excellent free (in the sense of free beer) support on this mailing lists. Even to people like me that have crude requirements. Be assured that I have read all the informationen you mentioned (including compatibility.html and every single line of dozens of radiusd -X outputs) and they were very helpful. I even like the tone on this list and the information about it on the registration page. As the subject of this thread is "allow WLAN-access in certain offices only" and this problem is already solved by clever using he SQL-capabilities of FreeRadius, I will explain the way I found to support our OTP-token in a new thread. You pointed out that using location-specific and time-specific passwords give a very bad experience and that forcing users to use OTP-token is a terrible idea. If you or anybody else is interested to know why I believe that this nevertheless improves our situation - just let me know. That might give an interesting discussion. I'm just not sure wether you like to have such discussions on the FreeRadius mailing list. Keep the good work going Peter
On Apr 28, 2021, at 3:31 AM, radius.pkoch@dfgh.net wrote:
thanks very much again for your last reply. It contained almost everyhing I needed to solve my problem.
That's good.
I feel I must emphazise that FreeRadius is free software at its best: Very easy installation. Whatever a Radius Server might be able to do - FreeRadius can do it. If one needs 100% precice information about what's going on, the source code will show you. It even has functionality that I did not expect. For example beeing a DHCP-server that reads its configuration data dynamically from an SQL database. Or OTP-support via a an easy to use interface. With all that functionality I would not wonder if FreeRadius-configuration was very time-consuming. But it isn't and the default configration supports most use cases out of the box. Very impressive!
Thanks.
And - most remarkable - your are giving excellent free (in the sense of free beer) support on this mailing lists. Even to people like me that have crude requirements. Be assured that I have read all the informationen you mentioned (including compatibility.html and every single line of dozens of radiusd -X outputs) and they were very helpful.
I even like the tone on this list and the information about it on the registration page.
We try to be polite, but straightforward.
As the subject of this thread is "allow WLAN-access in certain offices only" and this problem is already solved by clever using he SQL-capabilities of FreeRadius, I will explain the way I found to support our OTP-token in a new thread.
You pointed out that using location-specific and time-specific passwords give a very bad experience and that forcing users to use OTP-token is a terrible idea. If you or anybody else is interested to know why I believe that this nevertheless improves our situation - just let me know. That might give an interesting discussion. I'm just not sure wether you like to have such discussions on the FreeRadius mailing list.
Sure. I'd be interested in knowing what the user experience is like.
Keep the good work going
Thanks. Alan DeKok.
participants (3)
-
Alan DeKok -
Matthew Newton -
radius.pkoch@dfgh.net