Hi everyone,
I have found a possible solution for the hash algorithm, let's recap for those who don't know what we are talking about.
Problem
Freeradius many different authorization and authentication schemes but when it comes to the hashing algorithm used for passwords choices are limited, the stronger hashing algorithms being md5, sha1 and unix crypt.
Unfortunately these algorithms are rather obsolete and we would much rather let Django handle this for us because it does it pretty well .Django nowadays uses PBKDF2 by default and allows for even stronger algorithms, see the Password Management documentation on the django website for more information.
To use the default freeradius setup would mean downgrading our own hashing algorithm and I think this is unacceptable for several reasons:
- it's 2017, MD5 is easy to break and SHA1 has just been demonstrated to be crackable by Google and other big players
- we really didn't like that in OpenWISP1 each module has its own database of users, infact we hated it;
our aim is to have a single (distributed) database of users shared between the different openwisp2 modules and we really want django-freeradius to become an important module of openwisp2, therfore downgrading the hashing algorithm for django-freeradius means downgrading it for the entire openwisp2 ecosystem: definitely not viable!Solution
The recommended solution in these cases is to delegate authorization and authentication to a separate application, in our case this can be handled by django-freeradius itself.
rlm_exec
The first solution I have tried is to configure freeradius 3 to use the exec module call a unix/linux script during the authorization phase, the script gets passed the username and password and if the combination is correct exits with 0 (zero) otherwise it exits with 1 (which means failure).This solution works but has two problems:
- freeradius runs as a user (freerad in my test environment) which has very limited permissions and can't easily access the python virtualenv of django-freeradius, infact I had to perform some ugly hacks to make this script work
- this method is not recommended by the freeradius community because according to them it doesn't scale well, they suggest to use the rlm_rest module
rlm_rest
This module allows to configure freeradius to delegate some or all of its operations (authorization, authentication, accounting, postauth) to a REST API.
I've successfully configured my test freeradius instance to authenticate and authorize using an existing REST API and it seems to work very well.
Since this method is recommended by the freeradius community and allows great flexibility, I believe we should go along this path: we should implement a few simple API endpoints that are dedicated to freeradius, starting with authorize.
-- Leonardo Maccari, Assistant Professor @DISI, University of Trento Tel: +39 0461 285323, www.disi.unitn.it/~maccari, gpg ID: AABE2BD7
On 11/07/17 17:21, Federico Capoano wrote:
Hi everyone,
Hi Federico,
I have looked into FreeRadius (FR) in the past, so I am curious about this issue.
I have found a possible solution for the hash algorithm, let's recap for those who don't know what we are talking about.
Problem
Freeradius many different authorization and authentication schemes but when it comes to the hashing algorithm used for passwords choices are limited, the stronger hashing algorithms being md5, sha1 and unix crypt.
What is exactly the hash you are referring to? If I understood correctly it is the hash used to encrypt passwords in the database, which is not mandated by FR but from the (inner) method you configure FR to use:
http://deployingradius.com/documents/protocols/compatibility.html
basically, if you want to use any of these authentication protocols, you have to use these hashes because the password comes already hashed from the supplicant. If you want to use another hash you have to configure FR to pass along the password in clear, and then do your own hashing. You can do this using the PAP protocol, which sends the password in clear (!!) and then you can hash it at the destination. To make this reasonably secure you have to embed it into a TTLS tunnel. This may be even supported by other applications so you can re-use the db for other uses.
Unfortunately these algorithms are rather obsolete and we would much rather let Django handle this for us because it does it pretty well .Django nowadays uses PBKDF2 by default and allows for even stronger algorithms, see the Password Management documentation on the django website for more information.
To use the default freeradius setup would mean downgrading our own hashing algorithm and I think this is unacceptable for several reasons:
- it's 2017, MD5 is easy to break and SHA1 has just been demonstrated to be crackable by Google and other big players
- we really didn't like that in OpenWISP1 each module has its own database of users, infact we hated it;
our aim is to have a single (distributed) database of users shared between the different openwisp2 modules and we really want django-freeradius to become an important module of openwisp2, therfore downgrading the hashing algorithm for django-freeradius means downgrading it for the entire openwisp2 ecosystem: definitely not viable!Solution
The recommended solution in these cases is to delegate authorization and authentication to a separate application, in our case this can be handled by django-freeradius itself.
rlm_exec
The first solution I have tried is to configure freeradius 3 to use the exec module call a unix/linux script during the authorization phase, the script gets passed the username and password and if the combination is correct exits with 0 (zero) otherwise it exits with 1 (which means failure).This solution works but has two problems:
- freeradius runs as a user (freerad in my test environment) which has very limited permissions and can't easily access the python virtualenv of django-freeradius, infact I had to perform some ugly hacks to make this script work
- this method is not recommended by the freeradius community because according to them it doesn't scale well, they suggest to use the rlm_rest module
rlm_rest
This module allows to configure freeradius to delegate some or all of its operations (authorization, authentication, accounting, postauth) to a REST API.
I've successfully configured my test freeradius instance to authenticate and authorize using an existing REST API and it seems to work very well.
Since this method is recommended by the freeradius community and allows great flexibility, I believe we should go along this path: we should implement a few simple API endpoints that are dedicated to freeradius, starting with authorize.
Again, if I understood well, you are actually giving FR an API that plugs back into django? then, why are you using FR at all? I suppose your use case is to have one FR instance that serves several services, such as openwisp, but this way you can't decouple FR from django.
Yes you have understood correctly, we are talking about the password hashing algorithms supported by Freeradius.basically, if you want to use any of these authentication protocols, you have to use these hashes because the password comes already hashed from the supplicant. If you want to use another hash you have to configure FR to pass along the password in clear, and then do your own hashing. You can do this using the PAP protocol, which sends the password in clear (!!) and then you can hash it at the destination. To make this reasonably secure you have to embed it into a TTLS tunnel. This may be even supported by other applications so you can re-use the db for other uses.
We don't want to use one of those hashing algorithms for the reasons stated in the first email. The password can then be sent to freeradius in cleartext using a TTLS tunnel. In some cases, the NAS (network access server) sits on the same host of freeradius or in a trusted LAN (eg: the LAN of a virtualized physical server) and a TTLS tunnel is not needed.
We want to let freeradius do what is good at doing: speak the RADIUS protocol to perform AAA with popular networking software (captive portals, WPA enterprise).
Freeradius can read /write from/to one or more datastores to retrieve/log data about authorization, authentication and accounting, SQL is just one of the several datastores supported by freeradius. Other datastores supported are redis, couchdb, a REST API, an external program and some more.
Using a REST API built purposely for freeradius we can let freeradius focus on speaking the RADIUS protocol with other networking software and equipment while we can handle all the application level details autonomously overcoming limitations that would make the application less useful in the long term.
We can say that two pieces of software are highly coupled when both know many specific details about each other, in this design freeradius doens't know anything about django because it limits itself to sending DATA via HTTPS according to its configuration and expects a response in a specific format. It can be reconfigured any time. If someone changes their mind and wants to migrate to a different radius management solution they can just migrate the data and reconfigure their freeradius instances to speak to a different URL or they can reconfigure it entirely to use SQL queries or other datastores.
I hope is clear. If not, let me know.
Federico
--
You received this message because you are subscribed to the Google Groups "OpenWISP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openwisp+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Yes you have understood correctly, we are talking about the password hashing algorithms supported by Freeradius.basically, if you want to use any of these authentication protocols, you have to use these hashes because the password comes already hashed from the supplicant. If you want to use another hash you have to configure FR to pass along the password in clear, and then do your own hashing. You can do this using the PAP protocol, which sends the password in clear (!!) and then you can hash it at the destination. To make this reasonably secure you have to embed it into a TTLS tunnel. This may be even supported by other applications so you can re-use the db for other uses.
We don't want to use one of those hashing algorithms for the reasons stated in the first email. The password can then be sent to freeradius in cleartext using a TTLS tunnel. In some cases, the NAS (network access server) sits on the same host of freeradius or in a trusted LAN (eg: the LAN of a virtualized physical server) and a TTLS tunnel is not needed.maybe I was not clear enough, need a picture to explain:
SU --- AU -------------- Radius ---- DB
this is the typical authentiation set-up, with a supplicant, an authenticator, a radius and a user db. I think in your case SU and AU are co-located in the web server.
With protocols like MSCHAPv2 this happens:
SU --- AU -------------- Radius ---- DB
hash(pwd)------------------------------>
so basically Radius knows nothing about hashes, and you have to cope with crappy hashes (which, BTW, is what everybody uses, because you still pass through a TLS tunnel, so it is not that horrible, and collisions are still hard enough not to be practical).
With PAP this happens:
SU --- AU -------------- Radius ---- DB
pwd---------------------------------->hash(pwd)
So the pwd passes in the clear up to the DB. There you can hash it with whatever you want, including a salted SHA256. But, since everything passes in clear, you have to be extremely sure that you have no leaks anywhere (and that authentication is bi-directional in some way, but this may not be your case). I am pretty sure there is a working ldap configuration for this, even if i never tried it myself.
We want to let freeradius do what is good at doing: speak the RADIUS protocol to perform AAA with popular networking software (captive portals, WPA enterprise).
Freeradius can read /write from/to one or more datastores to retrieve/log data about authorization, authentication and accounting, SQL is just one of the several datastores supported by freeradius. Other datastores supported are redis, couchdb, a REST API, an external program and some more.
Using a REST API built purposely for freeradius we can let freeradius focus on speaking the RADIUS protocol with other networking software and equipment while we can handle all the application level details autonomously overcoming limitations that would make the application less useful in the long term.
We can say that two pieces of software are highly coupled when both know many specific details about each other, in this design freeradius doens't know anything about django because it limits itself to sending DATA via HTTPS according to its configuration and expects a response in a specific format. It can be reconfigured any time. If someone changes their mind and wants to migrate to a different radius management solution they can just migrate the data and reconfigure their freeradius instances to speak to a different URL or they can reconfigure it entirely to use SQL queries or other datastores.before i answer, maybe i miss the big picture. generally you want to interface to RADIUS because you have some external DB of passwords that are already in use, and you want to plug your application into it. But maybe you are interested in the other way around, you want to embed an user DB and a FreeRadius server into the host where openwisp is running, so you can offer to third-party applications all-in-one with OpenWISP and a RADIUS interface?
On Thu, Jul 13, 2017 at 11:00 PM Leonardo Maccari <leonardo...@unitn.it> wrote:
Yes you have understood correctly, we are talking about the password hashing algorithms supported by Freeradius.basically, if you want to use any of these authentication protocols, you have to use these hashes because the password comes already hashed from the supplicant. If you want to use another hash you have to configure FR to pass along the password in clear, and then do your own hashing. You can do this using the PAP protocol, which sends the password in clear (!!) and then you can hash it at the destination. To make this reasonably secure you have to embed it into a TTLS tunnel. This may be even supported by other applications so you can re-use the db for other uses.
We don't want to use one of those hashing algorithms for the reasons stated in the first email. The password can then be sent to freeradius in cleartext using a TTLS tunnel. In some cases, the NAS (network access server) sits on the same host of freeradius or in a trusted LAN (eg: the LAN of a virtualized physical server) and a TTLS tunnel is not needed.
maybe I was not clear enough, need a picture to explain:
SU --- AU -------------- Radius ---- DB
this is the typical authentiation set-up, with a supplicant, an authenticator, a radius and a user db. I think in your case SU and AU are co-located in the web server.
With protocols like MSCHAPv2 this happens:
SU --- AU -------------- Radius ---- DB
hash(pwd)------------------------------>
so basically Radius knows nothing about hashes, and you have to cope with crappy hashes (which, BTW, is what everybody uses, because you still pass through a TLS tunnel, so it is not that horrible, and collisions are still hard enough not to be practical).
With PAP this happens:
SU --- AU -------------- Radius ---- DB
pwd---------------------------------->hash(pwd)
So the pwd passes in the clear up to the DB. There you can hash it with whatever you want, including a salted SHA256. But, since everything passes in clear, you have to be extremely sure that you have no leaks anywhere (and that authentication is bi-directional in some way, but this may not be your case). I am pretty sure there is a working ldap configuration for this, even if i never tried it myself.Yes this is the solutions we are talking about, using PAP (encrypted with TTLS or not depending on where the communication between radius clients and radius).
Each method has trade offs. The method we have discussed is easy enough to implement, secure, flexible, has low mantainance costs.
As said, storing passwords in SHA1 or MD5 is not viable unless we only store passwords in that form only for users of a freeradius instance/federation, but we would need to store these passwords in a different location than the main user passwords (eg: administrators, operators, future contributors when we will introduce the possibility of contributing to the network by adding nodes into the system), this means we should keep the SHA1/MD5 encrypted passwords for freeradius users either in separate fields or a different DB entirely: this solution would be cumbersome, bug prone and costly to mantain.
before i answer, maybe i miss the big picture. generally you want to interface to RADIUS because you have some external DB of passwords that are already in use, and you want to plug your application into it. But maybe you are interested in the other way around, you want to embed an user DB and a FreeRadius server into the host where openwisp is running, so you can offer to third-party applications all-in-one with OpenWISP and a RADIUS interface?
Sorry, I'm not following you.
On 14/07/17 10:43, Federico Capoano wrote:
On Thu, Jul 13, 2017 at 11:00 PM Leonardo Maccari <leonardo...@unitn.it> wrote:
Yes you have understood correctly, we are talking about the password hashing algorithms supported by Freeradius.basically, if you want to use any of these authentication protocols, you have to use these hashes because the password comes already hashed from the supplicant. If you want to use another hash you have to configure FR to pass along the password in clear, and then do your own hashing. You can do this using the PAP protocol, which sends the password in clear (!!) and then you can hash it at the destination. To make this reasonably secure you have to embed it into a TTLS tunnel. This may be even supported by other applications so you can re-use the db for other uses.
We don't want to use one of those hashing algorithms for the reasons stated in the first email. The password can then be sent to freeradius in cleartext using a TTLS tunnel. In some cases, the NAS (network access server) sits on the same host of freeradius or in a trusted LAN (eg: the LAN of a virtualized physical server) and a TTLS tunnel is not needed.
maybe I was not clear enough, need a picture to explain:
SU --- AU -------------- Radius ---- DB
this is the typical authentiation set-up, with a supplicant, an authenticator, a radius and a user db. I think in your case SU and AU are co-located in the web server.
With protocols like MSCHAPv2 this happens:
SU --- AU -------------- Radius ---- DB
hash(pwd)------------------------------>
so basically Radius knows nothing about hashes, and you have to cope with crappy hashes (which, BTW, is what everybody uses, because you still pass through a TLS tunnel, so it is not that horrible, and collisions are still hard enough not to be practical).
With PAP this happens:
SU --- AU -------------- Radius ---- DB
pwd---------------------------------->hash(pwd)
So the pwd passes in the clear up to the DB. There you can hash it with whatever you want, including a salted SHA256. But, since everything passes in clear, you have to be extremely sure that you have no leaks anywhere (and that authentication is bi-directional in some way, but this may not be your case). I am pretty sure there is a working ldap configuration for this, even if i never tried it myself.Yes this is the solutions we are talking about, using PAP (encrypted with TTLS or not depending on where the communication between radius clients and radius).
Each method has trade offs. The method we have discussed is easy enough to implement, secure, flexible, has low mantainance costs.
As said, storing passwords in SHA1 or MD5 is not viable unless we only store passwords in that form only for users of a freeradius instance/federation, but we would need to store these passwords in a different location than the main user passwords (eg: administrators, operators, future contributors when we will introduce the possibility of contributing to the network by adding nodes into the system), this means we should keep the SHA1/MD5 encrypted passwords for freeradius users either in separate fields or a different DB entirely: this solution would be cumbersome, bug prone and costly to mantain.Ok I understand you don't want to have MD5/SHA1, but with the PAP solution, you don't have to. Unless you are telling me that the documentation or rlm_pap is wrong:
https://freeradius.org/radiusd/man/rlm_pap.txt
which is entirely plausible. Even if I am thinking that i miss some pieces because i don't understand why you want to replicate the user DB, once you have a RADIUS server.
Header Attribute Description
------ --------- -----------
{clear} Cleartext-Password clear-text passwords
{cleartext} Cleartext-Password clear-text passwords
{crypt} Crypt-Password Unix-style "crypt"ed passwords
{md5} MD5-Password MD5 hashed passwords
{base64_md5} MD5-Password MD5 hashed passwords
{smd5} SMD5-Password MD5 hashed passwords, with a salt
{sha} SHA-Password SHA1 hashed passwords
SHA1-Password SHA1 hashed passwords
{ssha} SSHA-Password SHA1 hashed passwords, with a salt
SSHA1-Password SHA1 hashed passwords, with a salt
{ssh2} SHA2-Password SHA2 hashed passwords
{ssh256} SHA2-Password SHA2 hashed passwords
{ssh512} SHA2-Password SHA2 hashed passwords
{nt} NT-Password Windows NT hashed passwords
{nthash} NT-Password Windows NT hashed passwords
{x-nthash} NT-Password Windows NT hashed passwords
{ns-mta-md5} NS-MTA-MD5-Password Netscape MTA MD5 hashed passwords
{x- orcllmv} LM-Password Windows LANMAN hashed passwords
{X- orclntv} LM-Password Windows LANMAN hashed passwordsWhen receiving a password with the PAP module, we have to choose either one of those algorithms or cleartext. Se we are choosing cleartext (over an encrypted tunnel if necessary), but delegating the authorization, that is the check of the password stored with a stronger hashing algorithm (and possibly more complex checks) to an external application.
before i answer, maybe i miss the big picture. generally you want to interface to RADIUS because you have some external DB of passwords that are already in use, and you want to plug your application into it. But maybe you are interested in the other way around, you want to embed an user DB and a FreeRadius server into the host where openwisp is running, so you can offer to third-party applications all-in-one with OpenWISP and a RADIUS interface?
Sorry, I'm not following you.let's try again: what is the architecture you have in mind? given the following scheme:
SU --- AU -------------- Radius ---- DB
what are the components you control and what are the external components you only plan to connect to?
let's try again: what is the architecture you have in mind? given the following scheme:
SU --- AU -------------- Radius ---- DB
what are the components you control and what are the external components you only plan to connect to?In public wifi or university wifi settings, we control everything. captive portal, VPNs, freeradius, openwisp2.
In other settings like Eduroam or other 802.1x settings we may not have control of access points that talk to freeradius, in that case we would need to properly setup the TTLS tunnel between freeradius and the parts we don't control.
Let me offer a bit more context about django-freeradius because maybe you are not aware of it. We are working to renovate an existing application called OpenWISP User Management System, which is basically a freeradius management interface which creates a (very weird) MySQL database that is then used by freeradius (usually deployed with freeradius 2). This application has been used for many years by many companies and municipalities to offer public wifi. OWUMS has many important limitations and shortcomings which we are trying to solve with this renovation.So with django-freeradius we are trying to create the base openwisp2 module that will take care of AAA in openwisp2, but in a cleaner way which we aim will be simpler to extend and less costly to mantain and evolve over time.
I hope is clearer now.