Freeradius with multiotp - but otp-pin is in username

Alan DeKok aland at deployingradius.com
Mon May 22 14:30:22 CEST 2017


On May 21, 2017, at 6:53 PM, blaster at vorsicht-bissig.de wrote:
> 
>   i'm trying to setup FreeRADIUS Version 3.0.13 with multiotp BUT I want
>   to enter the information like this:
>   "{Username}:{OTP-PIN}"   ==> f.e. "dani:955825"   (username in users
>   file)
>   "{Password}"                      ==> f.e. "blabla"  (password in users
>   file)

  That's a little unusual, but it should work, mostly.

  But most people appoint the OTP to the password, not to the User-Name.

>   I think this could be a way, to get some devices to work with 2 factor,
>   which are not build for it.
>   I successfully get an ok from multiotp, by regex'ing "{OTP-PIN}"
>   from "{Username}:{OTP-PIN}",
>   but PAP is failing, because I can't get PAP to look for "{Username}"
>   (f.e. "dani").
>   It always tries to look for "{Username}:{OTP-PIN}" (f.e. "dani:955825")
>   in the authentication-section.

  Because the default configuration looks up users by the contents of the User-Name attribute.

  Sine you've modified the User-Name to contain the OTP key, that won't work.

>   It would be nice if you could point me in the right direction.
>   My apologies, if this question was already asked, and I didn't find it.
>   Best regards
>   Gerald
>   remark - begin
>   ------------
>   I successfully did it with
>   "{Username} "                  ==> f.e. "dani" (username in users file)
>   "{Password}{OTP-PIN}"     ==> f.e. "blabla955825"  (password in users
>   file)

  Which is what most people use.

>   But I think the
>   "{Username}"
>   "{Password}{OTP-PIN}"
>   way, fails when it comes to MSCHAP (with ActiveDirectory), because
>   Freeradius compares only password hashes and not plaintext, so it can't
>   recongnise what's the OTP-PIN and what's the password.

  Yes.

>   --------------
>   remark - end
>   /usr/local/etc/raddb/users
>   ####
>   "dani"        Cleartext-Password := "blabla", MS-CHAP-Use-NTLM-Auth :=
>   0
>   ####
>   /usr/local/etc/dictionary
>   ####
>   ATTRIBUTE       User-OTP                3000    string

  You don't need that.

>   ATTRIBUTE       User-Password-TMP       3001    string
>   ####
>   /usr/local/etc/raddb# cat policy.d/pol_usernamemultiotp
>   #####
>   pol_usernamemultiotp.authorize {
>           if ( &User-Name =~ /^(.*)(\:)([0-9]{6})$/) {
>                   update request {
>                           User-Password-TMP := "%{User-Password}"
>                           User-OTP := "%{3}"
>                           User-Password := "%{User-OTP}"

  This isn't necessary.

>                           User-Name := "%{1}"

  You probably shouldn't re-write the User-Name.  Leave it alone.

>                           Stripped-User-Name := "%{1}"

  If Stripped-User-Name exists, the server uses it for lookups instead of User-Name.  So all you need to do is set Stripped-User-Name correctly.

>   #####
>   radiusd -X output - begin

  Reading it carefully helps... the messages are useful.

>   #####
>   Ready to process requests
>   (0) Received Access-Request Id 192 from 127.0.0.1:56491 to
>   127.0.0.1:1842 length 81
>   (0)   User-Name = "dani:955825"
>   (0)   User-Password = "blabla"
>   (0)   NAS-IP-Address = 127.0.0.1
>   (0)   NAS-Port = 100
>   (0)   Message-Authenticator = 0x0cc5e28430dea113b6b4fde2d1537388

  That's the Access-Request...

>   (0) custom_otp: Searching for user in group "vlan10"
>   rlm_ldap (ldap): Closing connection (0): Hit idle_timeout, was idle for
>   76 seconds
>   rlm_ldap (ldap): Closing connection (1): Hit idle_timeout, was idle for
>   76 seconds
>   rlm_ldap (ldap): Closing connection (2): Hit idle_timeout, was idle for
>   76 seconds
>   rlm_ldap (ldap): You probably need to lower "min"
>   rlm_ldap (ldap): Closing connection (3): Hit idle_timeout, was idle for
>   76 seconds
>   rlm_ldap (ldap): You probably need to lower "min"
>   rlm_ldap (ldap): Closing connection (4): Hit idle_timeout, was idle for
>   76 seconds
>   rlm_ldap (ldap): You probably need to lower "min"

  Pay attention to those messages.  Either increase "idle_timeout", or lower "min".

>   (0) custom_otp: EXPAND
>   (samaccountname=%{%{Stripped-User-Name}:-%{User-Name}})
>   (0) custom_otp:    --> (samaccountname=dani:955825)
>   (0) custom_otp: Search returned no results

  Note that it's looking up the User-Name attribute.  i.e. the name *before* any edits.

>   rlm_ldap (ldap): Released connection (6)
>   (0)     [ldap] = notfound
>   (0)     [expiration] = noop
>   (0)     [logintime] = noop
>   (0)     policy pol_usernamemultiotp.authorize {

  And AFTER you look up User-Name (the one with the OTP), you run the policy to fix the User-Name.

  i.e. you have this reversed.

 The solution is to put the re-write at the TOP of the "authorize" section. That way, the Stripped-User-Name attribute is seen by all modules.

  And the policy you created is too complicated.  Just do this:

	if ( &User-Name =~ /^(.*):([0-9]{6})$/) {
		update request {
			Stripped-User-Name := "%{1}"
			User-OTP := "%{2}"
		}
	}

  i..e. you don't need a "tmp" password. You don't need to re-write the password.  You don't need to match (:) in the regex.  Just matching : is good enough.

  Alan DeKok.




More information about the Freeradius-Users mailing list