Requesting guidance to understand all moving parts for RadSec + EAP-TLS
Hello, As said on the other thread, I’m trying to use RadSec to provide EAP-TLS authentication for remote site. I’m mainly a NPS user during last years, it’s been a while since I haven’t used Freeradius. I’m a little bit lost in the set of configuration to do here, especially since some parts seems redundant between RadSec and EAP-TLS. Especially, I will have different intermediate certificates authority to authenticate access points on one side and wireless client on the other. Also, the configuration for EAP-TLS will need to be PKI based only (authenticate and authorize if certificate based authentication works and if the certificate is not revoked). No per-user authorization expected, and the FreeRadius server is expected to not know the list of valid users, solely relying on PKI for that. So if someone can lead me to a clean article about the use of RadSec + EAP-TLS in FreeRadius, or if someone can take the time to explain it to me, I’m really interested. Thanks a lot
On Apr 19, 2025, at 11:28 AM, Yoann Gini <yoann.gini@gmail.com> wrote:
As said on the other thread, I’m trying to use RadSec to provide EAP-TLS authentication for remote site. I’m mainly a NPS user during last years, it’s been a while since I haven’t used Freeradius.
FreeRADIUS is a lot more complex than NPS. Plus, there's no GUI. The good news is that FreeRADIUS has had new features added since 2004. NPS, not so much.
I’m a little bit lost in the set of configuration to do here, especially since some parts seems redundant between RadSec and EAP-TLS.
They both use TLS. And since they both use TLS, they use the same configuration format. The reason for making two configurations is that you might not want to use the same certificates for RadSec and for EAP-TLS. If there was only one TLS configuration, then you would have to use the same vets.
Especially, I will have different intermediate certificates authority to authenticate access points on one side and wireless client on the other.
Also, the configuration for EAP-TLS will need to be PKI based only (authenticate and authorize if certificate based authentication works and if the certificate is not revoked). No per-user authorization expected, and the FreeRadius server is expected to not know the list of valid users, solely relying on PKI for that.
Sure. That's fine.
So if someone can lead me to a clean article about the use of RadSec + EAP-TLS in FreeRadius, or if someone can take the time to explain it to me, I’m really interested.
There's no "RadSec + EAP-TLS" guide. There is, however, documentation for how to configure RADIUS/TLS. And, documentation for how to configure EAP-TLS. So just configure both. i.e. get EAP-TLS working with normal radius. There are a few test tools out there, for Windows or OSX. If you're comfortable with the command-line, there's eapol_test on Linux. Separately, get RadSec working, and test it with simple name / password packets. Once both of those work, try EAP-TLS over RadSec. It will work. Alan DeKok.
Following recommendations I’m starting by EAP-TLS config first. I have two question. First, it seams that, in my understanding, the configuration key ca_file in mods-enabled/eap (Ubuntu) is both use for as anchor for the radius server certificate defined in certificate_file and as trusted authority for client authentication. Is there a way to use a different set here? My goal would be to use for the radius server a certificate from Let’s Encrypt, as any exposed Internet service (and to ease the server provisioning), and for the client authentication, my internal PKI. Is that doable? Or should I use only certificates from my PKI here? Then, I’m having some basic EAP-TLS setup that ends with the server side sending an Access-Challenge and now answer from the client. Network stack is UniFi network with a macOS client connected to the WiFi. Any recommendations for the troubleshooting steps needed when Access-Challenge is not answered? Here is the debug log (0) Received Access-Request Id 0 from <my_public_ip>:55641 to 172.31.4.143:1812 length 224 (0) User-Name = "y" (0) NAS-IP-Address = 172.16.128.187 (0) NAS-Identifier = "6ad79a4ae1df" (0) Called-Station-Id = "6A-D7-9A-4A-E1-DF:Test" (0) NAS-Port-Type = Wireless-802.11 (0) Service-Type = Framed-User (0) Calling-Station-Id = "8A-6C-88-1D-26-16" (0) Connect-Info = "CONNECT 0Mbps 802.11a" (0) Acct-Session-Id = "E6820D4A4AE32164" (0) Acct-Multi-Session-Id = "B340C339DFD7F4B8" (0) Mobility-Domain-Id = 45825 (0) WLAN-Pairwise-Cipher = 1027076 (0) WLAN-Group-Cipher = 1027076 (0) WLAN-AKM-Suite = 1027075 (0) Filter-Id = "wpa-eap" (0) Framed-MTU = 1002 (0) EAP-Message = 0x020100060179 (0) Message-Authenticator = 0x2dc1e95d3c1a904277374839acf24474 (0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default (0) authorize { (0) [preprocess] = ok (0) auth_log: EXPAND /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/auth-detail-%Y%m%d (0) auth_log: --> /var/log/freeradius/radacct/<my_public_ip>/auth-detail-20250420 (0) auth_log: /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/auth-detail-%Y%m%d expands to /var/log/freeradius/radacct/<my_public_ip>/auth-detail-20250420 (0) auth_log: EXPAND %t (0) auth_log: --> Sun Apr 20 16:52:55 2025 (0) [auth_log] = ok (0) suffix: Checking for suffix after "@" (0) suffix: No '@' in User-Name = "y", looking up realm NULL (0) suffix: No such realm "NULL" (0) [suffix] = noop (0) eap: Peer sent EAP Response (code 2) ID 1 length 6 (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 /etc/freeradius/3.0/sites-enabled/default (0) authenticate { (0) eap: EXPAND %{Calling-Station-Id} (0) eap: --> 8A-6C-88-1D-26-16 (0) eap: Peer sent packet with method EAP Identity (1) (0) eap: Calling submodule eap_tls to process data (0) eap_tls: (TLS) TLS -Initiating new session (0) eap_tls: (TLS) TLS - Setting verify mode to require certificate from client (0) eap: Sending EAP Request (code 1) ID 2 length 10 (0) eap: EAP session adding &reply:State = 0xbf9ac2b0bf98cffa (0) [eap] = handled (0) } # authenticate = handled (0) Using Post-Auth-Type Challenge (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default (0) Post-Auth-Type Challenge { (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) attr_filter.access_challenge: EXPAND %{User-Name} (0) attr_filter.access_challenge: --> y (0) attr_filter.access_challenge: Matched entry DEFAULT at line 12 (0) [attr_filter.access_challenge.post-auth] = updated (0) } # Post-Auth-Type Challenge = updated (0) session-state: Saving cached attributes (0) Framed-MTU = 1002 (0) Sent Access-Challenge Id 0 from 172.31.4.143:1812 to <my_public_ip>:55641 length 68 (0) EAP-Message = 0x0102000a0da000000000 (0) Message-Authenticator = 0x00000000000000000000000000000000 (0) State = 0xbf9ac2b0bf98cffac710c0c9c10466bb (0) Finished request Waking up in 4.9 seconds.
On Apr 20, 2025, at 1:08 PM, Yoann Gini <yoann.gini@gmail.com> wrote:
First, it seams that, in my understanding, the configuration key ca_file in mods-enabled/eap (Ubuntu) is both use for as anchor for the radius server certificate defined in certificate_file and as trusted authority for client authentication.
If you want. There's no requirement to do that.
Is there a way to use a different set here? My goal would be to use for the radius server a certificate from Let’s Encrypt, as any exposed Internet service (and to ease the server provisioning), and for the client authentication, my internal PKI.
Is that doable? Or should I use only certificates from my PKI here?
Yes. Just put all of the CA files into ca_dir, and then use ca_dir instead of ca_path. The server will read all of the CA files at startup.
Then, I’m having some basic EAP-TLS setup that ends with the server side sending an Access-Challenge and now answer from the client. Network stack is UniFi network with a macOS client connected to the WiFi.
Any recommendations for the troubleshooting steps needed when Access-Challenge is not answered?
Look at the logs on the NAS or the OSX machine. The packets have Message-Authenticator, so you know that the shared secret is OK. So the problem is likely not the NAS. The most common cause of this issue is that the end user machine isn't configured correctly. i.e. it doesn't know about the CA that the server is using. Update the OSX machine so that it has the CA, and the CA is being used for EAP. This is all very OS specific. :( Alan DeKok.
Hi
Le 20 avr. 2025 à 19:35, Alan DeKok <aland@deployingradius.com> a écrit :
On Apr 20, 2025, at 1:08 PM, Yoann Gini <yoann.gini@gmail.com <mailto:yoann.gini@gmail.com>> wrote:
First, it seams that, in my understanding, the configuration key ca_file in mods-enabled/eap (Ubuntu) is both use for as anchor for the radius server certificate defined in certificate_file and as trusted authority for client authentication.
If you want. There's no requirement to do that.
Is there a way to use a different set here? My goal would be to use for the radius server a certificate from Let’s Encrypt, as any exposed Internet service (and to ease the server provisioning), and for the client authentication, my internal PKI.
Is that doable? Or should I use only certificates from my PKI here?
Yes. Just put all of the CA files into ca_dir, and then use ca_dir instead of ca_path. The server will read all of the CA files at startup.
But if I put all of the CA into ca_dir, the Let’s Encrypt issued certificates could also be used to pass client auth?
Then, I’m having some basic EAP-TLS setup that ends with the server side sending an Access-Challenge and now answer from the client. Network stack is UniFi network with a macOS client connected to the WiFi.
Any recommendations for the troubleshooting steps needed when Access-Challenge is not answered?
Look at the logs on the NAS or the OSX machine.
The packets have Message-Authenticator, so you know that the shared secret is OK. So the problem is likely not the NAS.
The most common cause of this issue is that the end user machine isn't configured correctly. i.e. it doesn't know about the CA that the server is using.
Update the OSX machine so that it has the CA, and the CA is being used for EAP. This is all very OS specific. :(
Indeed, I’ve tested with a Windows endpoint and it just worked. I will see later the MDM configuration needed for the Windows. Now I will try to embed this in Radsec Thanks
On Apr 20, 2025, at 2:17 PM, Yoann Gini <yoann.gini@gmail.com> wrote:
But if I put all of the CA into ca_dir, the Let’s Encrypt issued certificates could also be used to pass client auth?
Technically, yes. Practically no. The LetsEncrypt certificates generally aren't CAs. So they can't issue client certs. Even if they were CAs, you can run the server in debug mode, and see what it prints out about the TLS certificates. You can then add policies to check the TLS-* attributes, to verify that the client certificates are created by a CA you trust. Alan DeKok.
What do you mean by: 'use for as anchor for the radius server certificate defined in certificate_file' The radius server certificate pointed to by certificate_file (EG the thing you got from "Let's Encrypt") does not need to contain a 'anchor CA' component. The only thing it should contain is the actual server "leaf" cert and any intermediate certs leading up to but not including the issuing root ("anchor"?) CA certificate. The clients that connect to your radius server should have their own local copy of trusted CA certs that they use to validate your server's TTLS cert when they connect to your server. The ca_file (or ca_dir) should contain CA certs that were used to issue any client TLS certs that you want to trust, it does not need to contain anything else. On Sun, 20 Apr 2025, Yoann Gini wrote:
Following recommendations I’m starting by EAP-TLS config first.
I have two question.
First, it seams that, in my understanding, the configuration key ca_file in mods-enabled/eap (Ubuntu) is both use for as anchor for the radius server certificate defined in certificate_file and as trusted authority for client authentication.
Is there a way to use a different set here? My goal would be to use for the radius server a certificate from Let’s Encrypt, as any exposed Internet service (and to ease the server provisioning), and for the client authentication, my internal PKI.
Is that doable? Or should I use only certificates from my PKI here?
Then, I’m having some basic EAP-TLS setup that ends with the server side sending an Access-Challenge and now answer from the client. Network stack is UniFi network with a macOS client connected to the WiFi.
Any recommendations for the troubleshooting steps needed when Access-Challenge is not answered?
Here is the debug log
(0) Received Access-Request Id 0 from <my_public_ip>:55641 to 172.31.4.143:1812 length 224 (0) User-Name = "y" (0) NAS-IP-Address = 172.16.128.187 (0) NAS-Identifier = "6ad79a4ae1df" (0) Called-Station-Id = "6A-D7-9A-4A-E1-DF:Test" (0) NAS-Port-Type = Wireless-802.11 (0) Service-Type = Framed-User (0) Calling-Station-Id = "8A-6C-88-1D-26-16" (0) Connect-Info = "CONNECT 0Mbps 802.11a" (0) Acct-Session-Id = "E6820D4A4AE32164" (0) Acct-Multi-Session-Id = "B340C339DFD7F4B8" (0) Mobility-Domain-Id = 45825 (0) WLAN-Pairwise-Cipher = 1027076 (0) WLAN-Group-Cipher = 1027076 (0) WLAN-AKM-Suite = 1027075 (0) Filter-Id = "wpa-eap" (0) Framed-MTU = 1002 (0) EAP-Message = 0x020100060179 (0) Message-Authenticator = 0x2dc1e95d3c1a904277374839acf24474 (0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default (0) authorize { (0) [preprocess] = ok (0) auth_log: EXPAND /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/auth-detail-%Y%m%d (0) auth_log: --> /var/log/freeradius/radacct/<my_public_ip>/auth-detail-20250420 (0) auth_log: /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/auth-detail-%Y%m%d expands to /var/log/freeradius/radacct/<my_public_ip>/auth-detail-20250420 (0) auth_log: EXPAND %t (0) auth_log: --> Sun Apr 20 16:52:55 2025 (0) [auth_log] = ok (0) suffix: Checking for suffix after "@" (0) suffix: No '@' in User-Name = "y", looking up realm NULL (0) suffix: No such realm "NULL" (0) [suffix] = noop (0) eap: Peer sent EAP Response (code 2) ID 1 length 6 (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 /etc/freeradius/3.0/sites-enabled/default (0) authenticate { (0) eap: EXPAND %{Calling-Station-Id} (0) eap: --> 8A-6C-88-1D-26-16 (0) eap: Peer sent packet with method EAP Identity (1) (0) eap: Calling submodule eap_tls to process data (0) eap_tls: (TLS) TLS -Initiating new session (0) eap_tls: (TLS) TLS - Setting verify mode to require certificate from client (0) eap: Sending EAP Request (code 1) ID 2 length 10 (0) eap: EAP session adding &reply:State = 0xbf9ac2b0bf98cffa (0) [eap] = handled (0) } # authenticate = handled (0) Using Post-Auth-Type Challenge (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default (0) Post-Auth-Type Challenge { (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) attr_filter.access_challenge: EXPAND %{User-Name} (0) attr_filter.access_challenge: --> y (0) attr_filter.access_challenge: Matched entry DEFAULT at line 12 (0) [attr_filter.access_challenge.post-auth] = updated (0) } # Post-Auth-Type Challenge = updated (0) session-state: Saving cached attributes (0) Framed-MTU = 1002 (0) Sent Access-Challenge Id 0 from 172.31.4.143:1812 to <my_public_ip>:55641 length 68 (0) EAP-Message = 0x0102000a0da000000000 (0) Message-Authenticator = 0x00000000000000000000000000000000 (0) State = 0xbf9ac2b0bf98cffac710c0c9c10466bb (0) Finished request Waking up in 4.9 seconds.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Dave Funk University of Iowa <dbfunk (at) engineering.uiowa.edu> College of Engineering 319/335-5751 FAX: 319/384-0549 1256 Seamans Center, 103 S Capitol St. Sys_admin/Postmaster/cell_admin Iowa City, IA 52242-1527 #include <std_disclaimer.h> Better is not better, 'standard' is better. B{
Hi
Le 20 avr. 2025 à 20:24, Dave Funk <dbfunk@engineering.uiowa.edu> a écrit :
What do you mean by: 'use for as anchor for the radius server certificate defined in certificate_file'
The radius server certificate pointed to by certificate_file (EG the thing you got from "Let's Encrypt") does not need to contain a 'anchor CA' component. The only thing it should contain is the actual server "leaf" cert and any intermediate certs leading up to but not including the issuing root ("anchor"?) CA certificate. The clients that connect to your radius server should have their own local copy of trusted CA certs that they use to validate your server's TTLS cert when they connect to your server.
The ca_file (or ca_dir) should contain CA certs that were used to issue any client TLS certs that you want to trust, it does not need to contain anything else.
OK, that’s where I was unsure. I can put in certificate_file the fullchain of the LE certificate, and in ca_file the root + intermediates of the internal PKI? Reading the comments in the configuration file, I was misunderstanding that if certificate_file had the fullchain, then ca_file cannot be used. My bad
Hi Yoann I've used RadSec with EAP-TLS on my FR (3.2 release). I have my own Radsec client and did not use the opensource radsecproxy. I'll answer some of your questions first 1 The cert+CA chain for Radsec is logically completely different than the cert+CA chain for EAP-TLS. The former is used to secure the transport (using TLS) between the NAS/Authenticator/Radius-client and FR. The latter is used for wireless/wired clients to mutually authenticate with the FR. In fact you can use the same CA for generating the Radsec server cert (for authenticating to the NAS/AP) and the Radius server cert (for authenticating to wireless clients). You may even use the same server cert for both as long as the other party can validate the cert 2 There is no conflict here about requiring EAP-TLS to be PKI only. You may have to setup OCSP/CRL on the FR side (I have not done it; others have). This won't interfere with Radsec in any way Here's my FR configs to support Radsec. I assume you already have the support for EAP-TLS over plain Radius. If you don't, first get that working over plain Radius before adding on Radsec I've attached a tarball that has everything you need to build an image that runs FR with Radsec support. To use this copy it into your ~/tmp folder (say) and then do cd ~/tmp mkdir FR_Radsec; cd FR_Radsec tar xzf ../FR_docker.tgz docker build -t freeradius_radsec -f Dockerfile RADIUS_DOCKER_FILES This will produce a Docker image freeradius_radsec To run the Docker image do. This will create a container whose ID you can get using the command 'docker ps' docker run -dt freeradius_radsec Then run cmd below to get a shell into the running container. <cid> is the container ID docker exec -it <cid> bash # cd /etc/freeradius/3.0/sites-available/ # less tls The very 1st section of the 'tls' file is the Radsec configuration. You need to replace the following files /etc/freeradius/3.0/certs/server.pem - This has already expired ! But you need to use the Radsec server cert that you generated using your CA server.key - Private key corresponding to cert above ca.pem - This has also expired. Please replace with your own The next section in the 'tls' fils is 'clients'. Replace the IP 20.20.20.20 with the IP of your NAS/AP/Controller EAP-TLS configuration This is in /etc/freeradius/3.0/mods-available/eap. Edit this file to match yours Hope this helps -gopal raman On Sat, Apr 19, 2025 at 8:28 AM Yoann Gini <yoann.gini@gmail.com> wrote:
Hello,
As said on the other thread, I’m trying to use RadSec to provide EAP-TLS authentication for remote site. I’m mainly a NPS user during last years, it’s been a while since I haven’t used Freeradius.
I’m a little bit lost in the set of configuration to do here, especially since some parts seems redundant between RadSec and EAP-TLS.
Especially, I will have different intermediate certificates authority to authenticate access points on one side and wireless client on the other.
Also, the configuration for EAP-TLS will need to be PKI based only (authenticate and authorize if certificate based authentication works and if the certificate is not revoked). No per-user authorization expected, and the FreeRadius server is expected to not know the list of valid users, solely relying on PKI for that.
So if someone can lead me to a clean article about the use of RadSec + EAP-TLS in FreeRadius, or if someone can take the time to explain it to me, I’m really interested.
Thanks a lot - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
participants (4)
-
Alan DeKok -
Dave Funk -
Gopal Raman -
Yoann Gini