Using One TIme Passwords with FreeRadius
radius.pkoch at dfgh.net
radius.pkoch at dfgh.net
Thu Apr 29 10:22:27 CEST 2021
Dear reader of this mailinglist
I'm new to the RADIUS business and I did my frist FreeRadius
installation just two weeks ago. I still might misunderstand some of the
concepts. So keep in mind that whenever I make statments about what
FreeRadius does or should do - these are all my personal assumptions
only and might be totally wrong. So far I only tried to get things
working. I did not look at my "solution" from a security perspective.
I'm describing my solution since this might be useful to other people.
And I was hoping to get some feedback.
My goal was to allow our users to authenticate with our WiFi
accesspoints with a 2-factor method. This means for us, that they either
have to user their identity card (which has a builtin smart card chip)
or their OTP-token (which generates OATH TOTP values). The solution was
expected to work with both laptops (Windows and MacOS) and smart
phones/tablets (iPhones, Android). It was expected to work with
company-devices (manages by our own MDM) and with BYO-devices from
eployees or guests.
I never heard of solutions that allows an iPhone to use a smart card for
authentication. And using smart cards always needs prior installation of
smart card middleware. But one time passwords can be used whenever a
password has to be entered. Some of our employees have a second token
for generation of "guest-passwords". So using passwords generated by our
OTP-tokens seemed to be the only way to go.
Without two-factor authentication our employees must go to a central
helpdesk, prove their identity by showing their identity card or
passport, just to get a piece of paper with a password that allows WiFi
acces for twelve hours only. If they forward this password to a guest,
they have to fill out another piece of paper.
With this situation we cannot force the devices to use certain
algorithms for WiFi-authentication. OTP-authentication might require
that the supplicant sends the password in clear (PAP or PAP within
EAP-TTLS). But configuring guest devices to use this authentication
method is unrealistic. iPhones for example can do this, but only if they
are under MDM-control.
So we use EAP-PEAP with MSCHAPv2 because that's supported by all devices
if the accesspoint is configured for WPA2-Enterprise. At least we hope
that this is true. And we don't care about guests that visit us with
their Win-XP laptops.
MSCHAPv2 does not send the password in cleartext within the inner
tunnel. But as you all know there's no need to compare password A with
password B if you just want to check wether they are equal or not.
Comparing HashFunction(A) with HashFunction(B) does work as well and the
hash function used by MSCHAPv2 is well documented in RFC 2759.
So how do you teach FreeRadius to verify an OATH time based one time
password? rlm_otp and rlm_secureid where of no help. So I read the the
source code of other FreeRadius modules to find the place where
FreeRadius does authentication based on the RFC2759 hash function.
I found it in rlm_mschap.c in function do_mschap(). There's a switch
statement which looks at the value of method. If method==AUTH_INTERNAL
FreeRadius calculates the MSCHAPv2 hash on it's own and complains if the
password is missing. But to my great pleasure (I love this
FreeRadius-software) I spotted another FreeRadius authentication method
in that switch-statement, namely AUTH_NTLM_EXEC. With that method
FreeRadius delegates the decision about wether the MSCHAPv2 hash value
is correct or not to an external program. The location of this external
program is configured by the ntlm_auth configuration directive. And the
idea behind this was obviously to let the ntlm_auth programm from Samba
do the decision.
But there's no real reason why the ntlm_auth programm must be the Samba
one. So I put
ntlm_auth = "/etc/radius/check_otp '%{mschap:User-Name}'
'%{mschap:Challenge}' '%{mschap:NT-Response}' '%{Packet-SRC-IP-Address}'"
into mods-enabled/mschap and wrote my own "ntlm_auth"-style routine. It
takes the username, challenge and a correct token values, calculates the
response from these values and compares that with the given response.
The 4th-parameter has informational purpoes only and will be included in
syslog-messages when something goes wrong. Actually
/etc/radius/check_otp does not do anything on its own, but just forwards
all arguments to our authentication server. One could avoid that
indirection across check_otp and let FreeRadius talk directly with our
authentication server. I don't think that's worth the minimal
performance improvement. And the interface between FreeRadius and the
"ntlm_auth"-program is very easy to implement.
This solutions is used within our IT-department since monday and will go
into production next week. So far we had no problems. Everybody is glad
that he must not visit the helpdesk anymore (which is mostely closed
anyway due to corona).
There are some pitfalls:
Most important: If a one time password turned out to be correct, it will
be reused by the supplicant many times. And for obvious reasons you
don't want to enter a new token value over and over again. Hence the
check_otp routine must accept token values that were successfully used
within the past for some amount of time. We use 12 hours for guests and
I have to fight with the security staff about wether this can be
increased for employees. Their main argument is, that a valid password
might be given to other people. So I'm looking for a way to detect
wether two supplicants are using the same user/password-combination. iOS
MAC-randomization is my enemy here. Maybe someone has an idea how to do
this.
Kind regards
Peter
More information about the Freeradius-Users
mailing list