FreeRadius / EAP-TLS: Client certificate cannot be found
-
Yeah, but what setting?
I think it cannot be within the Interfaces or NAS/Clients settings, since I can successfully authenticate with username/password. So that leaves us the Users and EAP settings, right?
In EAP I have specified:
- disabled Weak EAP types
- TLS as default EAP type
- SSL CA Certificate "A Root CA" [imported in client Local Machine as Trusted Root CA vault]
- SSL Server Certificate "A Server Certificate" [imported in client Local Machine in Personal vault]
- All other in default settings
In Users settings I have tried to enter the Username in the same formats that can be seen in Radius syslog error messages when authentication is rejected (both in the hostname and in the email formats), all other fields in default values.
Do you happen know the exact steps to start radiusd in debug mode within pfSense GUI so that I could possibly get more info on the authentication reject reason?
Do you happen to know the exact format how the Username field in Radiusd configuration vs. CN etc. fields in the certificate have to be set to guarantee a match?
Do you happen to know in which format the client andr server certificates as well as the CA must be imported in the client (i.e. .crt / .p12, and why, if the format matters?)
-
A. To run Radius in debug mode , you need To
1. stop Radius service
/Status/Services
2. in the console type
radiusd -X
B.
C. (Mac OS)
Result
Fri Nov 29 16:39:45 2019 : Auth: (3181) Login OK: [macbookpro2015.XYZ.org/<via Auth-Type = eap>] (from client Asus_WRT port 110 cli 9801a78ceb89) Fri Nov 29 16:41:30 2019 : Auth: (3186) Login OK: [sony_xperia.XYZ.org/<via Auth-Type = eap>] (from client es.XYZ.org port 473 cli 176.AB.CD.67[55742])
-
@Konstanti Thank you for your examples!
The only menaningful difference btw your configuration and mine seems to be that you have imported the client certificate as a .p12 archive which (as far as I understand) contains also the private key, whereas I have imported the .crt file.
If I export the client cert from Cert.Manager and import it into the client, Windows asks me to enter the password with which the private key was protected, but I have not been able to find a way to specify the password for the private key in Cert.Manager. How did you do that?
I also seem to be getting somewhat inconsistent results in my authorization tests, i.e. not the same results each time I try to authorize. For the last few hours I have been trying only the wireless network since @johnpoz mentioned that he has experience with only that...
I have tried with two clients using different configurations, and I have got e.g. following results:
Case a)
Waking up in 4.9 seconds.
(1) Received Access-Request Id 186 from 10.16.1.105:45863 to 10.16.1.1:1812 length 385
(1) User-Name = "host/xxxxxxxxxxxxxxx"
(1) NAS-Identifier = "xxxxxxxxxxxxxx"
(1) Called-Station-Id = "XX-XX-XX:XXX_XXX"
(1) NAS-Port-Type = Wireless-802.11
(1) Service-Type = Framed-User
(1) Calling-Station-Id = "XX-XX-XX"
(1) Connect-Info = "CONNECT 0Mbps 802.11b"
(1) Acct-Session-Id = "XXXXXXXXXXX"
(1) WLAN-Pairwise-Cipher = 1027076
(1) WLAN-Group-Cipher = 1027076
(1) WLAN-AKM-Suite = 1027073
(1) Framed-MTU = 1400
(1) EAP-Message = 0xxxxxx...
(1) State = 0xfe5ef851fec1f531117b750213ef0752
(1) Message-Authenticator = 0xdf7173c3453436c0a6827cedf4c2427d
(1) session-state: No cached attributes
(1) # Executing section authorize from file /usr/local/etc/raddb/sites-enabled/default
(1) authorize {
(1) [preprocess] = ok
(1) [chap] = noop
(1) [mschap] = noop
(1) [digest] = noop
(1) suffix: Checking for suffix after "@"
(1) suffix: No '@' in User-Name = "host/xxxxxxxxxxxxxxx", skipping NULL due to config.
(1) [suffix] = noop
(1) ntdomain: Checking for prefix before ""
(1) ntdomain: No '' in User-Name = "host/xxxxxxxxxxxxxxxxxx", skipping NULL due to config.
(1) [ntdomain] = noop
(1) eap: Peer sent EAP Response (code 2) ID 159 length 166
(1) eap: No EAP Start, assuming it's an on-going EAP conversation
(1) [eap] = updated
(1) files: users: Matched entry host/xxxxxxxxxxxxxxxxxx at line 17
(1) [files] = ok
rlm_counter: Entering module authorize code
rlm_counter: Could not find Check item value pair
(1) [daily] = noop
rlm_counter: Entering module authorize code
rlm_counter: Could not find Check item value pair
(1) [weekly] = noop
rlm_counter: Entering module authorize code
rlm_counter: Could not find Check item value pair
(1) [monthly] = noop
rlm_counter: Entering module authorize code
rlm_counter: Could not find Check item value pair
(1) [forever] = noop
(1) if (&request:Calling-Station-Id == &control:Calling-Station-Id) {
(1) ERROR: Failed retrieving values required to evaluate condition
(1) [expiration] = noop
(1) [logintime] = noop
(1) pap: WARNING: Auth-Type already set. Not setting to PAP
(1) [pap] = noop
(1) } # authorize = updatedCase b)
Ready to process requests
(0) Received Access-Request Id 196 from 10.16.1.105:45863 to 10.16.1.1:1812 length 200
(0) User-Name = "host/XX"
(0) NAS-Identifier = "xxxxxxxxxxx"
(0) Called-Station-Id = "XX-XX-XX:XX_XXX"
(0) NAS-Port-Type = Wireless-802.11
(0) Service-Type = Framed-User
(0) Calling-Station-Id = "XX-XX-XX"
(0) Connect-Info = "CONNECT 0Mbps 802.11b"
(0) Acct-Session-Id = "XXXXXXXXXX"
(0) WLAN-Pairwise-Cipher = 1027076
(0) WLAN-Group-Cipher = 1027076
(0) WLAN-AKM-Suite = 1027073
(0) Framed-MTU = 1400
(0) EAP-Message = 0x02xxxxxxxxxxxxx
(0) Message-Authenticator = 0xdxxxxxxxxxxxxxxx
(0) # Executing section authorize from file /usr/local/etc/raddb/sites-enabled/default
(0) authorize {
(0) [preprocess] = ok
(0) [chap] = noop
(0) [mschap] = noop
(0) [digest] = noop
(0) suffix: Checking for suffix after "@"
(0) suffix: No '@' in User-Name = "host/XX", skipping NULL due to config.
(0) [suffix] = noop
(0) ntdomain: Checking for prefix before ""
(0) ntdomain: No '' in User-Name = "host/XX", skipping NULL due to config.
(0) [ntdomain] = noop
(0) eap: Peer sent EAP Response (code 2) ID 68 length 12
(0) eap: EAP-Identity reply, returning 'ok' so we can short-circuit the rest of authorize
(0) [eap] = ok
(0) } # authorize = ok
(0) Found Auth-Type = eap
(0) # Executing group from file /usr/local/etc/raddb/sites-enabled/default
(0) authenticate {
(0) eap: Peer sent packet with method EAP Identity (1)
(0) eap: Calling submodule eap_tls to process data
(0) eap_tls: Initiating new EAP-TLS session
(0) eap_tls: Setting verify mode to require certificate from client
(0) eap_tls: [eaptls start] = request
(0) eap: Sending EAP Request (code 1) ID 69 length 6
(0) eap: EAP session adding &reply:State = 0x6a7e65856a3b682d
(0) [eap] = handled
(0) } # authenticate = handled
(0) Using Post-Auth-Type Challenge
(0) # Executing group from file /usr/local/etc/raddb/sites-enabled/default
(0) Challenge { ... } # empty sub-section is ignored
(0) Sent Access-Challenge Id 196 from 10.16.1.1:1812 to 10.16.1.105:45863 length 0
(0) EAP-Message = 0x014500060d20
(0) Message-Authenticator = 0x00000000000000000000000000000000
(0) State = 0x6a7e65856a3b682d8e67b5cd26b0f8d7
(0) Finished request
Waking up in 4.9 seconds.
(0) Cleaning up request packet ID 196 with timestamp +171
Ready to process requestsCase c)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! EAP session with state 0x6a7e65856a3b682d8e67b5cd26b0f8d7 did not finish! !!
!! Please read http://wiki.freeradius.org/guide/Certificate_Compatibility !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!And yeah, I went to see the above mentioned freeradius wiki page and followed several chains of hyperlinks, but to no avail...
-
your going to want the key - yeah if your client will not allow you to import the p12 without a password... Just use opensl to do that..
https://docs.netgate.com/pfsense/en/latest/packages/using-eap-and-peap-with-freeradius.html
openssl pkcs12 -export -certfile ca.crt -in user.crt -inkey user.key -out user.p12
This is a requirement to get say iphone to import.. Pretty sure the wording on that doc, is mine from the old wiki ;) There are for sure some old threads around here where that was discussed putting password on .p12 since some clients will not allow import of it without password on it.
-
Here I just fired up debug
Ready to process requests (0) Received Access-Request Id 46 from 192.168.2.2:54594 to 192.168.2.253:1812 length 218 (0) User-Name = "i5-win.local.lan" (0) NAS-Identifier = "802aa8144f07" (0) Called-Station-Id = "80-2A-A8-14-4F-07:unifi-ent" (0) NAS-Port-Type = Wireless-802.11 (0) Service-Type = Framed-User (0) Calling-Station-Id = "38-59-F9-5F-63-C1" (0) Connect-Info = "CONNECT 0Mbps 802.11b" (0) Acct-Session-Id = "CE20F0FE770BE285" (0) WLAN-Pairwise-Cipher = 1027076 (0) WLAN-Group-Cipher = 1027076 (0) WLAN-AKM-Suite = 1027073 (0) Framed-MTU = 1400 (0) EAP-Message = 0x022f00150169352d77696e2e6c6f63616c2e6c616e (0) Message-Authenticator = 0x4e601cac6b1b7beb7d8b7a1515aaeb9f (0) # Executing section authorize from file /usr/local/etc/raddb/sites-enabled/default (0) authorize { (0) [preprocess] = ok (0) [chap] = noop (0) [mschap] = noop (0) [digest] = noop (0) suffix: Checking for suffix after "@" (0) suffix: No '@' in User-Name = "i5-win.local.lan", skipping NULL due to config. (0) [suffix] = noop (0) ntdomain: Checking for prefix before "\" (0) ntdomain: No '\' in User-Name = "i5-win.local.lan", skipping NULL due to config. (0) [ntdomain] = noop (0) eap: Peer sent EAP Response (code 2) ID 47 length 21 (0) eap: EAP-Identity reply, returning 'ok' so we can short-circuit the rest of authorize (0) [eap] = ok (0) } # authorize = ok (0) Found Auth-Type = eap (0) # Executing group from file /usr/local/etc/raddb/sites-enabled/default (0) authenticate { (0) eap: Peer sent packet with method EAP Identity (1) (0) eap: Calling submodule eap_tls to process data (0) eap_tls: Initiating new EAP-TLS session (0) eap_tls: Setting verify mode to require certificate from client (0) eap_tls: [eaptls start] = request (0) eap: Sending EAP Request (code 1) ID 48 length 6 (0) eap: EAP session adding &reply:State = 0xd6e29e6ad6d29369 (0) [eap] = handled (0) } # authenticate = handled (0) Using Post-Auth-Type Challenge (0) # Executing group from file /usr/local/etc/raddb/sites-enabled/default (0) Challenge { ... } # empty sub-section is ignored (0) Sent Access-Challenge Id 46 from 192.168.2.253:1812 to 192.168.2.2:54594 length 0 (0) EAP-Message = 0x013000060d20 (0) Message-Authenticator = 0x00000000000000000000000000000000 (0) State = 0xd6e29e6ad6d29369189a0f067167850f (0) Finished request
How did you ever think it would work without the key on the client??? You need to install the key on the client as well..
-
well.... as I said, I'm neither a network specialist nor a security specialist...
The docs say that "if space does not work you can add a password..." So I assume that the openssl pkcs12 -export command adds a password to the .p12 file when exporting the cert?
I must apologize for my ignorance, but I'm not sure about how I should make the correct openssl command in my case. I understand the "-out user.p12" and the "-export", but the rest...
Or maybe the Cert.Manager database is a set of flat files in certain directory? Then I only need to figure out the directory where to execute the command... So ca.crt is the CA, user.crt is the client certificate, user.key is the private key for user.crt... but how to specify the password?
-
download the certs and key to your machine - and run openssl there, don't try and do it on pfsense directly.
Openssl will run on anything windows, mac, linux... Guess you can put the files directly on pfsense - but no your not going to find them stored as files - they are in the xml config file..
-
@DaveU said in FreeRadius / EAP-TLS: Client certificate cannot be found:
The docs say that "if space does not work you can add a password..." So I assume that the openssl pkcs12 -export command adds a password to the .p12 file when exporting the cert?
I must apologize for my ignorance, but I'm not sure about how I should make the correct openssl command in my case. I understand the "-out user.p12" and the "-export", but the rest...
Or maybe the Cert.Manager database is a set of flat files in certain directory? Then I only need to figure out the directory where to execute the command... So ca.crt is the CA, user.crt is the client certificate, user.key is the private key for user.crt... but how to specify the password?openssl pkcs12 -in peerCert.pem -inkey peerKey.pem -certfile caCert.pem -export -out peer.p12
-
@johnpoz @Konstanti thank you both for your kind assistance and patience with me!
It was just as I anticipated in my OP ("I must have done some beginner's error but seem to be blind for that..."). I only missed that part of pfSense documentation which mentioned about some clients refusing to load the .p12 file without password - and that I should use openssl in my Windows workstation to create the .p12 archive with a password.
With that information pointed to me, I was able to do my first certificate based EAP-TLS authentication over WLAN a few minutes ago. I think now I might have all the pieces I need to complete my configuration.
Tomorrow I'll proceed to the wired connections and will also play a little around with the user vs. device authentication using EAP-MSCHAP v2... (today I was able to use user authentication but for some reason not the device authentication, and I'd like to understand why...)
But anyway, thank you so much!
-
After playing around for a little while I made an interesting discovery that I have not been able to find an explanation to...
FreeRadius EAP Settings has a check box "Check Client Certificate CN" ("When enabled, the Common Name of the client certificate must match the username set in 'FreeRADIUS > Users'").
When using a certificate to authenticate, it seems to me that the certificate CN would NOT be checked against the Users database. Regardless of the users I have added, I always get error messages like below when I have that check box checked:
- Nov 30 17:33:15 radiusd 1388 tls: Certificate CN (K14) does not match specified value (host/K14)!
- Nov 30 17:33:15 radiusd 1388 tls: TLS_accept: Error in error
- Nov 30 17:33:15 radiusd 1388 (4) Login incorrect (Failed retrieving values required to evaluate condition): [host/K14/<via Auth-Type = eap>] (from client SW21 port 2 cli xx-xx-xx-xx-xx-xx) host/K14 -
So far I have not been able to figure how to effectively enable the client cert. CN check.
I wonder if this is also some stupid beginner's mistake, or is this something else?
And where does this "host/" prefix come from? At least it seems to be independent of the 802.1X authentication mode in the client (User vs. computer authentication)...
When the check box is not checked, authentication with the certificate succeeds without any problems.
FWIW, Radius debug log reveals:
- (2) files: users: Matched entry host/K14 at line 2
- (2) [files] = ok
...so it seems that it indeed performs the check against user database where I have an entry "host/K14".