FreeRADIUS two factor authentication (OTP and Password)

MultiOTP is a tool to verify one-time passwords from hardware or software HOTP or TOTP devices. In the README they describe how to set up FreeRADIUS for OTP verification. By default, MultiOTP requires entering a 4 digit personal PIN plus the token (usually 6 digits). For better security in multi-factor authentication (MFA), it’s a good idea to use a stronger password than a 4 digit PIN and concatenate it with the OTP. Combining the password and token in one field allows two factor authentication for a lot of older devices that don’t support multiple authentication challenges natively.

In order to do that, we create a user in FreeRADIUS with an encrypted password. We configure FreeRADIUS for multiOTP according to the instructions. We set “request_prefix_pin=0” in the multiOTP user config file and in multiotp.ini to disable the PIN check.

Then we change the “authorize” section in FreeRADIUS config “sites-available/default” to:

authorize {
        if (User-Password =~ /^(.*)([0-9]{6})$/) {
                update request {
                        User-Password := "%{2}"
                }
                multiotp.authenticate
                if (ok) {
                        update request {
                                User-Password := "%{1}"
                        }
                }
        } else {
                reject
        }
        files 
        expiration
        pap
}

The password of an incoming request is now split into password and 6 digit token via regex. The second match (OTP) is authenticated against the multiotp backend. If successful, the token is stripped from the password for further processing. If the token or the password format is incorrect, the request is rejected.

After the OTP has been validated, we read the user accounts, password and expiration times from the “users” file using the “files” module. After the expiration check, the password is validated via PAP.