EAP
Configure EAP method handling for TLS, TTLS, PEAP, and TEAP authentication flows.
- 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
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 returns backend State attributes on subsequent
Access-Requests and 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.
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";
}
}
}
}
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. |
- 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