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