FreeRadius with Google Workspace LDAP
This was the first time I used FreeRadius. This program reminds me of Postfix — a similarly complicated and powerful tool. Only one big difference: very poor documentation and not enough examples. In the mailing lists there are many questions without answers from FreeRadius gurus. Here I provide examples of how I solved some problems or where I spent too much time…
Remark: I love Postfix. My favorite book is The Book of Postfix. Read it!
Returning to FreeRadius. My task was to authorize and authenticate WiFi users from Google Workspace via LDAP. FreeRadius was the first thing I tried because WiFi with LDAP should be very easy… Yes? — No!
Step 1 (Access to LDAP)
All credentials can be created in Google Admin Console > Apps > LDAP. You need certificates and access credentials (username and password).
Step 2 (Test)
I made all tests with ldapsearch.
LDAPTLS_CERT=Google_2024.crt LDAPTLS_KEY=Google_2024.key \
ldapsearch -H ldaps://ldap.google.com \
-b dc=domain,dc=com '(mail=test1@a.domain.com)'
LDAPTLS_CERT=Google_2024.crt LDAPTLS_KEY=Google_2024.key \
ldapsearch -H ldaps://ldap.google.com \
-b dc=a,dc=domain,dc=com '(mail=test1@a.domain.com)'
Both commands return the same good result with different DN’s.
dn: uid=test1,ou=Users,ou=Teachers,ou=Users,dc=domain,dc=com
dn: uid=test1,ou=Users,ou=Teachers,ou=Users,dc=a,dc=domain,dc=com
And correct membership.
memberOf: cn=group_allow_wifi,ou=Groups,dc=domain,dc=com
Auth test.
LDAPTLS_CERT=Google_2024.crt LDAPTLS_KEY=Google_2024.key \
ldapsearch -H ldaps://ldap.google.com -w test1pass2 \
-D "uid=test1,ou=Users,dc=p,dc=domain,dc=com" \
-b "dc=domain,dc=com" '(mail=test1@p.domain.com)'
All good, move forward.
Step 3 (Hello FreeRadius)
First difference: Google Workspace is not Active Directory — the devil is in the details. Second difference from many manuals: my Google Workspace configuration. I have a few subdomains.
Main: domain.com
Trusted users: a.domain.com
Other: b.domain.com
For historical reasons, emails for the main domain are not in Google Workspace, so domain.com does not have users at all.
Example of how it should be according to documentation:
ldap {
server = 'ldaps://ldap.google.com:636'
identity = 'ou=admins,dc=domain,dc=com'
base_dn = 'dc=domain,dc=com'
...
user {
filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
...
}
...
}
But it’s not correct for Google Workspace. A working example:
ldap {
server = 'ldaps://ldap.google.com:636'
identity = Username
password = Password
Tmp-String-0 = "%{exec:/etc/raddb/mdn.sh %{User-Name}}"
base_dn = "dc=${Tmp-String-0},dc=domain,dc=com"
...
user {
filter = "(mail=%{%{Stripped-User-Name}:-%{User-Name}})"
...
}
...
}
# cat mdn.sh
#!/bin/bash
logger -t mdn "$1"
base_dn="null"
username="$1"
if [[ $username =~ @a\.domain\.com$ ]]; then
base_dn="a"
fi
if [[ $username =~ @b\.domain\.com$ ]]; then
base_dn="b"
fi
echo "$base_dn"
exit 0
All symbols like "=" or "." after returning to FreeRadius will be escaped.
echo "dn=a,dn=domain,dn=com" -> echo "dn\=a\,dn\=domain\,dn\=com"
Because of that I use only one symbol.
Here on top of the certificate you need a username and password from Google Admin Console. But that’s not all. Remember different DN’s? Here is the problem. How does user validation work? First we search for the user, then try the user password. For the second step we need the correct DN.
I didn’t find another way to make DN dynamic except using exec modules. BTW, two additional approaches can be used to solve this problem: templates and multiple LDAP instances. But templates do not work in the LDAP section, and multiple LDAP sections cannot be used with EAP. Maybe I missed something… but it’s not relevant anymore.
UID is the wrong filter because the same UID can exist in multiple domains. The best way is to use email (username). Also, Tmp-String-0 is not just a variable name — String here is a type.
Remark: like i = integer, s = string… A pointer to programming origins… “i” — fifty years on the counter market :)
In sites-enabled/default for multiple LDAP you can use:
Auth-Type LDAP {
if (User-Name =~ /@a\.domain\.com$$/) {
ldap-a-domain-com
}
if (User-Name =~ /@b\.domain\.com$$/) {
ldap-b-domain-com
}
}
And you can check the WiFi group.
if (&ldap-a-domain-com-LDAP-Group == "wifi_group1") {
# noop
} elsif (&ldap-b-domain-com-LDAP-Group == "wifi_group2") {
# noop
} else {
reject
}
“$$” and “&” in if() are not misspellings. This cost me one day. Also “noop” means skip this step — wrong result.
But you cannot use it with EAP. Because for EAP you need to remove “Auth-Type LDAP {}”. As a result, any if statements do not work.
Step 4 (Goodbye FreeRadius)
After all tests, PAP (Password Authentication Protocol) was configured and worked perfectly. On top of that EAP+TTLS (Extensible Authentication Protocol). Radius was connected as an auth server for the WiFi access point.
All tests with iPhone passed — no configuration required. Just find the SSID, enter username and password — works fine. On Android you need to choose some options — not great, but OK.
But when I started testing on different Windows versions, I stopped moving in this direction. Maybe for some companies with Active Directory this solution is acceptable, but in my case it requires too complicated a configuration for the end user.
Next solution I tried — First Look at UniFi Wireless Access Point.
Me gusto mucho tu publicación, si tienes un video explicativo te lo agradeceria grandemente
ReplyDelete