"authorize" etc. in v3.1
The “authorize”, etc. sections are increasingly mis-named. After some discussion with Arran, we’ve come up with what seems like a better approach. I’d like to get other peoples feedback on the suggested design. The idea is to get rid of the randomly named “authorize”, “authenticate”, etc. sections. Instead, we will have a standard set of names. These names are predictable, which is good. The new names can be mapped (hand-waving here) to the old methods, so upgrading from 3.0 to 3.1 won’t require major changes to the config. The idea is to use the following naming scheme: recv foo — run this section when receiving a packet “foo”. process foo - run this section to process a packet “foo” send foo - run this section before sending a packet “foo” The mapping between the new types and old is as follows: recv Access-Request == authorize process Access-Request == authenticate (mostly) send Access-Accept == post-auth send Access-Challenge == no matching section send Access-Reject == Post-Auth-Type Reject recv Accounting-Request == preacct process Accounting-Request == accounting send Accounting-Request == no matching section For proxying, we no longer have pre-proxy and post-proxy, instead we have: send Access-Request == pre-proxy recv Access-Accept == post-proxy recv Access-Reject == post-proxy (oops, that’s probably not a good idea) recv Access-Challenge == post-proxy (oops again) send Accounting-Request = pre-proxy recv Accounting-Reply == post-proxy This suggestion isn’t entirely perfect. The “authenticate” section is really a wrapper for each Auth-Type section. We need to find a way to address that. There’s also the Autz-Type section, which exists, but is very weird. Can it just go away? Does anyone use it? There’s also the “session” section. It doesn’t match the above naming scheme. Maybe we need something else? And what about fail and timeouts? e.g. “no reply to proxied request” should probably be: timeout Access-Request ??? Or “no live home server” could be: fail Access-Request? I’m leaning towards that method, instead of the existing Post-Proxy-Type Fail, etc. That method is confusing for end users, and hard to code. e.g. Why is “fail” inside of post-proxy? Is Post-Proxy-Type Fail run for normal proxying, because it’s inside of the post-proxy section? It not, why not? These things are hard to explain. If, instead, we had consistent names, it becomes trivial to know what to do. It becomes trivial to know what the names are, and what each section does. I *believe* we can set up aliases, etc. which will map the new method to the old one. So no one has to butcher their configuration for 3.1. BUT the benefit of using the new naming scheme is legion. The code becomes MUCH simpler, as does the configuration. Comments? Stones? Alan DeKok.
Hi, I understand some of the concepts and ideas of why the current naming is 'wrong' but I dont like this current proposed idea yes, not useful but thats my initial feedback. I cannot see this proposal lowering the skills-gap/helping the tpical FR admin from getting on board..I see it more of a way of making the server more complex for the admin (but easier for the coder). YMMV. ...I'll see if I can spend any time to actually submit more useful ideas for you :-) (and that isnt going to be an XML-ised config using a python mini-OS to drive the show and create live binary configs! ;-) ) alan
On Mar 9, 2015, at 4:37 PM, A.L.M.Buxey@lboro.ac.uk wrote:
I cannot see this proposal lowering the skills-gap/helping the tpical FR admin from getting on board..I see it more of a way of making the server more complex for the admin (but easier for the coder). YMMV.
It’s about making it easier to understand how the server works. What does Post-Proxy-Type Foo do? Why? Arran and I discussed ways of doing this which don’t require changes to the existing configuration. i.e. the default mapping could be internal, and no one need ever see it. BUT is you want a simpler configuration, update the config to over-ride the default mapping, and *poof*. Everything becomes better.
...I'll see if I can spend any time to actually submit more useful ideas for you :-)
The goal is to simplify the current problems. Alan DeKok.
On Mon, Mar 09, 2015 at 04:26:09PM -0400, Alan DeKok wrote:
The “authorize”, etc. sections are increasingly mis-named. After some discussion with Arran, we’ve come up with what seems like a better approach. I’d like to get other peoples feedback on the suggested design.
Totally agreed on the sections being mis-named. In the AAA sense, "authorize" should really be called "pre-auth" as it's preparing for authentication, then there's "authenticate" (OK), then post-auth should be "authorize". But changing to this scheme would be incredibly confusing.
The idea is to use the following naming scheme:
recv foo — run this section when receiving a packet “foo”. process foo - run this section to process a packet “foo” send foo - run this section before sending a packet “foo”
The coder part of me says "yes". The sysadmin part says "when I was learning RADIUS, it was hard enough to work out what was happening, let alone know what each packet did on the network, so no". The idea is great, but I'm not sure that the naming will be any more helpful for those not well versed in RADIUS (and it's obvious from the list that there are many people in this situation; that's just a fact of life, many probable only run the RADIUS server as a part time thing). However, it _might_ be very powerful and work with some sort of templating or aliasing feature. This is completely off the top of my head, but maybe something like radius.conf: aliases { "select-auth-type" = "receive Access-Request" "authenticate-user" = "process Access-Request" "authorize-user" = "send Access-Accept" "process-failure" = "send Acecss-Reject" ... } select-auth-type { ... eap files ... } etc This would also mean that a more advanced admin could quite happily write send Access-Challenge { ... } which doesn't appear at all in the default configuration, but could be useful in some circumstances. You could also have for example: sent Access-Accept { } which gets called only after the packet has actually been sent, for final logging. Again, probably not in the default config (or aliased as "log-successful-authentication" maybe).
process Access-Request == authenticate (mostly)
I'm not sure that the current config is helpful. It's quite confusing to work out which sections have sub-sections called automatically, or at least it was when still on the learning curve. So authenticate { Auth-Type PAP { ... } Auth-Type eap { ... } } always seems odd. However post-auth { ... Post-Auth-Type REJECT { ... } } seems even weirder, inconsistent even. Two ideas come to mind. The first is adding a parameter to the section name, such as (in current config terminology): authenticate PAP { pap } authenticate eap { eap } mutiple levels, but much clearer IMO. The other, slightly less clear way is pull the hidden switch out into the open: authenticat { switch (Auth-Type) { PAP { pap } eap { eap } ... } } At least that would be clearer, but goes more towards the programming side which I don't think is great for newcomers. Personally I think I'd prefer the first - just a separate authenticate (or process Access-Request) section for each Auth-Type. process Access-Request PAP { ... } etc. [possibly even "process Auth-Type PAP" ??? doesn't fit the model, but reads easier for the admin :-S ]
recv Access-Accept == post-proxy
recv Access-Reject == post-proxy (oops, that’s probably not a good idea)
recv Access-Challenge == post-proxy (oops again)
post-proxy (Post-Proxy-Type Fail) and post-auth (Post-Auth-Type Fail) are already messy IMO, so this might help sort them out.
This suggestion isn’t entirely perfect. The “authenticate” section is really a wrapper for each Auth-Type section. We need to find a way to address that.
Yeah.
There’s also the Autz-Type section, which exists, but is very weird. Can it just go away? Does anyone use it?
I'd suggest scrapping it, but then provide a module that can just call another virtual server. Then it can be rebuilt as current if needed. Or extended further. Got the beginnings of a module that does that already somewhere in my git repo, but can't remember how far I got with it. Isn't a hard module to write.
There’s also the “session” section. It doesn’t match the above naming scheme. Maybe we need something else?
Session is another one of those sections that seems odd to me. Why not just do the simultaneous checks in the authorize/post-auth sections? Though I may not understand it entirely as I don't use it. These days I'm sure it can be replicated easily in unlang; just lookup the unique key (username etc) in a database and send reject if they're already there. accounting{} should keep the database up-to-date.
And what about fail and timeouts? e.g. “no reply to proxied request” should probably be:
timeout Access-Request ???
Fits into the scheme, but seems an oddball. Maybe an alias defined as "proxy-timed-out" = "timeout Access-Request".
Or “no live home server” could be:
fail Access-Request?
I’m leaning towards that method, instead of the existing Post-Proxy-Type Fail, etc. That method is confusing for end users, and hard to code. e.g. Why is “fail” inside of post-proxy? Is Post-Proxy-Type Fail run for normal proxying, because it’s inside of the post-proxy section? It not, why not?
Totally agreed. Current is hard.
If, instead, we had consistent names, it becomes trivial to know what to do. It becomes trivial to know what the names are, and what each section does.
I *believe* we can set up aliases, etc. which will map the new method to the old one. So no one has to butcher their configuration for 3.1. BUT the benefit of using the new naming scheme is legion. The code becomes MUCH simpler, as does the configuration.
Comments? Stones?
No stones :). Just don't think exposing RADIUS packets directly to end users at first sight is the most helpful thing. Yes, they'll hopefully learn them in time, so giving the tools to do this is good, but terms such as "pre-authentication" or "authenticate-user" are easier to begin with. I think some of the above could also be a bit confusing to the advanced admin, such as: send Access-Accept recv Access-Accept are two _totally_ different things on opposide sides of the server (one as a server, the other as a client), yet look surprisingly similar. I'm not sure what else to suggest though. Matthew -- Matthew Newton, Ph.D. <mcn4@le.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 9, 2015, at 7:04 PM, Matthew Newton <mcn4@leicester.ac.uk> wrote:
recv foo — run this section when receiving a packet “foo”. process foo - run this section to process a packet “foo” send foo - run this section before sending a packet “foo”
The coder part of me says "yes".
The sysadmin part says "when I was learning RADIUS, it was hard enough to work out what was happening, let alone know what each packet did on the network, so no”.
Hmm… I was thinking it would help. Q: What does the server do when it receives an Access-Request packet? A: process it through a “receive Access-Request” section. That seems pretty simple. Sure, it means people have to know what Access-Requests are, but… if you don’t know that, you won’t get very far with RADIUS.
The idea is great, but I'm not sure that the naming will be any more helpful for those not well versed in RADIUS (and it's obvious from the list that there are many people in this situation; that's just a fact of life, many probable only run the RADIUS server as a part time thing).
Sure. It’s a balance, right. Simple enough that the beginner can understand it, and complicated enough that the expert can get things done. Right now the complexity is a source of frustration and confusion. The code to implement it is awkward. It’s hard to reason about what each section does. The sections aren’t really handled consistently.
However, it _might_ be very powerful and work with some sort of templating or aliasing feature. This is completely off the top of my head, but maybe something like
Yes, that would be the idea. The templating would allow the *current* configuration to work unchanged. But would also allow for *updated* configurations to work better. And it would make the code much simpler.
This would also mean that a more advanced admin could quite happily write
send Access-Challenge { ... }
Exactly.
which doesn't appear at all in the default configuration, but could be useful in some circumstances.
You could also have for example:
sent Access-Accept { }
which gets called only after the packet has actually been sent, for final logging. Again, probably not in the default config (or aliased as "log-successful-authentication" maybe).
Hmm… maybe. I’d prefer to avoid that for a host of reasons.
process Access-Request == authenticate (mostly)
I'm not sure that the current config is helpful. It's quite confusing to work out which sections have sub-sections called automatically, or at least it was when still on the learning curve. So
Exactly.
Two ideas come to mind. The first is adding a parameter to the section name, such as (in current config terminology):
authenticate PAP { pap }
Sure, that could work.
The other, slightly less clear way is pull the hidden switch out into the open:
That I find a bit more confusing.
No stones :). Just don't think exposing RADIUS packets directly to end users at first sight is the most helpful thing. Yes, they'll hopefully learn them in time, so giving the tools to do this is good, but terms such as "pre-authentication" or "authenticate-user" are easier to begin with.
I think some of the above could also be a bit confusing to the advanced admin, such as:
send Access-Accept recv Access-Accept
are two _totally_ different things on opposide sides of the server (one as a server, the other as a client), yet look surprisingly similar. I'm not sure what else to suggest though.
Me either. They’re similar, but *named consistently*. If you get confused as to what’s going on, just look at the name. Alan DeKok.
However, it _might_ be very powerful and work with some sort of templating or aliasing feature. This is completely off the top of my head, but maybe something like
radius.conf:
aliases { "select-auth-type" = "receive Access-Request" "authenticate-user" = "process Access-Request" "authorize-user" = "send Access-Accept" "process-failure" = "send Acecss-Reject" ... }
This might actually be very nice, especially in the transition
post-proxy (Post-Proxy-Type Fail) and post-auth (Post-Auth-Type Fail) are already messy IMO, so this might help sort them out.
They could be mapped as above perhaps? :-) Stefan Paetow Moonshot Industry & Research Liaison Coordinator t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc¹s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Collections and Janet Ltd. is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under Company No. number 2881024, VAT No. GB 197 0632 86. The registered office is: Lumen House, Library Avenue, Harwell, Didcot, Oxfordshire, OX11 0SG. T 01235 822200.
Alan, I've been thinking about this, and trying to come up with something coherent to say. First, I have high confidence that were this change implemented, it would have made it somewhat harder for me to learn FreeRADIUS back when I started. (That was about a year before I got involved with moonshot for an entirely different project). I was vaguely familiar with RADIUS, certainly knew what an access-accept and access-request packet were, but had never read RFC 2865. I did know where RFC 2865 was if I wanted it. I was acting as a sysadmin, not a developer with regard to FreeRADIUS at the time. That said, as a developer sometimes working on FreeRADIUS, I find the current config and especially its interactions with the code incredibly confusing. I agree that your proposal would make things easier for developers. Unfortunately, I also agree with the comments that say you're making things easier for developers at the expense of your users. I think this will be harder for sysadmins. I've been struggling trying to figure out why in hopes that I could explain it. Here's my best shot so far. You're focusing on things that coders want to think about: sending packets, receiving packets, processing packets. However, that's not what sysadmins want to do. Sysadmins want to authorize and authenticate users. They want to log information/accounting data. They want to apply policy. You're taking the configuration further away from that and focusing it more on packet flows. You're asking the sysadmins to make the kind of jumps in abstraction that are important to developers. Yeah, the best devops people will be able to follow you. Even they will struggle a bit if they are not developers for your product. Also, I'd urge you to think about backward compatibility. Again, in the interest of focusing on users' needs rather than developers' needs. being able to support configs for large numbers of years is important. Programs like Sendmail, Postfix, Bind, etc, allow you to mostly keep the same conplex configuuration for 5-10 years. That's really important when I have my sysadmin/devops hat on. Updating the default configuration is fine. However every time I see another config option deprecated/another perfectly valid existing config suddenly become invalid, I think "Ah, there FreeRADIUS goes hating its users again." --Sam
On Mar 11, 2015, at 8:46 AM, Sam Hartman <hartmans@mit.edu> wrote:
That said, as a developer sometimes working on FreeRADIUS, I find the current config and especially its interactions with the code incredibly confusing.
That’s one of the drivers. The other is that the current complexity is hard to maintain. So there are bugs, regressions when one bug is fixed, etc.
Here's my best shot so far. You're focusing on things that coders want to think about: sending packets, receiving packets, processing packets.
Which is largely what’s happening, of course.
However, that's not what sysadmins want to do. Sysadmins want to authorize and authenticate users. They want to log information/accounting data. They want to apply policy. You're taking the configuration further away from that and focusing it more on packet flows.
Yes. That may very well be a good thing. Many people on the -users list are confused because they “just want to authenticate users”. They don’t want to know how RADIUS works, and they don’t want to know how FreeRADIUS works. They invent some bizarre theory as to how it works, and then fight tooth and nail against being educated. The current scheme doesn’t lend itself to being explained in simple terms.
You're asking the sysadmins to make the kind of jumps in abstraction that are important to developers.
The way people use RADIUS is *much* more complicated than the way they use DNS, DHCP, SMTP, or nearly any other protocol. What other piece of software has an extensive policy language, and integrates with Perl, Python, SQL, LDAP, Redis, … ? There’s a *reason* it’s complicated. People want to do complicated things. And worse, they want to do complicated things without an understanding of it works. That’s a problem.
Also, I'd urge you to think about backward compatibility. Again, in the interest of focusing on users' needs rather than developers' needs. being able to support configs for large numbers of years is important.
Sure. Version 2.2.6 is backwards compatible with previous versions going back 5 years. That’s fine. Version 3 is a major upgrade, and isn’t 100% backwards compatible. That’s why it’s a major version increment. But it’s also about 90% backwards compatible with 2.2, which helps a lot.
Programs like Sendmail, Postfix, Bind, etc, allow you to mostly keep the same conplex configuuration for 5-10 years.
By (a) having tons of funding, (b) being compatible across *minor* versions, and (c) by not allowing complex configurations. Postfix has about the same amount of code as FreeRADIUS. But it’s processing of messages is not nearly as flexible as FreeRADIUS. It’s more on the order of “there are 3 hooks during the processing of a message, and you can run one of 10 things in each of those hooks”. Sendmail is insanely complex. But it has gone through incompatible upgrades, and has a significant amount of funding behind it. Bind, ISC DHCP, etc. have about the same amount of code as FreeRADIUS. Largely because they re-invent the wheel. Badly. ISC has tons of funding, and teams of full-time staff to each product. They’ve released major version upgrades which are incompatible with older versions. And the configuration for Bind or DHCP is laughably simple compared to FreeRADIUS. So of *course* the software you mentioned is doing better by your metrics. They have a simpler problem to solve, or money to solve complex problems. The issue I’m running into is that people want new features, new functionality, integration with more databases, more performance, etc. And they’re not willing to fund the development. And they’re not willing to learn how the software works. And outside of the ~20 hard-core people on this list, they’re not willing to contribute code, bug reports, etc. So… how do I make the software better? BY making it simpler for *me* to continue developing it.
Updating the default configuration is fine. However every time I see another config option deprecated/another perfectly valid existing config suddenly become invalid, I think "Ah, there FreeRADIUS goes hating its users again."
I can’t think of the last time we deprecated something in 2.2.x. It’s backwards compatible going back to 2.0, from what I recall. We did deprecate a lot in 3.0. Because the old way was confusing the users, and hard to maintain for us. The new config and code is easier to understand, and easier to maintain. But we’re not done yet. I hear you. As I said already, the plan is to allow the current configurations to continue working. BUT to allow more complex configurations to also work, AND having those complex configurations simple to understand. I think that addresses your concerns. The only downside is the attitude of “don’t change anything”. Well, if you don’t want change, pick a version, and stick with it. Don’t upgrade. Don’t get new features. Your configuration will be compatible for as long as you don’t upgrade. Alan DeKok.
On 11/03/15 13:49, Alan DeKok wrote:
So… how do I make the software better? BY making it simpler for *me* to continue developing it.
I consider a big problem with RADIUS to be that people want to set it up and forget about it, but the problem space doesn't lend itself to that, because the "state of the art" for authentication is really pretty poor, and always moving forward. Things like DHCP and DNS have similar issues, and similar levels of lazy/clue are evident on the dhcp-users and bind-users mailing lists, their better docs notwithstanding. However, I share some of the concerns in this thread. My gut feeling aligns with Matthew/Sam - this will confuse the (sadly very common) inexperienced and lazy first-time user. This is just a gut feeling, and I'd love to be proven wrong. At the same time, I do see the problem in making a maintainable codebase at the same time as new features, absent a generous corporate sponsor. Given that, I wonder if it's worth considering something substantially more... radical. Maybe the server core *should* be a set of very low-level "receive" / "transmit" hooks, that call into a high-level processing language - a full-featured, complete, language, with robust threading, flow control and modern features, let's say an embedded JavaScript or Lua interpreter, for a straw man. Maybe the server config should come with a default supplied "processing script" that builds a high-level construct on top of that, and fulfils 90% of common needs - which these days, really means EAP, PAP, DHCP (VMPS and mac-auth being special cases of PAP). Anyone wanting to go beyond the default processing rules can locally fork the processing script and customise to hearts content. It might look something like this: server name { listen { ... } script = ${raddb}/processing.{js,lua} local-config { module-call { eap pap } eap-user-lookup { module = sqlmod query = "select attr,op,val from ... where ..." } eap-user-check { action = permit match = SQL-Group == 'foobar' } pap-user-lookup { ... } } } The script would actually be the thing processing the entire "local-config" block - the server wouldn't do much other than provide the script an API to call modules and modify the packet. In particular I think it would be very helpful for the high-level script to provide a kind of "session" abstraction that corresponds to the points in an EAP exchange that, intuitively, people care about - at the "demand" time for inner EAP credentials, and immediately before making the decision to send an inner accept. It could build that on top of the EAP state machine and the radius "State" variable. This is only a semi-serious proposal - there's probably a lot wrong with it. But if we're considering exposing users of FreeRADIUS to the inner details, it might be worth considering other ways to capitalise on that, and moving those details out of the compiled-in code entirely, into a language with a lower maintenance burden (if you buy that argument, that is...). Alternatively, maybe in addition to the low-level events, synthetic "high-level" events, strategically picked, could fulfil 90% of use-cases. Maybe most people will never need to expand beyond this: process eap-tunnel-ready { # SQL/LDAP lookups go here } process eap-tunnel-success { # VLAN assignment/logging goes here } process eap-tunnel-failure { # logging goes here } It's a tricky one, and I suspect it'll be hard to know if any decision you take is right until a couple of years down the line :o( And someone will always disagree with whatever you decide; bikeshedding is super-hard to avoid. Cheers, Phil
On Mar 11, 2015, at 12:06 PM, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
Things like DHCP and DNS have similar issues, and similar levels of lazy/clue are evident on the dhcp-users and bind-users mailing lists, their better docs notwithstanding.
Not only better docs, but simpler configurations.
However, I share some of the concerns in this thread. My gut feeling aligns with Matthew/Sam - this will confuse the (sadly very common) inexperienced and lazy first-time user. This is just a gut feeling, and I'd love to be proven wrong.
I’m almost OK with that. If you don’t have the time to understand *anything* about the software you’re using, you probably shouldn’t be using it.
At the same time, I do see the problem in making a maintainable codebase at the same time as new features, absent a generous corporate sponsor.
Yeah. While I’m doing FreeRADIUS full-time now, as is Arran… we spend much of our time paying the bills rather than improving the server.
Maybe the server core *should* be a set of very low-level "receive" / "transmit" hooks, that call into a high-level processing language - a full-featured, complete, language, with robust threading, flow control and modern features, let's say an embedded JavaScript or Lua interpreter, for a straw man.
Arran and I have discussed that. It’s not a bad idea. The problem is the protocol-specific mangling. i.e. EAP, SQL, etc. There’s a *reason* that complexity is hidden in modules. That’s hard to duplicate in lua.
Anyone wanting to go beyond the default processing rules can locally fork the processing script and customise to hearts content.
You’re presuming they’ll read it. I’m not so optimistic.
It might look something like this:
I’d find that confusing. A mish-mash of lua and calls out to FreeRADIUS modules...
In particular I think it would be very helpful for the high-level script to provide a kind of "session" abstraction that corresponds to the points in an EAP exchange that, intuitively, people care about - at the "demand" time for inner EAP credentials, and immediately before making the decision to send an inner accept.
Sure, that could help. But people often want to use EAP and non-EAP from the same clients. Getting all that to work simply and easily is hard. The current “default” server could be simplified I think. BUT at the expense of making it not work for some people.
Alternatively, maybe in addition to the low-level events, synthetic "high-level" events, strategically picked, could fulfil 90% of use-cases. Maybe most people will never need to expand beyond this:
That’s useful. It could be done today with the default virtual server and some new policies.
It's a tricky one, and I suspect it'll be hard to know if any decision you take is right until a couple of years down the line :o(
Exactly. Alan DeKok.
On Wed, Mar 11, 2015 at 01:14:07PM -0400, Alan DeKok wrote:
On Mar 11, 2015, at 12:06 PM, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
However, I share some of the concerns in this thread. My gut feeling aligns with Matthew/Sam - this will confuse the (sadly very common) inexperienced and lazy first-time user. This is just a gut feeling, and I'd love to be proven wrong.
I’m almost OK with that. If you don’t have the time to understand *anything* about the software you’re using, you probably shouldn’t be using it.
Yes. It's just a shame that people still do. I guess it stems from the where RADIUS fits in. Many people likely have no interest in running a RADIUS server. Their job is, for example, to "get the wireless network working". A part of this is having to install this software they don't understand to link between the access points and whatever backend they have credentials in. The bit in the middle is just "magic". Trying to understand something you have no interest in is not easy. Especially when you're under pressure to provide the network. Admin is under-resourced? Probably, yes. Fact of life for us? Yes as well, unfortunately.
Maybe the server core *should* be a set of very low-level "receive" / "transmit" hooks, that call into a high-level processing language - a full-featured, complete, language, with robust threading, flow control and modern features, let's say an embedded JavaScript or Lua interpreter, for a straw man.
Arran and I have discussed that. It’s not a bad idea.
The problem is the protocol-specific mangling. i.e. EAP, SQL, etc. There’s a *reason* that complexity is hidden in modules. That’s hard to duplicate in lua.
I'm not sure it's even got to be that complex or deep. I sort of like the idea, though it may be adding complexity beyond what is needed. Not that hidden complexity is a bad thing to make the server flexible, but hopefully not at the expense of performance. The thing I usually think about with FreeRADIUS (and have never managed to actually fully document, though I nearly got there once) is that there is essentially a hard-coded script running behind the scenes. It goes something like when a packet is received: - go through authorize - check module return codes - if Proxy-To-Realm is set: - go through pre-proxy - proxy the packet - end - if Simultaneous-Use is set: - go through session - if Auth-Type is not set: - reject - if Auth-Type section does not exist: - reject - go through authenticate section based on Auth-Type - check module return codes - if success: - go through post-auth - else - go through post-auth/Fail - send response packet - end ... and the post-proxy bit, etc. There is definitely a coded flow through the server that isn't possible to change, but with hidden if()s coded in behind the scenes (such as checking Proxy-To-Realm). Maybe, then, rather than re-jigging the config file, abstract it slightly. Define what happens when packets come in/got out (this is then the "advanced adminstrator" bit: receive Access-Request { authorize if (Proxy-To-Realm) { pre-proxy proxy } else { authenticate(Auth-Type) } } send Access-Accept { post-auth } send Access-Reject { post-auth(Post-Auth-Fail) } the above (in unlang) doesn't call modules, but config sections. Basically, move the hidden server flow out into an unlang configuration. This then allows the config to be tidied, but still allow the existing configurations to work. Code like above matching the exact current flow is distributed with the server, but you could also completely change how the sections are called, e.g. the following would call a section "receive-access-request" and wouldn't ever be able to proxy anything: receive Access-Request { receive-access-request } If this lower-level could also call modules, you could easily hide some things in it, such as preprocess, that the vast majority of people never need to concern themselves with.
Anyone wanting to go beyond the default processing rules can locally fork the processing script and customise to hearts content.
You’re presuming they’ll read it. I’m not so optimistic.
No, they won't. But the idea would be that 99% of admins won't need to.
It might look something like this:
I’d find that confusing. A mish-mash of lua and calls out to FreeRADIUS modules...
It sort of looks nice - the lua (or whatever, maybe just unlang as above) defines which sections are called in what order. The defined sections _are_ the same as current config, so do call out to the current modules. A solution to this all might be as simple as renaming the config sections as originally suggested, and adding a "gosub" in unlang to call other config sections.
The current “default” server could be simplified I think. BUT at the expense of making it not work for some people.
The current default config, while very flexible for nearly any setup, is particularly long and complex. I remember looking at it the first time, and it was daunting. No idea where things hung together and where to start. There are so many comments it's hard to read through it. The comments are really good, don't get me wrong, but are a lot to wade through when you want to find something when you don't know where to look. One way to do it might be to break the default config up into simpler "examples". I keep meaning to try and start putting some sort of cookbook together, and this is really how it's likely to look. So instead of "default" and "inner-tunnel" you might have "wireless-802.1x-active-directory" "wireless-802.1x-ldap" "wireless-802.1x-local-auth" "adsl-chap-sql" ... etc "wireless-802.1x-active-directory" might look something like the following, with very few comments. modules { mschap { ... } eap { ... } } server default { listen { ... } authorize { filter_username preprocess eap files } authenticate { eap } post-auth { detail } } server inner-tunnel { authorize { mschap eap files } authenticate { eap } } The idea being that it's a full server config in one file, but as simple as possible. Then the existing config files are there as full reference guides with all the configs. Then the new admin edits wireless-802.1x-active-directory, drops it in sites-enabled, and hopefully is about the way to a working setup. No need to worry about configuring the right modules, etc - it's all in the one file. To me, that would have been much easier to begin with, as I wouldn't have been wading through many options that were totally irrelevant to what I was trying to do, and actually confused me a lot. It's trying to get a fine balance between easy for developers, easy for newcomers but customisable enough for advanced admins. That's hard. Matthew -- Matthew Newton, Ph.D. <mcn4@le.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>
The mapping between the new types and old is as follows:
recv Access-Request == authorize process Access-Request == authenticate (mostly) send Access-Accept == post-auth
Fair enough, if you call the section that (i.e. 'recv Access-Request'). That should be fairly straight-forward to understand (especially when liberally commented).
send Access-Challenge == no matching section
This might be useful (especially when you've got the weirdnesses where you've got a challenge being sent after the 'send Access-Accept' for some reason).
send Access-Reject == Post-Auth-Type Reject recv Accounting-Request == preacct process Accounting-Request == accounting send Accounting-Request == no matching section
Straight-forward.
For proxying, we no longer have pre-proxy and post-proxy, instead we have:
send Access-Request == pre-proxy
how about 'proxy-send Access-Request' (which under the covers just means 'send')?
recv Access-Reject == post-proxy (oops, that’s probably not a good idea)
The above resolves this one?
recv Access-Challenge == post-proxy (oops again)
Ditto?
There’s also the Autz-Type section, which exists, but is very weird. Can it just go away? Does anyone use it?
Never seen that really... Autz-Type = Authorization-Type?
And what about fail and timeouts? e.g. “no reply to proxied request” should probably be:
timeout Access-Request ???
Or “no live home server” could be:
fail Access-Request?
Makes sense?
If, instead, we had consistent names, it becomes trivial to know what to do. It becomes trivial to know what the names are, and what each section does.
Yes. Something being self-explanatory always makes life easier.
I *believe* we can set up aliases, etc. which will map the new method to the old one. So no one has to butcher their configuration for 3.1. BUT the benefit of using the new naming scheme is legion. The code becomes MUCH simpler, as does the configuration.
As someone who did not have any FR experience in 2012 before starting on Moonshot, starting on something like this as a fresh-faced newbie would probably be easier to understand. HOWEVER, I can see why this would/could be a nightmare for those migrating from 2.x or 3.0.x configurations, or those FR newbies who find *loads* of references to authorize, authenticate, session, post-auth, pre- and post-proxy etc on t'Internet. When this happens, the wiki needs to be overhauled as part of this, possibly with two specific sites, i.e. 3.0.x and earlier, and 3.1 and later. Will try to help with the documentation where possible... Anything to ease the pain of transition for people. Stefan Paetow Moonshot Industry & Research Liaison Coordinator t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet Lumen House, Library Avenue, Harwell Oxford, Didcot, OX11 0SG jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Collections and Janet Ltd. is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under Company No. number 2881024, VAT No. GB 197 0632 86. The registered office is: Lumen House, Library Avenue, Harwell, Didcot, Oxfordshire, OX11 0SG. T 01235 822200.
participants (6)
-
A.L.M.Buxey@lboro.ac.uk -
Alan DeKok -
Matthew Newton -
Phil Mayers -
Sam Hartman -
Stefan Paetow