Hey Stack Overflow folks,
So, here's the deal. We're running a WPA2 business setup, and our users get authenticated through FreeRADIUS, which is using LDAP to check passwords stored in NTLM hash.
We've decided to spice things up a bit and set up a Kerberos server. The plan is to switch FreeRADIUS to use Kerberos for authentication. But, surprise, surprise, we're hitting a wall.
I've Googled my heart out and tried a bunch of solutions (adding realms, tweaking proxies, etc.), but nothing seems to stick. Now I set up a fresh FreeRADIUS and tweaked it to the extent that I expect it to work. I've attached the output/config files for your perusal, and if you don't see a specific file that you expect, it means we're using default settings. (I have also removed some default output/config lines so that I could meet character limit and avoid getting "This looks like a spam" error for this question so if you need anything else more, let me know)
My gut feeling is that FreeRADIUS is struggling to find the Kerberos Auth-Type to do its magic (according to the log files), although I've put the related configurations in place with the sites config files, but no luck.
Any ideas or tricks up your sleeves to get FreeRADIUS to play nice with Kerberos? I'm all ears.
P.S. In order to show that Freeradius is working, I have also authenticated bob (freeradisu test user) in my test and you can find the logs below as well. But neither myuser@MYDOMAIN.COM
nor myuser
are working although the principal myuser
exists in kdc1.mydomain.com
.
mods-enabled/krb5
krb5 {
keytab = /etc/krb5.keytab
service_principal = radius/myhost.mydomain.com
...
}
sites-enabled/default
server default {
...
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
Auth-Type Kerberos {
krb5
}
eap
}
...
}
sites-enabled/inner-tunnel
server inner-tunnel {
...
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
Auth-Type Kerberos {
krb5
}
eap
}
...
}
freeradius -X
FreeRADIUS Version 3.0.26
Copyright (C) 1999-2021 The FreeRADIUS server project and contributors
...
# Loaded module rlm_krb5
# Loading module "krb5" from file /etc/freeradius/3.0/mods-enabled/krb5
krb5 {
keytab = "/etc/krb5.keytab"
service_principal = "radius/myhost.mydomain.com"
}
...
radiusd: #### Loading Virtual Servers ####
server { # from file /etc/freeradius/3.0/radiusd.conf
} # server
server inner-tunnel { # from file /etc/freeradius/3.0/sites-enabled/inner-tunnel
# Loading authenticate {...}
Compiling Auth-Type PAP for attr Auth-Type
Compiling Auth-Type CHAP for attr Auth-Type
Compiling Auth-Type MS-CHAP for attr Auth-Type
Compiling Auth-Type Kerberos for attr Auth-Type
# Loading authorize {...}
Ignoring "sql" (see raddb/mods-available/README.rst)
Ignoring "ldap" (see raddb/mods-available/README.rst)
# Loading session {...}
# Loading post-proxy {...}
# Loading post-auth {...}
# Skipping contents of 'if' as it is always 'false' -- /etc/freeradius/3.0/sites-enabled/inner-tunnel:339
Compiling Post-Auth-Type REJECT for attr Post-Auth-Type
} # server inner-tunnel
server default { # from file /etc/freeradius/3.0/sites-enabled/default
# Loading authenticate {...}
Compiling Auth-Type PAP for attr Auth-Type
Compiling Auth-Type CHAP for attr Auth-Type
Compiling Auth-Type MS-CHAP for attr Auth-Type
Compiling Auth-Type Kerberos for attr Auth-Type
# Loading authorize {...}
Compiling Autz-Type New-TLS-Connection for attr Autz-Type
# Loading preacct {...}
# Loading accounting {...}
# Loading post-proxy {...}
# Loading post-auth {...}
Compiling Post-Auth-Type REJECT for attr Post-Auth-Type
Compiling Post-Auth-Type Challenge for attr Post-Auth-Type
Compiling Post-Auth-Type Client-Lost for attr Post-Auth-Type
} # server default
radiusd: #### Opening IP addresses and Ports ####
listen {
type = "auth"
ipaddr = 127.0.0.1
port = 18120
}
listen {
type = "auth"
ipaddr = *
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
type = "acct"
ipaddr = *
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
type = "auth"
ipv6addr = ::
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
type = "acct"
ipv6addr = ::
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
Listening on auth address 127.0.0.1 port 18120 bound to server inner-tunnel
Listening on auth address * port 1812 bound to server default
Listening on acct address * port 1813 bound to server default
Listening on auth address :: port 1812 bound to server default
Listening on acct address :: port 1813 bound to server default
Listening on proxy address * port 57046
Listening on proxy address :: port 48368
Ready to process requests
(0) Received Access-Request Id 162 from 127.0.0.1:48852 to 127.0.0.1:1812 length 73
(0) User-Name = "bob"
(0) User-Password = "hello"
(0) NAS-IP-Address = 127.0.1.1
(0) NAS-Port = 1812
(0) Message-Authenticator = 0x7894a2aa45e6b0d3621da2cd35e5ff1d
(0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default
(0) authorize {
(0) policy filter_username {
...
(0) } # if (&User-Name) = notfound
(0) } # policy filter_username = notfound
(0) [preprocess] = ok
(0) [chap] = noop
(0) [mschap] = noop
(0) [digest] = noop
(0) suffix: Checking for suffix after "@"
(0) suffix: No '@' in User-Name = "bob", 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: users: Matched entry bob at line 207
(0) [files] = ok
(0) [expiration] = noop
(0) [logintime] = noop
(0) [pap] = updated
(0) } # authorize = updated
(0) Found Auth-Type = PAP
(0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default
(0) Auth-Type PAP {
(0) pap: Login attempt with password
(0) pap: Comparing with "known good" Cleartext-Password
(0) pap: User authenticated successfully
...
(0) Finished request
Waking up in 4.9 seconds.
(0) Cleaning up request packet ID 162 with timestamp +10 due to cleanup_delay was reached
Ready to process requests
(1) Received Access-Request Id 137 from 127.0.0.1:59059 to 127.0.0.1:1812 length 91
(1) User-Name = "myuser@MYDOMAIN.COM"
(1) User-Password = "mypassword"
(1) NAS-IP-Address = 127.0.1.1
(1) NAS-Port = 1812
(1) Message-Authenticator = 0x019a1ace5301cf741365042877d3b08b
(1) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default
(1) authorize {
(1) policy filter_username {
...
(1) } # if (&User-Name) = notfound
(1) } # policy filter_username = notfound
(1) [preprocess] = ok
(1) [chap] = noop
(1) [mschap] = noop
(1) [digest] = noop
(1) suffix: Checking for suffix after "@"
(1) suffix: Looking up realm "MYDOMAIN.COM" for User-Name = "myuser@MYDOMAIN.COM"
(1) suffix: No such realm "MYDOMAIN.COM"
(1) [suffix] = noop
(1) eap: No EAP-Message, not doing EAP
(1) [eap] = noop
(1) [files] = noop
(1) [expiration] = noop
(1) [logintime] = noop
(1) pap: WARNING: No "known good" password found for the user. Not setting Auth-Type
(1) pap: WARNING: Authentication will fail unless a "known good" password is available
(1) [pap] = noop
(1) } # authorize = ok
(1) ERROR: No Auth-Type found: rejecting the user via Post-Auth-Type = Reject
(1) Failed to authenticate the user
(1) Using Post-Auth-Type Reject
...
Waking up in 0.3 seconds.
Waking up in 0.6 seconds.
(1) Sending delayed response
(1) Sent Access-Reject Id 137 from 127.0.0.1:1812 to 127.0.0.1:59059 length 20
Waking up in 3.9 seconds.
(1) Cleaning up request packet ID 137 with timestamp +18 due to cleanup_delay was reached
Ready to process requests
(2) Received Access-Request Id 199 from 127.0.0.1:51213 to 127.0.0.1:1812 length 76
(2) User-Name = "myuser"
(2) User-Password = "mypassword"
(2) NAS-IP-Address = 127.0.1.1
(2) NAS-Port = 1812
(2) Message-Authenticator = 0x0535e0799d3002096b71b8e5476aefbc
(2) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default
(2) authorize {
(2) policy filter_username {
...
(2) } # if (&User-Name) = notfound
(2) } # policy filter_username = notfound
(2) [preprocess] = ok
(2) [chap] = noop
(2) [mschap] = noop
(2) [digest] = noop
(2) suffix: Checking for suffix after "@"
(2) suffix: No '@' in User-Name = "myuser", looking up realm NULL
(2) suffix: No such realm "NULL"
(2) [suffix] = noop
(2) eap: No EAP-Message, not doing EAP
(2) [eap] = noop
(2) [files] = noop
(2) [expiration] = noop
(2) [logintime] = noop
(2) pap: WARNING: No "known good" password found for the user. Not setting Auth-Type
(2) pap: WARNING: Authentication will fail unless a "known good" password is available
(2) [pap] = noop
(2) } # authorize = ok
(2) ERROR: No Auth-Type found: rejecting the user via Post-Auth-Type = Reject
(2) Failed to authenticate the user
(2) Using Post-Auth-Type Reject
...
Waking up in 0.3 seconds.
Waking up in 0.6 seconds.
(2) Sending delayed response
(2) Sent Access-Reject Id 199 from 127.0.0.1:1812 to 127.0.0.1:51213 length 20
Waking up in 3.9 seconds.
(2) Cleaning up request packet ID 199 with timestamp +34 due to cleanup_delay was reached
Ready to process requests
I expect myuser
to be authenticated via either of the following test commands (I used the same commands for the above tests):
radtest myuser@MYDOMAIN.COM mypassword localhost 1812 testing123
or
radtest myuser mypassword localhost 1812 testing123
So I finally found out how to get this sorted.
You don't need to change sites-enabled/inner-tunnel
file at all so restore it to its initial state. You should only need to edit default site (sites-enabled/default
) as follows:
authorize {
...
if (&User-Password) {
update control {
&Auth-Type = Kerberos
}
}
pap
...
}
authenticate {
Auth-Type Kerberos {
krb5
}
Auth-Type PAP {
pap
}
...
}
Disclaimer:
This is not a secure and optimised configuration. I just wanted to let you know how the configuration should look like so that the command radtest myuser mypassword localhost 1812 testing123
can authenticate your kerberos principal myuser
against your Kerberos server. So feel free to align it to suit your needs.