EAP-TTLS/PAP failing: client NAKs and requests MSCHAPv2 inside inner-tunnel
Hello, I am trying to configure FreeRADIUS for guest Wi-Fi authentication using *EAP-TTLS/PAP*. My backend is a custom REST API that validates the username and plain-text password. The Phase 1 TLS tunnel is established successfully, but the inner authentication (Phase 2) always fails. The debug log shows that my inner-tunnel server rejects the user. Here is the part of my debug log: (7) server inner-tunnel { (7) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/inner-tunnel (7) authorize { (7) eap: Peer sent EAP Response (code 2) ID 1 length 6 (7) eap: No EAP Start, assuming it's an on-going EAP conversation (7) [eap] = updated (7) } # authorize = updated (7) Found Auth-Type = EAP (7) # Executing group from file /etc/freeradius/3.0/sites-enabled/inner-tunnel (7) authenticate { (7) eap: Peer sent packet with method EAP NAK (3) (7) eap: Peer NAK'd asking for unsupported EAP type MSCHAPv2 (26), skipping... (7) eap: ERROR: No mutually acceptable types found (7) [eap] = invalid (7) } # authenticate = invalid (7) Failed to authenticate the user ... (7) eap_ttls: Got tunneled Access-Reject (7) eap: ERROR: Failed continuing EAP TTLS (21) session. EAP sub-module failed My eap.conf is configured to use default_eap_type = "pap" inside the ttls section. *My questions are:* 1. Does the log line Peer NAK'd asking for unsupported EAP type MSCHAPv2 definitively mean that client requests MSCHAPv2 but the server is only configured to accept EAP-TTLS/PAP? 2. What is the recommended best practice to solve this for a guest network? Should I focus on forcing the client devices to use PAP, or is it more reliable to reconfigure my server and REST API to support MSCHAPv2 (by providing the NT-Password hash)? Thank you for your help
On Sep 23, 2025, at 7:49 AM, Arifia Hapsari <arifiarahmi@gmail.com> wrote:
I am trying to configure FreeRADIUS for guest Wi-Fi authentication using *EAP-TTLS/PAP*. My backend is a custom REST API that validates the username and plain-text password.
It's almost always better to have the back-end supply the password to FreeRADIUS. FreeRADIUS can then authenticate the user.
Does the log line Peer NAK'd asking for unsupported EAP type MSCHAPv2 definitively mean that client requests MSCHAPv2 but the server is only configured to accept EAP-TTLS/PAP?
Yes.
2.
What is the recommended best practice to solve this for a guest network? Should I focus on forcing the client devices to use PAP,
That's pretty much impossible. There's no way for a server to reconfigure the client. If you can somehow change the client configuration to use PAP, that would work. But that can only be done manually / script / etc. i.e. outside of RADIUS.
or is it more reliable to reconfigure my server and REST API to support MSCHAPv2 (by providing the NT-Password hash)?
Yes. Alan DeKok.
Hello Alan, Thank you for your guidance in the previous email. Following your advice, I have successfully reconfigured my entire setup to use PEAP/MSCHAPv2, with my Django backend providing the NT-Password hash. I have solved all the initial issues (including the OpenSSL MD4 problem in Docker), and my API is now healthy. However, I am stuck on one final, very confusing problem. The Problem: During a real Wi-Fi authentication, my rlm_rest instance (guest_auth) consistently returns noop, which causes the mschap module to fail with ERROR: FAILED: No NT-Password. The Mystery: A curl test performed from the FreeRADIUS server shell to the API endpoint succeeds with a 200 OK and returns the correct NT-Password hash. This proves the API is working and the network path is clear. As a diagnostic test, i added a fallback to my inner-tunnel to hardcode a Cleartext-Password only if the guest_auth module returns noop. When I do this and use the same password on my client, the entire authentication succeeds and I receive an Access-Accept. This proves that my EAP, PEAP, and MSCHAP configurations are all working correctly. The problem is isolated entirely to the rlm_rest module's behavior. The module fails with noop even though curl from the same machine works. I also have a linelog configured in my rest.conf, but no linelog messages appear in the debug output. My Question: What could cause rlm_rest to fail silently (noop) without any linelog output, when a curl call with the same parameters succeeds? Could there be a difference in the TLS/SSL context, permissions for the freerad user, or environment that rlm_rest uses compared to the shell's curl? I also included a log snippet below. Thank you again for your invaluable expertise Best Regards, Arifia (8) server inner-tunnel { (8) session-state: No cached attributes (8) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/inner-tunnel (8) authorize { (8) [mschap] = noop (8) if (!&control:NT-Password) { (8) if (!&control:NT-Password) -> TRUE (8) if (!&control:NT-Password) { (8) [guest_auth] = noop (8) } # if (!&control:NT-Password) = noop (8) eap: Peer sent EAP Response (code 2) ID 9 length 63 (8) eap: No EAP Start, assuming it's an on-going EAP conversation (8) [eap] = updated (8) } # authorize = updated (8) Found Auth-Type = EAP (8) # Executing group from file /etc/freeradius/3.0/sites-enabled/inner-tunnel (8) authenticate { (8) eap: Expiring EAP session with state 0x2f4111f32f480b47 (8) eap: Finished EAP session with state 0x2f4111f32f480b47 (8) eap: Previous EAP request found for state 0x2f4111f32f480b47, released from the list (8) eap: Peer sent packet with method EAP MSCHAPv2 (26) (8) eap: Calling submodule eap_mschapv2 to process data (8) eap_mschapv2: # Executing group from file /etc/freeradius/3.0/sites-enabled/inner-tunnel (8) eap_mschapv2: Auth-Type MS-CHAP { (8) mschap: WARNING: No Cleartext-Password configured. Cannot create NT-Password (8) mschap: Creating challenge hash with username: test (8) mschap: Client is using MS-CHAPv2 (8) mschap: ERROR: FAILED: No NT-Password. Cannot perform authentication (8) mschap: ERROR: MS-CHAP2-Response is incorrect (8) eap_mschapv2: [mschap] = reject (8) eap_mschapv2: } # Auth-Type MS-CHAP = reject (8) eap: Sending EAP Failure (code 4) ID 9 length 4 (8) eap: Freeing handler (8) [eap] = reject (8) } # authenticate = reject Alan DeKok via Freeradius-Users <freeradius-users@lists.freeradius.org> schrieb am Di. 23. Sept. 2025 um 13:58:
On Sep 23, 2025, at 7:49 AM, Arifia Hapsari <arifiarahmi@gmail.com> wrote:
I am trying to configure FreeRADIUS for guest Wi-Fi authentication using *EAP-TTLS/PAP*. My backend is a custom REST API that validates the username and plain-text password.
It's almost always better to have the back-end supply the password to FreeRADIUS. FreeRADIUS can then authenticate the user.
Does the log line Peer NAK'd asking for unsupported EAP type MSCHAPv2 definitively mean that client requests MSCHAPv2 but the server is only configured to accept EAP-TTLS/PAP?
Yes.
2.
What is the recommended best practice to solve this for a guest network? Should I focus on forcing the client devices to use PAP,
That's pretty much impossible. There's no way for a server to reconfigure the client.
If you can somehow change the client configuration to use PAP, that would work. But that can only be done manually / script / etc. i.e. outside of RADIUS.
or is it more reliable to reconfigure my server and REST API to support MSCHAPv2 (by providing the NT-Password hash)?
Yes.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Oct 1, 2025, at 7:43 AM, Arifia Hapsari <arifiarahmi@gmail.com> wrote: Thank you for your guidance in the previous email. Following your advice, I have successfully reconfigured my entire setup to use PEAP/MSCHAPv2, with my Django backend providing the NT-Password hash. I have solved all the initial issues (including the OpenSSL MD4 problem in Docker), and my API is now healthy. However, I am stuck on one final, very confusing problem.
OK.
The Problem: During a real Wi-Fi authentication, my rlm_rest instance (guest_auth) consistently returns noop, which causes the mschap module to fail with ERROR: FAILED: No NT-Password.
Looking at the source code to rlm_rest, the only time it returns NOOP is when there's no relevant section in the configuration. i.e. you're listing "rest" in the "authorize" section, but then mods-enabled/rest doesn't have an "authorize" configuration. Alan DeKok.
participants (2)
-
Alan DeKok -
Arifia Hapsari