EAP
- TLS Session Resumption
- eap_tls
- Example action call
- eap_ttls
- Example action call for TTLS with PAP
- Example action call for TTLS with MSCHAPv2
- Example action call for TTLS with inner EAP-MSCHAPv2
- eap_peap
- Example action call
- Proxying the complete inner EAP conversation
- eap_teap
- Example action call for TEAP with PAP
- Example action call for TEAP with inner EAP-MSCHAPv2
- tls
- Example action call
- Statements
- EAP-MSCHAPv2 password retries
Use eap { ... } action to handle incoming EAP requests. Each method block handles one outer EAP type. TLS-based methods such as eap_tls, eap_ttls, eap_peap, and eap_teap define a tls { ... } block and can then run additional action calls for inner authentication or post-authentication processing.
Use eap { ... } to group one or more supported EAP methods.
Example action call:
@execute {
eap {
eap_tls {
tls {
certificate "EAP_SERVER_CERT";
certificate_key "EAP_SERVER_KEY";
client_ca_certificate "EAP_SERVER_CLIENT_CA";
require_client_certificate true;
}
}
eap_ttls {
tls {
certificate "EAP_SERVER_CERT";
certificate_key "EAP_SERVER_KEY";
require_client_certificate false;
}
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
pap;
}
}
}
}
Use stronger methods first when you support multiple methods in the same policy.
TLS Session Resumption
TLS-based EAP methods use the same tls { ... } session resumption settings
as server TLS listeners. Configure these settings inside the EAP method's
tls { ... } block.
TLS 1.2 SessionID resumption and TLS 1.3 session tickets are disabled by default. Enable only the resumption modes that your clients should use:
eap {
eap_peap {
tls {
certificate "EAP_SERVER_CERT";
certificate_key "EAP_SERVER_KEY";
require_client_certificate false;
tls12_session_id_resumption true;
tls13_session_tickets 1;
session_cache_size 1024;
}
@authentication {
eap {
eap_mschapv2 {
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
mschapv2;
}
}
}
}
}
}
Use tls12_session_id_resumption true; to enable TLS 1.2 SessionID
resumption. Use tls13_session_tickets N; to send TLS 1.3 session tickets.
Use session_cache_size to set the maximum number of stateful resumption
entries stored for the method.
For eap_ttls and eap_peap, a resumed session can skip the inner
authentication exchange. Radiator keeps cached authentication state for the
resumed session. Variables stored under vars.* during the full inner
authentication remain available to later @post_authentication and
@authorization actions.
For eap_peap, a successful resumed session can return Access-Accept without
running inner EAP again. Store values that later audit or authorization logic
needs under vars.* during full inner authentication. Radiator restores those
values for resumed sessions.
Resumed TLS sessions do not perform a full certificate verification step. If you rely on certificate revocation lists for prompt revocation enforcement, disable TLS session resumption or keep resumption lifetimes short.
See server TLS for all TLS resumption parameters, defaults, cache behavior, and certificate revocation implications.
eap_tls
Use eap_tls for certificate-based mutual authentication. The server presents its certificate, and the client must also present a valid certificate.
Example action call
@execute {
eap {
eap_tls {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
client_ca_certificate "EAP_SERVER_CLIENT_CA";
require_client_certificate true;
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
eap_ttls
Use eap_ttls when you want a TLS tunnel with inner authentication. The supported inner methods are:
papmschapv2eap { eap-mschapv2 { ... } }
The outer server certificate is always validated by the client. The server does not require a client certificate in the tested TTLS examples.
Example action call for TTLS with PAP
@execute {
eap {
eap_ttls {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
pap;
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
Example action call for TTLS with MSCHAPv2
@execute {
eap {
eap_ttls {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
mschapv2;
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
Example action call for TTLS with inner EAP-MSCHAPv2
@execute {
eap {
eap_ttls {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
eap {
eap_mschapv2 {
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
mschapv2;
}
}
}
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
eap_peap
Use eap_peap for a TLS tunnel with inner EAP authentication.
PEAP keeps the outer EAP identity and tunneled EAP identity in separate
execution contexts. Use root.eap.identity for the outer identity and
eap.identity for the tunneled identity inside @authentication. Use the
writable aaa.identity when a backend requires a translated inner identity.
Nested EAP method pipelines can also use parent.eap.identity and
parent.aaa.identity. See EAP identity layers
for the complete accessor list and an identity translation example.
Use cryptobinding to control PEAP version 0 Cryptobinding TLVs. The allowed
values are:
optional: Send Cryptobinding TLVs and use the derived key when the peer replies. If the inner method does not generate keying material, use the MS-PEAP zero Inner Session Key (ISK). This is the default.required: Require the peer to return a valid Cryptobinding TLV for successful protected Result TLV exchanges. Also require the inner method to generate keying material during full authentication.disabled: Do not send Cryptobinding TLVs.
Radiator always clears the mandatory bit in PEAP Cryptobinding TLVs, as
required by MS-PEAP. The required value controls local validation policy and
does not change the Cryptobinding TLV wire format. Fast reconnect derives
cryptobinding keys from the resumed tunnel state and does not run the inner
method again.
Example action call
@execute {
eap {
eap_peap {
cryptobinding optional;
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
eap {
eap_mschapv2 {
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
mschapv2;
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
}
}
}
Proxying the complete inner EAP conversation
Call a RADIUS backend directly from the PEAP @authentication block when an
upstream RADIUS server must handle the complete inner EAP method. Do not add a
nested eap_mschapv2 action on the terminating server in this configuration.
@execute {
eap {
eap_peap {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
backend "INNER_EAP_RADIUS";
}
}
}
}
Radiator terminates the PEAP TLS tunnel and sends each complete inner EAP
packet to the backend in EAP-Message. Access-Challenge responses continue the
inner conversation. Radiator stores the latest backend State and returns it
to that backend in the next Access-Request. It does not expose this value as
the client-facing proxy correlation value. The backend may change State in
each challenge. See
RADIUS proxy State.
Radiator imports the MPPE key pair from Access-Accept for PEAP key derivation
and cryptobinding.
Each Access-Challenge must contain exactly one complete EAP-Request. Radiator keeps the upstream EAP Identifier when PEAP header compression omits it from the peer response. An Access-Accept may omit EAP-Success, and an Access-Reject may omit EAP-Failure. Radiator forwards an included terminal EAP packet only when its result and Identifier match the completed inner exchange. It ignores an invalid or contradictory terminal EAP packet and bases the access decision on the RADIUS response Code, as required by RFC 3579.
An Access-Accept may provide the MPPE key pair without EAP-Message. Radiator requires both MS-MPPE-Recv-Key and MS-MPPE-Send-Key when either is present. It forms the 32-octet PEAP Server ISK from the start of the receive-key and send-key concatenation. A shorter pair is zero-padded, and additional octets are ignored.
This direct complete-inner-EAP proxy mode applies to PEAP. EAP-TTLS backend
conversion continues to proxy the inner TTLS attributes or the configured
nested EAP method according to the eap_ttls action.
EAP-TTLS carries inner AVP values under the tunnel's TLS protection. When an inner AVP maps to a protected RADIUS dictionary attribute, Radiator applies the destination RADIUS packet profile during proxying: RADIUS/1.0 encodes the value with the destination shared secret, while RADIUS/1.1 carries the underlying value over its protected transport. Unknown AVPs are preserved without assuming historic RADIUS encryption.
Use @pre_proxying on the RADIUS backend to add routing attributes or translate
the upstream User-Name. This translation does not change the identity inside
the EAP packet. See RADIUS backend PEAP inner EAP proxying
for a complete backend example.
eap_teap
Use eap_teap for Tunnel Extensible Authentication Protocol (TEAP). Supports
these inner methods:
papmschapv2eap { eap-mschapv2 { ... } }
Set eap_teap_identity_type to user or machine. Both values use unquoted
syntax. Quoted "user" and "machine" values remain supported for existing
configurations.
The optional eap_teap_intermediate_result timeout accepts a duration such as
60s. A value without a suffix remains supported and represents milliseconds.
If you omit the timeout, Radiator uses 3 seconds. The timeout is stored as a
duration and is not limited to 65,535 milliseconds.
Use session_key_derivation to select how Radiator derives the session keys,
the Master Session Key (MSK) and Extended Master Session Key (EMSK). The MSK
must match the key that the peer derives. Otherwise, the peer authenticates
successfully but cannot establish the wireless connection. The allowed values
are:
rfc7170: Derive the MSK from the MSK based key chain and the EMSK from the EMSK based key chain. When no inner EAP method succeeds, such as with password authentication only, derive the MSK from the TLS tunnel and send no EMSK. wpa_supplicant 2.11 and older derive the keys this way. This is the default.rfc9930: Derive both keys from the key chain that the peer selects in its Crypto-Binding TLV, as RFC 9930 defines. wpa_supplicant 2.12 and newer derive the keys this way.
The value applies to both TLS 1.2 and TLS 1.3. With TLS 1.3, Radiator derives the TEAP keys with the TLS exporter as RFC 9427 defines.
eap_teap {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
session_key_derivation rfc9930;
@authentication {
eap_teap_identity_type user;
challenge "Enter user password?";
pap;
}
}
Example action call for TEAP with PAP
@execute {
eap {
eap_teap {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
eap_teap_identity_type user;
challenge "Enter user password?";
backend {
name "JSON_USERS";
query "FIND_USER";
}
pap;
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
Example action call for TEAP with inner EAP-MSCHAPv2
@execute {
eap {
eap_teap {
tls {
certificate_key "EAP_SERVER_KEY";
certificate "EAP_SERVER_CERT";
require_client_certificate false;
}
@authentication {
eap_teap_identity_type user;
challenge "Enter user password?";
backend {
name "JSON_USERS";
query "FIND_USER";
}
eap {
eap_mschapv2 {
@authentication {
backend {
name "JSON_USERS";
query "FIND_USER";
}
mschapv2;
}
}
}
}
@post_authentication {
invoke "LOG_AUTHENTICATION";
}
}
}
}
TEAP preserves inner rejection reasons in the outer log. Peer failure details are
available in vars.teap_result_tlv_status and vars.teap_result_tlv_reason.
tls
The tls { ... } block is shared by the TLS-based EAP methods shown on this page.
Example action call
tls {
certificate "EAP_SERVER_CERT";
certificate_key "EAP_SERVER_KEY";
# client_ca_certificate "EAP_SERVER_CLIENT_CA";
# require_client_certificate false;
}
Statements
| Statement | Required | Notes |
|---|---|---|
certificate | Yes | Server certificate reference. |
certificate_key | Yes | Matching private key reference. |
client_ca_certificate | No | Needed when validating client certificates. |
require_client_certificate | No | Set to true for EAP-TLS. Commonly false for TTLS, PEAP, and TEAP password tunneling. |
EAP-MSCHAPv2 password retries
Set max_password_retries inside eap_mschapv2 to limit password retries.
Values range from 0 to 255; the default is 1 retry after the initial attempt.
Use max_password_retries 0; to reject the first incorrect password without
an interactive retry.
This also applies to inner EAP-MSCHAPv2 in PEAP, TTLS and TEAP. It does not
change the standalone mschapv2 action or TTLS MSCHAPv2 without inner EAP.