FreeRADIUS with custom multi-factor authentication

Alan DeKok aland at
Wed Feb 13 17:37:50 CET 2019

On Feb 13, 2019, at 11:15 AM, Clint Lord <clint at> wrote:
> We are evaluating FreeRADIUS as a possible solution but we have a very specific authentication workflow and aren’t sure if FreeRADIUS will fit our needs.

  If the RADIUS protocol supports it, FreeRADIUS can do it.

>  We’ve searched the documentation for insights into how we might accomplish our goals, but haven’t seen anything that quite matches up.
> Here is our workflow:
> 1. The user enters their username and password.
> 2. The system calls a web service to validate the username and password.
> 3. If the username and password are valid, and the user’s account has MFA enabled:
> 	a. The MFA method is executed (ex. OTP is sent via SMS message)
> 	b. The system sends the user a message asking them to enter the OTP and allows them to submit the value.
> 	c. The system validates their response by calling another web service.
> 	d. If the response is invalid the system sends another message informing them of the failure and allows them to respond again (a few times).
> All of the account data, username/password authentication and MFA processing is done behind web services, we just need FreeRADIUS to allow us to go through the multiple request and response steps as we call these web services.

  Which means... what?

  The requirements above need to be more specific.  What part is a web service?  What part is FreeRADIUS?  What packets go back and forth?

> We thought we might be able to use rlm_python or rlm_perl to accomplish this, but we are only seeing simple “func_authenticate” implementations and can’t see how we can facilitate this back and forth communication with the user.

  See Access-Challenge packets.  They're intended for this kind of situation.

> All we are asking are some pointers or general guidance so we can continue our research and determine if FreeRADIUS will meet our needs.

  The typical process for challenge-response authentication is like this:

* user enters name / password (PPP, VPN, whatever)
* the NAS sends name / password to the RADIUS server
* the RADIUS server determines that it should challenge the user
* it sends Access-Challenge
  * With a Reply-Message like "Please enter token"
  * with a State attribute that ties the challenge/response together
* the NAS shows the message to the user, who then enters a token
* the NAS sends a new Access-Request with
  * same User-Name
  * user's token as User-Password
  * State attribute from Access-Challenge
* the server sees that it's the same State as before, and continues authentication...
   * all *session* data needs be stored in the "session-state" list, which is automatically saved / restored.


authorize {

	if (!State) {
  	  update reply {
		Reply-Message := "enter token"

           update session-state {
		Cleartext-Password := "1234"


	if (User-Password != &session-state:Cleartext-Password) {

  That's the basics.

  Alan DeKok.

More information about the Freeradius-Users mailing list