User authentication for remote NAS'?
Hi, I'm completely new to Freeradius and mysql and have been playing around with it for the past couple of weeks. A lot of fun but also a bit frustrating at times. So far I've managed to get Freeradius and mysql working. I can even authenticate users and send back attributes to them to limit time online, link speed etc. This part I've got working. However one thing I'm totally unable to figure out is how I can base authentication on which NAS a user is trying to log in from. I've been reading the mailing lists, googling, and there are people with similar questions but I've yet to find an answer. Hopefully somebody can give me some pointers :) Goal: Have multiple NAS' in remote locations authenticate with a central Freeradius server. The NAS' will be in remote locations, I won't always know the IP and in some cases they will be using the same IP as they are behind a private network. Setting up radius proxies at the remote locations is not an option. I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that? My non-programmer-way-of-thinking Freeradius receives request from NAS NAS request includes NAS-ID Freeradius somehow checks if NAS-ID is present in mysql table If not present -> Reject request If present -> check usergroup that corresponds with the NAS-ID and authenticate against the users in that group. Very simple minded I thought that it might be as simple as modifying the hunt group tutorial on the wiki by replacing the nas-ip with nas-id but that didn't work. After some more reading all the mailing list entries tell me the wiki is wrong and won't work. Right now I'm at a loss and don't know what to do. The mailing list is my last resort. I would like to know if A) its possible to use anything other than the IP to identify the NAS and B) How would I go about achieving that? By the way, if I ever get this working, can I write a guide and submit it to the wiki? Freeradius version 2.2.8 Freeradius -X: None as I don't think that'll answer my question at this point ;) Thanks.
On 30/03/2017 03:15, wefwe fewfew wrote:
However one thing I'm totally unable to figure out is how I can base authentication on which NAS a user is trying to log in from.
I've been reading the mailing lists, googling, and there are people with similar questions but I've yet to find an answer. Hopefully somebody can give me some pointers:)
Goal:
Have multiple NAS' in remote locations authenticate with a central Freeradius server.
The NAS' will be in remote locations, I won't always know the IP and in some cases they will be using the same IP as they are behind a private network. Setting up radius proxies at the remote locations is not an option.
I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that?
I presume you're talking about the NAS-Identifier attribute. If your NAS can be configured to send this, and allows you to set a unique value for each NAS, that's the right way to do what you want. (Often you'd use the NAS-IP-Address attribute instead, but that won't work for you if multiple NASes have the same local IP address) Once you've got an attribute in the incoming request which identifies the NAS, then it's relatively straightforward to do what you want. To start with, you can use unlang in a policy module: e.g. if (&SQL-Group[*] == "staff" && &NAS-Identifier =~ /^(foo|bar)$/) { ... } [Aside: the [*] is there to allow the user to have multiple SQL-Group attributes, and to match if any of them is "staff"] But in practice, you probably want to map a bunch of different NAS-Identifiers to some sort of group attribute so you can create a policy which says "when user is in group X and NAS is in group Y then do Z" There are various ways you could lookup NAS-Identifier to set some group attribute. To do this in SQL, you'd need to create a new instance of the "sql" module, keyed by NAS-Identifier rather than User-Name, and using a different set of tables: sql sql_nas { sql_user_name = "%{NAS-Identifier}" group_attribute = "NAS-SQL-Group" ... also configure to point to a different set of tables } In your authorize { } section you would invoke both "sql" and "sql_nas" modules. The first looks up the username, and the second looks up the NAS-Identifier. Then you can have policy logic like: if (&SQL-Group[*] == "staff" && &NAS-SQL-Group[*] == "dialup") { ... } (Warning: all examples untested) If this is too complicated, then there is another brute-force way you can consider: set up a bunch of radius virtual servers listening on different ports, one for each type of NAS access policy. Then configure each NAS to point to the correct port. HTH, Brian.
On Thu, Mar 30, 2017 at 02:15:20AM +0000, wefwe fewfew wrote:
I'm completely new to Freeradius and mysql and have been playing around with it for the past couple of weeks. A lot of fun but also a bit frustrating at times.
It's very flexible, but therefore can also be complicated, with a steep learning curve. But start small and don't go too fast with learning.
The NAS' will be in remote locations, I won't always know the IP and in some cases they will be using the same IP as they are behind a private network. Setting up radius proxies at the remote locations is not an option.
Doing RADIUS behind NAT is not a good idea and will likely cause you problems. How to identify the client is one of them that you've hit.
I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that?
Yes, but you can't necessarily trust it, being an attribute the RADIUS client can change it. You normally have several options: Key off NAS-Identifier, NAS-IP or Called-Station-Id. Key off the virtual attribute Packet-Src-IP-Address, which you can trust (it's the source IP of the packet). Add another config setting to the client definition, e.g. client x { ... mygroupname = something } and refer to it in the config with %{client:mygroupname}. The latter two are better, but will break with NAT as you'll be using the same client entry for multiple RADIUS servers. The latter two are best, but will break with NAT.
Very simple minded I thought that it might be as simple as modifying the hunt group tutorial on the wiki by replacing the nas-ip with nas-id but that didn't work. After some more reading all the mailing list entries tell me the wiki is wrong and won't work.
Unlang is preferable over huntgroups.
I would like to know if A) its possible to use anything other than the IP to identify the NAS and B) How would I go about achieving that?
a) Not really with NAT b) don't use NAT, or at least have a RADIUS proxy.
Freeradius version 2.2.8
3.0.13 is recommended, version 2 is obsolete now. Matthew -- Matthew Newton, Ph.D. <mcn4@leicester.ac.uk> Systems Specialist, Infrastructure Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
On Mar 29, 2017, at 10:15 PM, wefwe fewfew <totallimpbizkit@hotmail.com> wrote:
I'm completely new to Freeradius and mysql and have been playing around with it for the past couple of weeks. A lot of fun but also a bit frustrating at times.
Everything is documented, and the debug output is without equal. Just try debugging rules in Apache, nginx, postfix, or any other networking daemon. The most common message is "Error", which is entirely useless. If you find it frustrating, it would be good to describe what's missing in the documentation, so that other people don't run into the same issues. But my $0.02 is that the largest source of frustration is a general lack of knowledge about how RADIUS works. Which is why I wrote the technical guide available on networkradius.com.
I've been reading the mailing lists, googling, and there are people with similar questions but I've yet to find an answer. Hopefully somebody can give me some pointers :)
The documentation that comes with the server describes this in detail. Just read clients.conf, or raddb/sites-available/README There seems to be a general belief that a pice of software just can't possibly come with documentation or configuration examples that make sense. Instead, the goal should be to just google things, and hope some random third-party page has what you're looking for. Please don't do that. It's a waste of time.
Have multiple NAS' in remote locations authenticate with a central Freeradius server.
See clients.conf. Clients are defined by IP address. There is nothing which suggests you can do anything else.
The NAS' will be in remote locations, I won't always know the IP and in some cases they will be using the same IP as they are behind a private network. Setting up radius proxies at the remote locations is not an option.
RADIUS works by keying off of the source IP address. If the NASes are behind NATs and you can't install local proxies... you can't do RADIUS as it was designed. The only other option is to use the same IP address for a network. Again, see clients.conf for how to specify a mask (e.g. 192.168.0.0/16)
I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that?
It's not possible.
Right now I'm at a loss and don't know what to do. The mailing list is my last resort.
The mailing list should be your first resort. Or maybe second after reading the docs included with FreeRADIUS.
I would like to know if A) its possible to use anything other than the IP to identify the NAS and B) How would I go about achieving that?
It's not possible.
By the way, if I ever get this working, can I write a guide and submit it to the wiki?
Since it's not possible, no, sorry.
Freeradius version 2.2.8
Please upgrade to v3. It's just so much better. Alan DeKok.
On 30/03/2017 13:44, Alan DeKok wrote:
I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that? It's not possible.
If you have multiple NASes behind a NAT, then obviously you can't have different shared secrets for each one, but I don't think that's what the OP was asking. The question was "how I can base authentication on which NAS a user is trying to log in from?", which I took to mean "how can I make the authentication response vary depending on which NAS originated the radius request?" It is clearly possible to use NAS-Identifier for that purpose. Given the constraints in the original question, it seems like a reasonable solution to me. Regards, Brian.
On Mar 30, 2017, at 9:20 AM, Brian Candler <b.candler@pobox.com> wrote:
On 30/03/2017 13:44, Alan DeKok wrote:
I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that? It's not possible.
If you have multiple NASes behind a NAT, then obviously you can't have different shared secrets for each one, but I don't think that's what the OP was asking.
He was pretty clear that he had multiple NASes behind NAT gateways. That just doesn't work. I suspect he was trying to authenticate the *NAS*, not the user. But the question was unclear. Alan DeKok.
Hi guys, Thanks for the feedback. I went with Brian's advise and started small. By adding the NAS-ID attribute to the user I can limit access from a certain ID regardless of the IP in my test setup. This is not how I eventually want it to be but it will do for now. Second problem I'm running into is accounting. I have no idea how get this to work. I thought it would be fairly straight forward to have freeradius check daily/weekly/monthly/total time online/data used and allow/disconnect a user based on that. I've looked at this guy's guide, seems he also asked a bit on the mailing list. https://aacable.wordpress.com/2016/03/25/mikrotik-with-freeradiusmysql-chang... But I can't get the data usage part to work. I sent to total limit attribute as supported by my NAS (mikrotik) which works fine on a per sessions basis but not when disconnecting. Even if I could get it to work, does COA really require a IP to be set or can I use a variable as well? The NAS IP will be dynamic. I tried setting variables but that gave an error about being unable to send a request to the NAS port (even though it gave the right IP. I don't have access to my test setup right now so I'll send the log output later). The biggest problem I'm having is with the documentation. All information is spread over the Internet over the past decade with bits and pieces everywhere but nowhere there is documentation that tells you though from all the question asked online it seems like a lot of users have problems with it. Long story short is that I want FR/mysql to check how long a user is still allowed online or how much bandwidth he has left and reject access/disconnect a user based on that. ________________________________ From: Freeradius-Users <freeradius-users-bounces+totallimpbizkit=hotmail.com@lists.freeradius.org> on behalf of Alan DeKok <aland@deployingradius.com> Sent: Thursday, March 30, 2017 2:04:07 PM To: FreeRadius users mailing list Subject: Re: User authentication for remote NAS'? On Mar 30, 2017, at 9:20 AM, Brian Candler <b.candler@pobox.com> wrote:
On 30/03/2017 13:44, Alan DeKok wrote:
I was thinking about using the NAS-ID or called-station-id to authenticate instead. The NAS-ID is in the rad_recv request so I'm figuring somehow it must be possible to use that? It's not possible.
If you have multiple NASes behind a NAT, then obviously you can't have different shared secrets for each one, but I don't think that's what the OP was asking.
He was pretty clear that he had multiple NASes behind NAT gateways. That just doesn't work. I suspect he was trying to authenticate the *NAS*, not the user. But the question was unclear. Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On 03/04/2017 09:52, wefwe fewfew wrote:
Long story short is that I want FR/mysql to check how long a user is still allowed online or how much bandwidth he has left and reject access/disconnect a user based on that.
If you can *pre-calculate* this at the time the user connects, then you may be able to set an attribute at the start of the session and let the NAS kick them off when it's exceeded. Session-Timeout is a standard attribute and gives the time limit (in seconds). But that's not what you want. For limiting the bytes uploaded/downloaded, then it's entirely vendor specific. I notice in dictionary.mikrotik you'll find: ATTRIBUTE Mikrotik-Recv-Limit 1 integer ATTRIBUTE Mikrotik-Xmit-Limit 2 integer ATTRIBUTE Mikrotik-Recv-Limit-Gigawords 14 integer ATTRIBUTE Mikrotik-Xmit-Limit-Gigawords 15 integer ATTRIBUTE Mikrotik-Total-Limit 17 integer ATTRIBUTE Mikrotik-Total-Limit-Gigawords 18 integer (An integer is a 32-bit value, so if you want to give a value greater than 4GB you'll have to split it a 64-bit value into high and low 32-bit words, and use Gigawords for the high value. See RFC2869) So maybe that will do what you want. You could check at authentication time what their monthly limit is (say 40GB) and how much they've used so far this month (say 10GB), and then set the limit to 30GB. Otherwise, you'll have to run a process which periodically checks how much data a user has consumed, and tell the NAS interactively to kick them off. That again is very NAS-specific. Some NASes support a CoA packet for this; some NASes support an SNMP SET to do this; others you may need to script a login to the CLI and issue a command to kick them off. Sorry, I can't give you an off-the-shelf recipe to do this for Mikrotik, as I've never used their gear. FreeRADIUS can happily accumulate the accounting information into a database, to give you the source of info you need. (If you have a huge number of users then it might be an idea to use something like a Redis database instead of SQL) You will however want to ensure that you get accounting updates during a long-lived session, rather than waiting until the user disconnects which is the default. The way to do this is by including the Acct-Interim-Interval attribute in the authentication response: e.g. Acct-Interim-Interval = 600 This means "send me an update of usage for this session every 10 minutes". Most NASes won't let you set it lower than 5 or 10 minutes. For an ISP network I'd probably set it to 2 hours. HTH, Brian.
participants (4)
-
Alan DeKok -
Brian Candler -
Matthew Newton -
wefwe fewfew