Two-Factor Auth using FreeRADIUS
Hello all, long-time reader, first time poster to this list. I've watched many posters go down in flames on this list, so I'm going to try to learn from their mistakes and be as precise as possible; I'm also going to make it known at the outset that I have read all the documentation that I can get my hands on and I am running FreeRADIUS -X to start it in debug mode! I am attempting to implement two-factor authentication with LDAP combined with FreeRADIUS. As you probably know at this point, many SSL-VPN and network control devices only offer both LDAP/AD and RADIUS authentication for their devices (some have native SecurID support as well). The client is authenticating users with Active Directory as the first-level auth. It is on the second-level auth that I have questions. The authentication mechanism that we are using for the second-factor authentication is a one-time password sent to the user via an out-of-band mechanism. Therefore, this requires two different interactions with the RADIUS server: 1: Access-Request: SSL-VPN -> FreeRADIUS. This sends the username (and another piece of data that I am currently putting in the password field) to the RADIUS server. *At this point, I have written a JRadius component: * On the SSL-VPN side I have PAP authentication selected. That is because as above, I am using the password field to transfer another piece of data (the delivery method) to RADIUS. * It resides in the "authorize" stage of the "default" site in FreeRADIUS * It looks the user up in LDAP (again) to obtain his/her E-Mail address to send. It then sends the OTP to the e-mail address. This part works perfectly! * Then, I construct a new Access-Challenge packet in JRadius, creating a new State and copying the initial Access-Request packet's identifier, and return from the JRadius handler. This part also works perfectly. 2: Access-Challenge: FreeRADIUS -> SSL-VPN device This step is where the wheels are falling off the bus. FreeRADIUS does not seem to want to send out my Access-Challenge packet; it automatically changes it to an Access-Reject. I have even put another handler in the post-auth reject handler to change it BACK to a Access-Challenge. At that point if I do that, FreeRADIUS' debug mode reports that it is sending an Access-Request packet to the IP address of the NAS (or my RADIUS test program)! 3: Access-Request (original Using state and Packet ID so I can identify the request on the back-end JRadius component) * Compare passed OTP to stored OTP for that "session". Act accordingly. * Obviously this step does not yet work! I have tried many permutations of Auth-Methods. Since I am using PAP authentication on the SSL-VPN side, I initially chose that module, however it really does not like my sending that Access-Challenge packet out. I have tried commenting lots of things out, even using jradius in the 'PAP' handler of the authentication section. At that point, even though the PAP module is not running, FreeRADIUS puts the kibosh on my Access-Challenge packet. This leads me to believe that FreeRADIUS has a very rigid idea of what these packets should be depending on auth method. Is there really no use case at all for PAP where you would ever send an access challenge? Are there any "dummy" auth methods that just, well, let me do whatever the hell I want? Is it possible to implement a new Auth method like this? Questions: * Is there any way with current functionality, I can Implement a custom challenge flow like the one I am describing? * Are there examples of this kind of functionality out there "in the wild" that I can look at and use as a model? * I greatly enjoy working with JRadius in spite of its occasional wonkiness, but I can dust off my C if necessary. Is some sort of JRadius handler combined with C FreeRADIUS mods possible? I do not mind writing code if it is necessary, but of course I'd prefer not to if it's at all avoidable! (Is this a question better posed to the dev list?) Thank you for any help or guidance you can give me in this matter!
Hi,
Hello all, long-time reader, first time poster to this list. I've watched many posters go down in flames on this list, so I'm going to try to learn from their mistakes and be as precise as possible; I'm also going to make it known at the outset that I have read all the documentation that I can get my hands on and I am running FreeRADIUS -X to start it in debug mode!
...so close! all the details and ideas....and what was missing? the output of 'radiusd -X' ;-) alan
:-( Sometimes it's tough being *almost* perfect.
Will reply back later with an exhaustive list of things I have tried that didn't work, their sites-enabled/default configurations, and the debug output! ________________________________ From: Alan Buxey <A.L.M.Buxey@lboro.ac.uk> To: Ryon Day <ryon_day@yahoo.com>; FreeRadius users mailing list <freeradius-users@lists.freeradius.org> Sent: Friday, March 16, 2012 4:54 PM Subject: Re: Two-Factor Auth using FreeRADIUS Hi,
Hello all, long-time reader, first time poster to this list. I've watched many posters go down in flames on this list, so I'm going to try to learn from their mistakes and be as precise as possible; I'm also going to make it known at the outset that I have read all the documentation that I can get my hands on and I am running FreeRADIUS -X to start it in debug mode!
...so close! all the details and ideas....and what was missing? the output of 'radiusd -X' ;-) alan
Ryon Day wrote:
Hello all, long-time reader, first time poster to this list. I've watched many posters go down in flames on this list, so I'm going to try to learn from their mistakes and be as precise as possible; I'm also going to make it known at the outset that I have read all the documentation that I can get my hands on and I am running FreeRADIUS -X to start it in debug mode!
It's easy to avoid "flames". Be honest, be clear, and follow instructions.
The authentication mechanism that we are using for the second-factor authentication is a one-time password sent to the user via an out-of-band mechanism. Therefore, this requires two different interactions with the RADIUS server:
1: Access-Request: SSL-VPN -> FreeRADIUS. This sends the username (and another piece of data that I am currently putting in the password field) to the RADIUS server. *At this point, I have written a JRadius component: * On the SSL-VPN side I have PAP authentication selected. That is because as above, I am using the password field to transfer another piece of data (the delivery method) to RADIUS. * It resides in the "authorize" stage of the "default" site in FreeRADIUS * It looks the user up in LDAP (again) to obtain his/her E-Mail address to send. It then sends the OTP to the e-mail address. This part works perfectly! * Then, I construct a new Access-Challenge packet in JRadius, creating a new State and copying the initial Access-Request packet's identifier, and return from the JRadius handler. This part also works perfectly.
You can't create an Access-Challenge packet in jradius. You can only create a reply. If the user isn't accepted, the reply is automatically a reject.
2: Access-Challenge: FreeRADIUS -> SSL-VPN device This step is where the wheels are falling off the bus. FreeRADIUS does not seem to want to send out my Access-Challenge packet; it automatically changes it to an Access-Reject. I have even put another handler in the post-auth reject handler to change it BACK to a Access-Challenge. At that point if I do that, FreeRADIUS' debug mode reports that it is sending an Access-Request packet to the IP address of the NAS (or my RADIUS test program)!
You need to set the "request->reply->code = PW_ACCESS_CHALLENGE" for challenges to work. See rlm_example. It's just not set up to do manually created challenges. The reason is that 99.9999% of people get it wrong, and it's not necessary.
3: Access-Request (original Using state and Packet ID so I can identify the request on the back-end JRadius component) * Compare passed OTP to stored OTP for that "session". Act accordingly. * Obviously this step does not yet work!
Does the SSL-VPN even support Access-Challenge? Some don't.
This leads me to believe that FreeRADIUS has a very rigid idea of what these packets should be depending on auth method. Is there really no use case at all for PAP where you would ever send an access challenge? Are there any "dummy" auth methods that just, well, let me do whatever the hell I want? Is it possible to implement a new Auth method like this?
There are many cases where you can send an Access-Challenge. HOWEVER... most of them are mandated by the authentication method. EAP, MS-CHAP, etc.
Questions: * Is there any way with current functionality, I can Implement a custom challenge flow like the one I am describing?
Yes. See rlm_example. You *can't* do it via unlang.
* Are there examples of this kind of functionality out there "in the wild" that I can look at and use as a model? * I greatly enjoy working with JRadius in spite of its occasional wonkiness, but I can dust off my C if necessary. Is some sort of JRadius handler combined with C FreeRADIUS mods possible? I do not mind writing code if it is necessary, but of course I'd prefer not to if it's at all avoidable! (Is this a question better posed to the dev list?)
See rlm_example. Alan DeKok.
Good afternoon, Alan; Thank you for your reply! I have spent some time ruminating on this and You have given me some leads to follow, for which I am very grateful! I intend to follow up on this again after I experiment more this afternoon and evening, but first a few quick replies to some of your points:
It's easy to avoid "flames". Be honest, be clear, and follow instructions.
Understood! I don't want to waste anyone's time beating horses that have long since expired; I also did not mean to intimate that anyone on the list goes out of their way to 'haze' people!
You can't create an Access-Challenge packet in jradius. You can only create a reply. If the user isn't accepted, the reply is automatically a reject.
Okay, I believe that this is where some of my confusion came from. A friend of mine who went to the Navy Nuclear School said that the instructors marked their papers with "GCE" for "Gross Conceptual Error" whenever they got something terribly wrong on an assignment. I believe this may be my first of many GCEs here. I think that I took the JRadius API at face value; I was doing something like this (again, this was in the "authorize" stage): RadiusPacketreq =request.getRequestPacket(); RadiusPacketrep=request.getReplyPacket(); RadiusPacketresponse =newAccessChallenge(); To this I would add the 'State' and 'Reply-Message' attributes, copy the packet ID, and then later: request.setReplyPacket(reply ); My thinking was that FreeRADIUS would take this at face value; After all, the difference between a Access-Challenge and another RADIUS packet is merely the ID. So from what you say above, may I infer that the only thing that FreeRADIUS takes from the reply are the different attributes assigned to it, and it handles the "type" of packet itself?
You need to set the "request->reply->code = PW_ACCESS_CHALLENGE" for challenges to work. See rlm_example.
Thank you!
It's just not set up to do manually created challenges. The reason is that 99.9999% of people get it wrong, and it's not necessary.
Here's to hoping that I can be part of the 00.0001%, maybe in income one day, as well as in FreeRADIUS packet manipulation! In this case, I cannot find another auth method that allows a flow with the aspects that the use case requires. Most other OTP schemes have something where the server knows the value ahead of time, and the user has a device that displays it i.e. RSA SecurID or Gemalto's equivalent (both of which I believe are implemented as RADIUS protocol implementations as well). The Access-Challenge method also allows us to give users multiple retries.
Does the SSL-VPN even support Access-Challenge? Some don't.
As a matter of fact, it does. I absolutely would not have set off on this, much less posted to this list had I not done an Extensive POC with TinyRADIUS (A wonderful little tool for quick mock-ups). Obviously in choosing to attempt it in FreeRADIUS I got in a little over my head!
There are many cases where you can send an Access-Challenge. HOWEVER... most of them are mandated by the authentication method. EAP, MS-CHAP, etc.
Thank you again. So it seems that what I want to do doesn't really fit into any of the current authentication methods. I will continue digging, you have given me some seriously great education and help here; Thank you so much. I will follow up with my experiences!
See rlm_example.
Thanks! Ryon D.
Ryon Day wrote:
request.setReplyPacket(reply );
My thinking was that FreeRADIUS would take this at face value; After all, the difference between a Access-Challenge and another RADIUS packet is merely the ID. So from what you say above, may I infer that the only thing that FreeRADIUS takes from the reply are the different attributes assigned to it, and it handles the "type" of packet itself?
There's more to it than that. jradius isn't part of FreeRADIUS, as it's not written in C. So there needs to be an API between the two. And that API can only handle setting attributes. It can't handle setting packet types.
Thank you again. So it seems that what I want to do doesn't really fit into any of the current authentication methods. I will continue digging, you have given me some seriously great education and help here; Thank you so much. I will follow up with my experiences!
It doesn't. Hand-rolled challenge-response mechanisms are rare. Alan DeKok.
participants (3)
-
Alan Buxey -
Alan DeKok -
Ryon Day