Configuring FreeRadius with LDAP and Google MFA
Hello, I'm trying to setup a freeradius v.3.0.20 server using LDAP with MFA (Google authenticator). The LDAP part worked, however, since I added the MFA configuration, it doesn't work anymore, it seems that the password are not even checked against the ldap database (Windows AD). I followed this tutorial to get it working: https://sysopstechnix.com/enable-2fa-on-freeradius-with-openldap-users/ Here is part of the logs : Ready to process requests (0) Received Access-Request Id 67 from 127.0.0.1:46701 to 127.0.0.1:1812 length 95 (0) User-Name = "my_user" (0) User-Password = "Password831041" (0) NAS-IP-Address = 127.0.0.1 (0) NAS-Port = 1812 (0) Message-Authenticator = 0x63145e2376266d9643ce6ad73cf9e8f3 (0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default (0) authorize { (0) policy filter_username { (0) if (&User-Name) { (0) if (&User-Name) -> TRUE (0) if (&User-Name) { (0) if (&User-Name =~ / /) { (0) if (&User-Name =~ / /) -> FALSE (0) if (&User-Name =~ /@[^@]*@/ ) { (0) if (&User-Name =~ /@[^@]*@/ ) -> FALSE (0) if (&User-Name =~ /\.\./ ) { (0) if (&User-Name =~ /\.\./ ) -> FALSE (0) if ((&User-Name =~ /@/) && (&User-Name !~ mailto:/@(.+)\.(.+)$/)) { (0) if ((&User-Name =~ /@/) && (&User-Name !~ mailto:/@(.+)\.(.+)$/)) -> FALSE (0) if (&User-Name =~ /\.$/) { (0) if (&User-Name =~ /\.$/) -> FALSE (0) if (&User-Name =~ mailto:/@\./) { (0) if (&User-Name =~ mailto:/@\./) -> FALSE (0) } # if (&User-Name) = notfound (0) } # policy filter_username = notfound (0) policy filter_uuid { (0) if (&User-Name =~ /^(.*)@example\.com$/) { (0) if (&User-Name =~ /^(.*)@example\.com$/) -> FALSE (0) } # policy filter_uuid = notfound (0) policy filter_google_otp { (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) { (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) -> TRUE (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) { (0) update request { (0) EXPAND %{2} (0) --> 831041 (0) &Google-Password := 831041 (0) EXPAND %{1} (0) --> Password (0) &User-Password := Password (0) } # update request = noop (0) } # if (&User-Password =~ /^(.*)([0-9]{6})$/) = noop (0) } # policy filter_google_otp = noop (0) [preprocess] = ok (0) [chap] = noop (0) [mschap] = noop (0) [digest] = noop (0) suffix: Checking for suffix after "@" (0) suffix: No '@' in User-Name = "my_user", looking up realm NULL (0) suffix: No such realm "NULL" (0) [suffix] = noop (0) eap: No EAP-Message, not doing EAP (0) [eap] = noop (0) files: Searching for user in group "LAN_Network_Admins" rlm_ldap (ldap): Reserved connection (0) (0) files: EXPAND (samaccountname=%{%{Stripped-User-Name}:-%{User-Name}}) (0) files: --> (samaccountname=my_user) (0) files: Performing search in "DC=office,DC=my,DC=lan" with filter "(samaccountname=my_user)", scope "sub" (0) files: Waiting for search result... rlm_ldap (ldap): Rebinding to URL ldaps://DomainDnsZones.office.my.lan/DC=DomainDnsZones,DC=office,DC=my,DC=lan rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) files: User object found at DN "CN=test ldap,OU=Network,OU=Level3,OU=Admins,OU=NEOXAN,OU=Management,OU=Accounts,DC=office,DC=my,DC=lan" (0) files: Checking for user in group objects (0) files: EXPAND (&(CN=LAN_Network_Admins,OU=Organization,OU=Groups,DC=office,DC=my,DC=lan=LAN_Network_Admins)(objectClass=GroupOfNames)(|(&(objectClass=GroupOfNames)(member=%{control:Ldap-UserDn}))(&(objectClass=GroupOfNames)(member=%{control:Ldap-UserDn})))) (0) files: --> (&(CN=LAN_Network_Admins,OU=Organization,OU=Groups,DC=office,DC=my,DC=lan=LAN_Network_Admins)(objectClass=GroupOfNames)(|(&(objectClass=GroupOfNames)(member=CN\3dtest ldap\2cOU\3dNetwork\2cOU\3dLevel3\2cOU\3dAdmins\2cOU\3dNEOXAN\2cOU\3dManagement\2cOU\3dAccounts\2cDC\3doffice\2cDC\3dmy\2cDC\3dlan))(&(objectClass=GroupOfNames)(member=CN\3dtest ldap\2cOU\3dNetwork\2cOU\3dLevel3\2cOU\3dAdmins\2cOU\3dNEOXAN\2cOU\3dManagement\2cOU\3dAccounts\2cDC\3doffice\2cDC\3dmy\2cDC\3dlan)))) (0) files: Waiting for bind result... (0) files: Bind successful (0) files: Performing search in "DC=office,DC=my,DC=lan" with filter "(&(CN=LAN_Network_Admins,OU=Organization,OU=Groups,DC=office,DC=my,DC=lan=LAN_Network_Admins)(objectClass=GroupOfNames)(|(&(objectClass=GroupOfNames)(member=CN\3dtest ldap\2cOU\3dNetwork\2cOU\3dLevel3\2cOU\3dAdmins\2cOU\3dNEOXAN\2cOU\3dManagement\2cOU\3dAccounts\2cDC\3doffice\2cDC\3dmy\2cDC\3dlan))(&(objectClass=GroupOfNames)(member=CN\3dtest ldap\2cOU\3dNetwork\2cOU\3dLevel3\2cOU\3dAdmins\2cOU\3dNEOXAN\2cOU\3dManagement\2cOU\3dAccounts\2cDC\3doffice\2cDC\3dmy\2cDC\3dlan))))", scope "sub" (0) files: Waiting for search result... rlm_ldap (ldap): Rebinding to URL ldaps://DomainDnsZones.office.my.lan/DC=DomainDnsZones,DC=office,DC=my,DC=lan rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) files: Search returned no results (0) files: Checking user object's memberOf attributes (0) files: Waiting for bind result... (0) files: Bind successful (0) files: Performing unfiltered search in "CN=test ldap,OU=Network,OU=Level3,OU=Admins,OU=NEOXAN,OU=Management,OU=Accounts,DC=office,DC=my,DC=lan", scope "base" (0) files: Waiting for search result... (0) files: Processing memberOf value "CN=SG_NEOXAN_Users,OU=Shadow Groups,OU=Management,OU=Groups,DC=office,DC=my,DC=lan" as a DN (0) files: Resolving group DN "CN=SG_NEOXAN_Users,OU=Shadow Groups,OU=Management,OU=Groups,DC=office,DC=my,DC=lan" to group name (0) files: Performing unfiltered search in "CN=SG_NEOXAN_Users,OU=Shadow Groups,OU=Management,OU=Groups,DC=office,DC=my,DC=lan", scope "base" (0) files: Waiting for search result... (0) files: ERROR: No CN=LAN_Network_Admins,OU=Organization,OU=Groups,DC=office,DC=my,DC=lan attributes found in object rlm_ldap (ldap): Deleting connection (0) - Was referred to a different LDAP server Need 6 more connections to reach 10 spares rlm_ldap (ldap): Opening additional connection (5), 1 of 28 pending slots used rlm_ldap (ldap): Connecting to ldaps://my-dc-01.office.my.lan:636 rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) files: User is not a member of "LAN_Network_Admins" (0) files: users: Matched entry DEFAULT at line 5 (0) [files] = ok rlm_ldap (ldap): Reserved connection (1) (0) ldap: EXPAND (samaccountname=%{%{Stripped-User-Name}:-%{User-Name}}) (0) ldap: --> (samaccountname=my_user) (0) ldap: Performing search in "DC=office,DC=my,DC=lan" with filter "(samaccountname=my_user)", scope "sub" (0) ldap: Waiting for search result... rlm_ldap (ldap): Rebinding to URL ldaps://DomainDnsZones.office.my.lan/DC=DomainDnsZones,DC=office,DC=my,DC=lan rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) ldap: User object found at DN "CN=test ldap,OU=Network,OU=Level3,OU=Admins,OU=NEOXAN,OU=Management,OU=Accounts,DC=office,DC=my,DC=lan" (0) ldap: Processing user attributes (0) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute (0) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure) rlm_ldap (ldap): Deleting connection (1) - Was referred to a different LDAP server (0) [ldap] = ok (0) [expiration] = noop (0) [logintime] = noop (0) pap: WARNING: Auth-Type already set. Not setting to PAP (0) [pap] = noop (0) } # authorize = ok (0) Found Auth-Type = Reject (0) Auth-Type = Reject, rejecting user (0) Failed to authenticate the user (0) Using Post-Auth-Type Reject (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default (0) Post-Auth-Type REJECT { (0) attr_filter.access_reject: EXPAND %{User-Name} (0) attr_filter.access_reject: --> my_user (0) attr_filter.access_reject: Matched entry DEFAULT at line 11 (0) [attr_filter.access_reject] = updated (0) [eap] = noop (0) policy remove_reply_message_if_eap { (0) if (&reply:EAP-Message && &reply:Reply-Message) { (0) if (&reply:EAP-Message && &reply:Reply-Message) -> FALSE (0) else { (0) [noop] = noop (0) } # else = noop (0) } # policy remove_reply_message_if_eap = noop (0) } # Post-Auth-Type REJECT = updated (0) Delaying response for 1.000000 seconds Waking up in 0.2 seconds. Waking up in 0.7 seconds. (0) Sending delayed response (0) Sent Access-Reject Id 67 from 127.0.0.1:1812 to 127.0.0.1:46701 length 20 Waking up in 3.9 seconds. (0) Cleaning up request packet ID 67 with timestamp +16 Ready to process requests Can someone help me? Thanks in advance, best regards, Quentin
On Oct 5, 2021, at 3:25 AM, Quentin Rapin <quentinrapin@gmail.com> wrote:
I'm trying to setup a freeradius v.3.0.20 server using LDAP with MFA (Google authenticator).
3.0.23+ includes a TOTP module, which is compatible with google authenticator.
The LDAP part worked, however, since I added the MFA configuration, it doesn't work anymore, it seems that the password are not even checked against the ldap database (Windows AD). I followed this tutorial to get it working: https://sysopstechnix.com/enable-2fa-on-freeradius-with-openldap-users/
That doesn't seem too bad.
Here is part of the logs :
Ready to process requests (0) Received Access-Request Id 67 from 127.0.0.1:46701 to 127.0.0.1:1812 length 95 (0) User-Name = "my_user" (0) User-Password = "Password831041"
That seems normal.
(0) policy filter_google_otp { (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) { (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) -> TRUE (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) { (0) update request { (0) EXPAND %{2} (0) --> 831041 (0) &Google-Password := 831041 (0) EXPAND %{1} (0) --> Password (0) &User-Password := Password
That's good.
... rlm_ldap (ldap): Rebinding to URL ldaps://DomainDnsZones.office.my.lan/DC=DomainDnsZones,DC=office,DC=my,DC=lan rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) ldap: User object found at DN "CN=test ldap,OU=Network,OU=Level3,OU=Admins,OU=NEOXAN,OU=Management,OU=Accounts,DC=office,DC=my,DC=lan" (0) ldap: Processing user attributes (0) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute (0) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure) rlm_ldap (ldap): Deleting connection (1) - Was referred to a different LDAP server
So the user information wasn't found in LDAP. This has nothing to do with OTP issues. Try using "ldapsearch", as documented in mods-available/ldap Once that works, use the same configuration in FreeRADIUS. Alan DeKok.
3.0.23+ includes a TOTP module, which is compatible with google authenticator.
Great, I checked it out, the example is clear. As said in the documentation, the module takes no configuration items. Does that mean that it is only compatible with google authenticator and knows where to find the file ? I mean it's even not required to indicate the path to the .google_authenticator file.
So the user information wasn't found in LDAP. This has nothing to do with OTP issues.
Try using "ldapsearch", as documented in mods-available/ldap
Once that works, use the same configuration in FreeRADIUS.
Just did that, it works well. I can retrieve the information. What's strange is that ldap authentication worked before I added the TOTP config. Le mar. 5 oct. 2021 à 17:06, Alan DeKok <aland@deployingradius.com> a écrit :
On Oct 5, 2021, at 3:25 AM, Quentin Rapin <quentinrapin@gmail.com> wrote:
I'm trying to setup a freeradius v.3.0.20 server using LDAP with MFA (Google authenticator).
3.0.23+ includes a TOTP module, which is compatible with google authenticator.
The LDAP part worked, however, since I added the MFA configuration, it doesn't work anymore, it seems that the password are not even checked against the ldap database (Windows AD). I followed this tutorial to get it working: https://sysopstechnix.com/enable-2fa-on-freeradius-with-openldap-users/
That doesn't seem too bad.
Here is part of the logs :
Ready to process requests (0) Received Access-Request Id 67 from 127.0.0.1:46701 to 127.0.0.1:1812 length 95 (0) User-Name = "my_user" (0) User-Password = "Password831041"
That seems normal.
(0) policy filter_google_otp { (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) { (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) -> TRUE (0) if (&User-Password =~ /^(.*)([0-9]{6})$/) { (0) update request { (0) EXPAND %{2} (0) --> 831041 (0) &Google-Password := 831041 (0) EXPAND %{1} (0) --> Password (0) &User-Password := Password
That's good.
... rlm_ldap (ldap): Rebinding to URL ldaps://DomainDnsZones.office.my.lan/DC=DomainDnsZones,DC=office,DC=my,DC=lan rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) ldap: User object found at DN "CN=test ldap,OU=Network,OU=Level3,OU=Admins,OU=NEOXAN,OU=Management,OU=Accounts,DC=office,DC=my,DC=lan" (0) ldap: Processing user attributes (0) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute (0) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure) rlm_ldap (ldap): Deleting connection (1) - Was referred to a different LDAP server
So the user information wasn't found in LDAP. This has nothing to do with OTP issues.
Try using "ldapsearch", as documented in mods-available/ldap
Once that works, use the same configuration in FreeRADIUS.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Oct 7, 2021, at 8:42 AM, Quentin Rapin <quentinrapin@gmail.com> wrote:
Great, I checked it out, the example is clear. As said in the documentation, the module takes no configuration items. Does that mean that it is only compatible with google authenticator and knows where to find the file ? I mean it's even not required to indicate the path to the .google_authenticator file.
As the module documentation makes clear, it expects the TOTP secret to be placed in the TOTP-Secret attribute. This means that you can place the secret in a file, or database, or anything else. It's up to you. That's the power of FreeRADIUS.
Just did that, it works well. I can retrieve the information. What's strange is that ldap authentication worked before I added the TOTP config.
Then something changed. Put all of the configuration into revision control. Commit after every change, with a comment of what works, and what doesn't work. You could spend days trying to figure out "it used to work, and now it doesn't why?" Or, you could just revert to a "known working" configuration, and start over. That's generally much, much, faster. Alan DeKok.
participants (2)
-
Alan DeKok -
Quentin Rapin