not logged in | [Login]


This guide shows the configuration necessary to make the multiOTP system work with recent versions of FreeRADIUS, it doesn't detail actually setting the tokens up, but there's plenty of documentation on that already.

multiOTP tokens will work with any type of PAP/CHAP/MS-CHAP/MS-CHAPv2 based authentication, including EAP-TTLS-PAP. With the correct OS/Supplicant software tokens can be used for 802.1X authentication and well as for standard PAP/CHAP/MS-CHAP/MS-CHAPv2 authentication (just make the changes described in the inner server). This guide closely follows the NTLM Auth with PAP HOWTO but with a little extra validation.

NT_KEY generation is also supported using the -request-nt-key option (like for ntlm_auth --request-nt-key option), which is needed in order to enable VPN (PPTP + MPPE) with MS-CHAP/MS-CHAPv2.

Before starting or asking for help

  • Make sure the otp script is executable chmod +x /path/to/multiotp.php
  • Verify multiotp is setup correctly by calling the script from the commandline with the appropriate arguments

FreeRADIUS 3.x.x

  1. Create 'raddb/modules/multiotp' and add the following, this will create a new instance of the exec module:

    # Exec module instance for multiOTP
    # Replace '/path/to' with the actual path to the multiotp.php file
    exec multiotp {
            wait = yes
            input_pairs = request
            output_pairs = reply
            program = "/path/to/multiotp.php %{User-Name} %{User-Password} -request-nt-key -src=%{Packet-Src-IP-Address} -chap-challenge=%{CHAP-Challenge} -chap-password=%{CHAP-Password} -ms-chap-challenge=%{MS-CHAP-Challenge} -ms-chap-response=%{MS-CHAP-Response} -ms-chap2-response=%{MS-CHAP2-Response}"
            shell_escape = yes
  2. Copy module/mschap to module/multiotpmschap. Change the following line in multiotpmschap:

    "mschap {"
    "mschap multiotpmschap {"

Also change ntlm_auth variable:

ntlm_auth = "/path/to/multiotp.php %{User-Name} %{User-Password}
-request-nt-key -src=%{Packet-Src-IP-Address}
-chap-challenge=%{CHAP-Challenge} -chap-password=%{CHAP-Password}
  1. Edit 'raddb/policy.conf' and add the following to override the authorize method of the exec module:

    policy {
        # Change to a specific prefix if you want to deal with normal PAP authentication as well as OTP
        # e.g. "multiotp_prefix = 'otp:'"
        multiotp_prefix = ''
        multiotp.authorize {
           # This test is for decimal OTP code only, otherwise you will have to change it
           # Try for example this simple test: if (!control:Auth-Type) {
            if (control:Auth-Type == 'MS-CHAP') {
                  update control {
                          Auth-Type := multiotpmschap
            elsif (!control:Auth-Type && User-Password =~ /^${policy.multiotp_prefix}([0-9]{10})$/) {
                update control {
                    Auth-Type := multiotp
  2. Edit your virtual server file, the default for the outer server is 'raddb/sites-available/default'

  3. Add a call to multiotp before the pap module in authorize:

    authorize {
        # Handle multiotp authentication
        # Handle other PAP authentication
  4. Create the multiotp sub-section in authenticate:

    authenticate {
        Auth-Type multiotp {
        Auth-Type multiotpmschap {
  5. Start the server up in debug mode radiusd -X and test authentication