FreeRadius and Google Workspace LDAP

This is the first time when I used FreeRadius, this program reminds me of Postfix, I mean similar complicated and powerful tool. Only one big difference - very bad documentation and not enough examples. In the maillists a lot of questions without answers from FreeRadius guru. Here I provided examples of how I solved some problems or where I took too much time…

Remark: I love postfix, my favorite book is The Book of Postfix. Read it!

Returning to FreeRadius. My task was - authorize and authenticate WiFi users from Google Workspace via LDAP. FreeRadius is 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 from 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 command return 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 an Active Directory - The Devil is in details. Second difference from many manuals - my Google Workspace configuration. I have few subdomains.

Main: domain.com
Trusted users: a.domain.com
Other: b.domain.com

For historical reasons emails for the main domain is not in Google Workspace, so domain.com does not have users at all.

Example how should be by 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 with Google Workspace. Good 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"
"dn\=a\,dn\=domain\,dn\=com"
Because why do I use only one simbol.

Here on top of the certificate you need username and password from Google Admin Console. But it’s not all, remember, different DN’s? Here is a problem. How does user validation work? First we search for users, then try user passwords. For the second step we need correct DN. I don't find another way to make DN dynamic, only exec modules. BTW, two additional ways can be used for solving this problem. Templates and multiple LDAP cases. But templates do not work in the LDAP section, multiple LDAP sections can not be used with EAP. Maybe I miss something… but it’s not actual anymore… UID is wrong filter. Because the same UID can be in few domains, the best way is to use email (username). Also, Tmp-String-0, not just variable name, String here is a type.

Remark: Like i=integer, s=string… Pointer to programming beginning... “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-comain-com
    }
}
And you can check 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() - is not misspelling. This cost me one day. Also “noop” means skip this step - wrong result.
But you can not use it with EAP. Because for EAP you need remove “Auth-Type LDAP {}”. As a result any if’s not work.

Step 3 (Goodbye FreeRadius)

After all tests PAP (Password Authentication Protocol) was configured and worked perfect. On top EAP+TTLS (Extensible Authentication Protocol). Radius was connected as an auth server for WiFi access point. All tests with iPhone passed, no need any configuration, just find SSID, enter username and password - work fine. With Android you need to choose some options, not good, but OK… But when I started tests on different Windows versions - I stopped moving to this direction. Maybe for some companies with Active Directory this solution is acceptable, but in my case - too complicated a configuration for the end user.

Next solution with I try - UniFi Wireless Access Point with Captive Portal

Comments

Popular posts from this blog

Redis with failover replication