Hi, We've been struggling a bit with the TLS config - not actually configuring it, but how it appears in the config file. The basic thoughts go something along the lines of: PEAP uses TLS EAP-TTLS uses TLS EAP-TLS uses TLS ... so why is the TLS config all inside EAP-TLS, and mysteriously PEAP and TTLS use EAP-TLS's config? When you go to configure PEAP/EAP-TLS things get more interesting, as you actually have to configure EAP-TLS+PEAP (outer), and then EAP-TLS (inner). To be honest, configuring PEAP/MS-CHAPv2 a year or so ago for the first time felt wierd too - "but I don't want EAP-TLS" :) This it not from a programming point of view - I can see why it's done like that. It's more for ease of understanding the configuration. There are other places where TLS crops up too, such as RADSEC and LDAP. The RADSEC one specifically says it's the same config as EAP-TLS (but at least it doesn't *use* EAP-TLS's config!) We wondered whether something like the following would be feasable, or worth trying to implement? In the main top-level config in radiusd.conf, have a new 'tls' section, that might look something like this: tls { outer-peap { certificate_file = ${certdir}/server.pem ... } inner-eap { private_key_file = ${certdir}/server.pem certificate_file = ${certdir}/server.pem CA_file = ${cadir}/ca.pem ... } outer-tls { ... } radsec { ... } ldap { ... } } where the sub-headings are just labels - instantiations of the 'tls' config. Then wherever a TLS configuration is required, we can have just "tls = outer-peap". For example, modules: eap { tls { tls = outer-tls fragment_size = 1200 ... } peap { tls = outer-peap default_eap_type = mschapv2 copy_request_to_tunnel = no use_tunneled_reply = no virtual_server = "inner-tunnel" ... } } eap inner-eap { tls { tls = inner-tls cache { ... } fragment_size = 1024 verify { ... } } } This then makes it quite clear which TLS config belongs to which section, and allows sharing of TLS configs if really desired. The only potential problem I can see is if the TLS on EAP comes up first, before the EAP type is determined, but having looked at the protocol I don't believe that is the case - so the server should always know that it's the PEAP tls= config that is being used, as the EAP type was code 25, for example. I think we were thinking "hang on a sec, TLS is a generic server thing, nothing really to specifically do with EAP-TLS or PEAP, etc, so why is the config just in EAP-TLS - that's confusing". As a start, I guess the modules could keep their current TLS settings, but have an additional tls= option that would pull global config in at instantiation time. I'm not sure it needs to be any more difficult than that - except maybe in the PEAP/TTLS sections which don't have their own settings already. Are there any thoughts on this - is it worth persuing? I'm not sure if I'll have time to work on it or not, but thought it was worth throwing the idea out anyway. :) Thanks, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Matthew Newton wrote:
... so why is the TLS config all inside EAP-TLS, and mysteriously PEAP and TTLS use EAP-TLS's config?
Because they all use TLS. And because you want the server to appear as one RADIUS server. Having a shared configuration makes that easier. The alternative would be to configure TLS *separately* for PEAP and TTLS. When the user switches from PEAP to TTLS, a "new server" warning pops up, along with a new certificate. That's not nice.
When you go to configure PEAP/EAP-TLS things get more interesting, as you actually have to configure EAP-TLS+PEAP (outer), and then EAP-TLS (inner). To be honest, configuring PEAP/MS-CHAPv2 a year or so ago for the first time felt wierd too - "but I don't want EAP-TLS" :)
You have to configure two TLS modules if you want to use TLS in two different ways.
In the main top-level config in radiusd.conf, have a new 'tls' section, that might look something like this:
The difficulty is that it doesn't follow the module format of the server. It mixes module configuration, "listen" section configuration, and has configuration for different virtual servers in one place.
Then wherever a TLS configuration is required, we can have just "tls = outer-peap".
You can pretty much do this today. Just re-arrange the configuration. See raddb/templates.conf. It's pretty much just reorganization. The current model works for me. The TLS configuration is located in the places where it's used. (for the most part) That makes sense. Putting it somewhere else is a recipe for end-user confusion.
The only potential problem I can see is if the TLS on EAP comes up first, before the EAP type is determined, but having looked at the protocol I don't believe that is the case - so the server should always know that it's the PEAP tls= config that is being used, as the EAP type was code 25, for example.
That isn't a problem. EAP does negotiation of EAP types.
As a start, I guess the modules could keep their current TLS settings, but have an additional tls= option that would pull global config in at instantiation time. I'm not sure it needs to be any more difficult than that - except maybe in the PEAP/TTLS sections which don't have their own settings already.
Maybe... the PEAP and TTLS modules are strongly tied to the enclosing EAP module, and share the same TLS config. So it is *very* difficult for them to find a TLS configuration which is located elsewhere in the code. See src/modules/rlm_eap/eap.c. Look for "TLS". Knowledge that TTLS/PEAP uses TLS is hard-coded into the EAP module. Changing that is difficult.
Are there any thoughts on this - is it worth persuing? I'm not sure if I'll have time to work on it or not, but thought it was worth throwing the idea out anyway. :)
Independent of any code changes, I would find that configuration confusing. It might be worth locating all of the TLS config in one place, but I'm not sure that the benefit is justified. Alan DeKok.
Hi, On Tue, Feb 07, 2012 at 08:40:33AM +0100, Alan DeKok wrote:
Matthew Newton wrote:
... so why is the TLS config all inside EAP-TLS, and mysteriously PEAP and TTLS use EAP-TLS's config?
Because they all use TLS. And because you want the server to appear as one RADIUS server. Having a shared configuration makes that easier.
The alternative would be to configure TLS *separately* for PEAP and TTLS. When the user switches from PEAP to TTLS, a "new server" warning pops up, along with a new certificate. That's not nice.
Hmm - agreed on this point. Maybe our confusion, then, is that there is (logically, I'm not talking about the underlying code): TLS configuration, used by EAP-TLS, PEAP, TTLS because they all do TLS yet the configuration implies: EAP-TLS, which is used by PEAP and TTLS. The fact is that you have to configure EAP-TLS so that you can use the PEAP/TTLS, even if you don't want to actually use the EAP-TLS type itself.
In the main top-level config in radiusd.conf, have a new 'tls' section, that might look something like this:
The difficulty is that it doesn't follow the module format of the server. It mixes module configuration, "listen" section configuration, and has configuration for different virtual servers in one place.
OK, maybe that isn't such a good way to clarify it. Like you say, it would move configuration to different places and may make it harder to follow. Thinking more about it, maybe just this would make it easier to understand: eap { ... common-tls { private_key_file = ... certificate_file = ... ... } md5 { } tls { } peap { ... } ttls { } ... } So the "TLS" bit is split from the EAP-TLS type. To disable EAP-TLS, you'd just comment out the tls{} section, just like any other EAP type, but leave the common-tls section for PEAP/TTLS to use. I guess as an extreme, the TLS options could even be directly in the eap section rather than in a sub-section, as all eap types requiring TLS in that instantiation will use the same TLS settings (i.e. they're actually 'global'). But it seems tidier for them to be grouped together.
See src/modules/rlm_eap/eap.c. Look for "TLS". Knowledge that TTLS/PEAP uses TLS is hard-coded into the EAP module. Changing that is difficult.
Yeah, I can see how PEAP/TTLS use the underlying EAP-TLS code - that makes a lot of sense. It's the fact that that code structure percolates up into the configuration. I admit, now that we know how it works, it's easy to configure, but I've now been doing this for over a year. Things are always easy when you know how! Initially it was a right pig to understand... "but I don't *want* EAP-TLS (and I want to guarantee it can never work)" :-) Just trying to explore if there is any way the config can be updated/simplified to remove that initial confusion! Cheers, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Matthew Newton wrote:
The fact is that you have to configure EAP-TLS so that you can use the PEAP/TTLS, even if you don't want to actually use the EAP-TLS type itself.
Yes. The saving grace there is you don't normally issue client certs. So EAP-TLS won't work when people try to use it.
OK, maybe that isn't such a good way to clarify it. Like you say, it would move configuration to different places and may make it harder to follow. Thinking more about it, maybe just this would make it easier to understand: ... So the "TLS" bit is split from the EAP-TLS type. To disable EAP-TLS, you'd just comment out the tls{} section, just like any other EAP type, but leave the common-tls section for PEAP/TTLS to use.
That would work.
I guess as an extreme, the TLS options could even be directly in the eap section rather than in a sub-section, as all eap types requiring TLS in that instantiation will use the same TLS settings (i.e. they're actually 'global'). But it seems tidier for them to be grouped together.
A bit, yes.
Yeah, I can see how PEAP/TTLS use the underlying EAP-TLS code - that makes a lot of sense. It's the fact that that code structure percolates up into the configuration.
In git "master" branch, the code has changed. All of the SSL cert stuff is now in src/main/tls.c. So it *should* be possible to more cleanly separate the configurations.
Just trying to explore if there is any way the config can be updated/simplified to remove that initial confusion!
My take is the following: 1) update eap_tls_attach() to do cf_pair_find(cs, "tls") put it before the tls_server_conf_parse() line. if it's found, look for the section referred to by the "tls" entry and use that for the TLS configuration. 2) verify that you can change the config to: eap { tls_common { ... cert stuff ... } tls { tls = tls_common } ... } and check that it works. 3) move the eap_tls_instantiate() code to rlm_eap/libeap/eap_tls.c not all, just the common "set up session code". Leave the TLS / TTLS / PEAP code in eap_tls_instantiate() 4) copy the eap_tls_instantiate() code to TTLS and PEAP as eap_ttls_instantiate(), and eap_peap_attach() ensure that ONLY the TTLS / PEAP code is there. remove the TTLS / PEAP stuff from eap_tls_instantiate() 5) copy the cf_pair_find(cs, "tls") stuff from eap_tls_attach into eap_ttls_attach() and eap_peap_attachI(). 6) remove the TTLS / PEAP --> TLS code from rlm_eap/eap.c If TLS, TTLS, and PEAP work, then you now are a good ways to Steps 5 && 6 might be complicated. But the basic idea *should* work. The end result will be the TLS configuration will be anywhere you want. The EAP tls, ttls, and peap code will just have an entry "tls =" to point to the TLS configuration. The HARD thing about this is now the TLS configuration will be loaded multiple times. Once each for EAP-TLS, TTLS, and PEAP. Finding a way to avoid that would be good. Alan DeKok.
Hi, On Wed, Feb 08, 2012 at 09:18:55AM +0100, Alan DeKok wrote:
Matthew Newton wrote:
The fact is that you have to configure EAP-TLS so that you can use the PEAP/TTLS, even if you don't want to actually use the EAP-TLS type itself.
Yes. The saving grace there is you don't normally issue client certs. So EAP-TLS won't work when people try to use it.
In our case, when we started out, we used the local CA to create a certificate for FreeRADIUS, but then also put the local CA root as CA_file (that's what you do, right? Put in the certificate and the root...) ...then realised that any client could authenticate just by switching to EAP-TLS and presenting another certificate from the same CA, which was the CA for the domain, with auto-enrolment about to be used :-) I guess it comes from configuring Apache for so long, where you tend to put the CA root and all intermediates on the server, even though technically you probably don't need the root cert itself.
In git "master" branch, the code has changed. All of the SSL cert stuff is now in src/main/tls.c. So it *should* be possible to more cleanly separate the configurations.
OK.
Just trying to explore if there is any way the config can be updated/simplified to remove that initial confusion!
My take is the following:
Thanks, that's useful. I'll try and have a look and see if I can come up with anything.
The end result will be the TLS configuration will be anywhere you want. The EAP tls, ttls, and peap code will just have an entry "tls =" to point to the TLS configuration.
If the tls config HAS to be called common_tls, inside the eap module, then there's no need for the "tls=" entry any more - which could be another way of doing it, albeit slightly less flexible.
The HARD thing about this is now the TLS configuration will be loaded multiple times. Once each for EAP-TLS, TTLS, and PEAP. Finding a way to avoid that would be good.
Agreed. Thanks, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Matthew Newton wrote:
If the tls config HAS to be called common_tls, inside the eap module, then there's no need for the "tls=" entry any more - which could be another way of doing it, albeit slightly less flexible.
There may be use-cases where multiple virtual servers can share the same TLS configuration. Permitting a layer of indirection doesn't cost much, and is useful.
The HARD thing about this is now the TLS configuration will be loaded multiple times. Once each for EAP-TLS, TTLS, and PEAP. Finding a way to avoid that would be good.
Agreed.
I have a simple way. :) Get me a patch as suggested, and fixing the "loading certs twice" problem is another ~5 lines of code. Alan DeKok.
Hi, On Thu, Feb 09, 2012 at 04:42:31PM +0100, Alan DeKok wrote:
Matthew Newton wrote:
If the tls config HAS to be called common_tls, inside the eap module, then there's no need for the "tls=" entry any more - which could be another way of doing it, albeit slightly less flexible.
There may be use-cases where multiple virtual servers can share the same TLS configuration. Permitting a layer of indirection doesn't cost much, and is useful.
I've been a bit busy with other things, but have now got around to doing this. There's a branch at the following URL with a set of patches to do it. https://github.com/mcnewton/freeradius-server/commits/patch-tls-option Essentially they follow your helpful suggestions in the previous e-mail. It's something like: - Rejig config and eaptls_attach to move TLS specific options out from EAP-TLS section - update eaptls_initiate to just deal with EAP-TLS, moving session code to libeap - Add TLS config parsing to EAP-PEAP attach - add an eappeap_initiate function - ditto for EAP-TTLS - remove the "Wild & crazy stuff" from eap.c :-) - tidy the config a bit and add explanatory comments. The code also has a fallback, so if the new tls= options are not specified it will read the config as v2.x currently does (e.g. tls{} must exist before peap and ttls will load). There are still a few tiny bits that are duplicated between TLS/PEAP/TTLS, but it's a close call whether these are worth putting into some library function, or just leaving as-is for clarity. This lot now means that there should be no dependencies between PEAP/TTLS and TLS, so they each stand on their own. I think from the config perspective, it's also a lot cleaner as it's removed the dependency where you need EAP-TLS, even though you don't use it. It's tidied some switch()/if()s from the code, too.
The HARD thing about this is now the TLS configuration will be loaded multiple times. Once each for EAP-TLS, TTLS, and PEAP. Finding a way to avoid that would be good.
Agreed.
I have a simple way. :) Get me a patch as suggested, and fixing the "loading certs twice" problem is another ~5 lines of code.
I did this by caching the result in tls_server_conf_parse - if it's passed the same CONF_SECTION as the previous time, it returns the same conf pointer. As the EAP sections are pretty much always going to be called consecutively, this saves re-parsing each time. It was about 5 lines of code - dunno if it was what you were thinking or not ;-) Cheers, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Matthew Newton wrote:
I've been a bit busy with other things, but have now got around to doing this. There's a branch at the following URL with a set of patches to do it.
OK. I added some comments, mostly minor.
I did this by caching the result in tls_server_conf_parse - if it's passed the same CONF_SECTION as the previous time, it returns the same conf pointer. As the EAP sections are pretty much always going to be called consecutively, this saves re-parsing each time.
It was about 5 lines of code - dunno if it was what you were thinking or not ;-)
It's not. Static variables are generally bad. My comments on github suggest a better way. Alan DeKok.
On Tue, Feb 28, 2012 at 10:15:34AM +0100, Alan DeKok wrote:
Matthew Newton wrote:
I've been a bit busy with other things, but have now got around to doing this. There's a branch at the following URL with a set of patches to do it.
OK. I added some comments, mostly minor.
Updated this code now, it's in a new branch at https://github.com/mcnewton/freeradius-server/commits/patch-tls-option-1 Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Matthew Newton wrote:
Updated this code now, it's in a new branch at
https://github.com/mcnewton/freeradius-server/commits/patch-tls-option-1
Ok... I've pulled most of the coce in, with some minor changes. Alan DeKok.
On Sun, Mar 04, 2012 at 10:46:00AM +0100, Alan DeKok wrote:
I've pulled most of the coce in, with some minor changes.
OK, thanks! I'm pondering a few more small things - I've tested templates with the tls config, and it works fine - so I wonder if it's worth an example in the templates.conf for tls? Not sure how much would normally be shared to be worth it, though. Server certificate and a few other bits, maybe. On PEAP/TTLS client certificates, I think it would now be nice to have a require_client_cert = yes option in the peap {} and ttls {} sections. Maybe that can be overridden by EAP-TLS-Require-Client-Cert (or maybe even EAP-PEAP-Require-* and EAP-TTLS-Require-*, although not sure if that's worth it). I'll put together a patch for the option to peap/ttls if it's worth it. There's a comment in the code about the EAP-TLS-Require-Client-Cert needing fixing, but I don't know what the thoughts on that were at the time? I'm still not 100% sure on the tls-config tls-common directive. It seemed the best way a few days ago, because the eap module treats all conf_sections inside eap {} as eap-type modules to load. Having tls-config as a 'virtual type' meant it was easier to avoid. I'm starting to look at it and think it's not that clean, though. The following might tidy it up. eap { common_settions = here tls-config { common { ... } } tls { tls = common } peap { ... } gtc { ... } md5 { ... } ... } Possibly also have a 'types {}' section for all the eap-types to go in, to then avoid having the exception for tls-config that's not a sub-module, as the eap code could iterate over that knowing it will only contain modules (a bit like the main modules{} section). Cheers, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Matthew Newton wrote:
I've tested templates with the tls config, and it works fine - so I wonder if it's worth an example in the templates.conf for tls? Not sure how much would normally be shared to be worth it, though. Server certificate and a few other bits, maybe.
Sure. Examples are always good.
On PEAP/TTLS client certificates, I think it would now be nice to have a
require_client_cert = yes
option in the peap {} and ttls {} sections. Maybe that can be overridden by EAP-TLS-Require-Client-Cert (or maybe even EAP-PEAP-Require-* and EAP-TTLS-Require-*, although not sure if that's worth it). I'll put together a patch for the option to peap/ttls if it's worth it.
Yes. Have that EAP-TLS-Require-Client-Cert attribute over-ride the configuration setting.
There's a comment in the code about the EAP-TLS-Require-Client-Cert needing fixing, but I don't know what the thoughts on that were at the time?
No idea. It works, so... that's that, I guess.
I'm still not 100% sure on the tls-config tls-common directive. It seemed the best way a few days ago, because the eap module treats all conf_sections inside eap {} as eap-type modules to load. Having tls-config as a 'virtual type' meant it was easier to avoid. I'm starting to look at it and think it's not that clean, though.
It works.
The following might tidy it up.
eap { common_settions = here tls-config { common { ... } }
That looks complicated and weird. I'd just leave it the way it is. The most I would change is to have the "tls = ..." be a *reference*. If the configuration section isn't found in "eap", start looking from the top-level configuration.
Possibly also have a 'types {}' section for all the eap-types to go in, to then avoid having the exception for tls-config that's not a sub-module, as the eap code could iterate over that knowing it will only contain modules (a bit like the main modules{} section).
That's an extra layer which is confusing, and doesn't add a lot of value. I'd say it's not necessary. Alan DeKok.
participants (2)
-
Alan DeKok -
Matthew Newton