Skip to content

Fortified IDDocs

RadiusClient

Module for outbound RADIUS authentication

The RadiusClient module sends RADIUS Access-Request messages to a RADIUS server and returns the result (Accept, Reject, or Challenge) to the caller.

Each module instance targets a single RADIUS server. To connect to multiple servers, configure multiple module instances with different names. Two transport modes are supported:

  • PAP/UDP — classic RADIUS over UDP using a shared secret (RFC 2865)
  • RadSec/TCP+TLS — RADIUS over a persistent TLS connection (RFC 6614)
NameDescriptionDefaultMandatory
nameDestination name. Unique identifier for this module instance. Must be unique across all RadiusClient configurations."default"
hostHostname or IP address of the RADIUS server.
portUDP or TCP port of the RADIUS server.1812 (PAP), 2083 (RadSec)
radsecEnable RadSec mode (RADIUS over TCP+TLS). When false, PAP/UDP is used.false
secretShared secret used for PAP/UDP. Required when radsec is false; ignored in RadSec mode, where the value is always "radsec".""
timeout_msTime in milliseconds to wait for a response before the request fails.5000
request_attrsOptional array of additional RADIUS attributes to include in every Access-Request. See Request attributes.

The request_attrs array lets the operator include additional RADIUS attributes in every Access-Request — for example NAS-Identifier (type 32) or Service-Type (type 6).

NameDescriptionDefaultMandatory
typeRADIUS attribute type code (integer, 3–255).
valueAttribute value as a string.
value_typeEncoding of the value. One of: string (UTF-8), integer or time (4-byte big-endian), ipaddr (dotted-decimal IPv4), ipv6addr (IPv6), octets (hex-encoded raw bytes)."string"

RadSec requires a TLS connection. The following options control the TLS configuration.

NameDescriptionDefaultMandatory
ssl_truststoreTruststore object: path (PKCS12 file), password. Used to verify the server certificate. If omitted, the default Java truststore is used.
ssl_truststore_pathCompatibility form: path to a PKCS12 truststore.""
ssl_truststore_passwordPassword for ssl_truststore_path.""
ssl_keystoreKeystore object: path (PKCS12 file), password (opens the store), optional key_password (private key entry — defaults to password), optional alias (key entry alias — defaults to first alias in the store). Used for mutual TLS (client certificate).
ssl_keystore_pathCompatibility form: path to a PKCS12 client keystore.""
ssl_keystore_passwordPassword for ssl_keystore_path.""
ssl_key_aliasPrivate-key alias used with ssl_keystore_path; the first alias is used when omitted.First alias
ssl_key_passwordPrivate-key password used with ssl_keystore_path.ssl_keystore_password
ssl_verify_hostWhether to verify that the server certificate hostname matches host.true
ssl_trust_allDisable all SSL certificate validation. Not recommended for production.false

Multi-step authentication (Challenge/Response)

Section titled “Multi-step authentication (Challenge/Response)”

Some RADIUS servers implement multi-factor authentication using Access-Challenge responses. When a challenge is received the caller must include the state value returned in the challenge as part of the next Access-Request.

1. Caller → Access-Request (username + password)
2. RADIUS → Access-Challenge (state + optional Reply-Message)
3. Caller → Access-Request (username + OTP + state)
4. RADIUS → Access-Accept / Access-Reject

The state attribute (type 24) is surfaced as a top-level field in the response alongside the response type:

{ "type": "CHALLENGE", "state": "a1b2c3d4", "attrs": [] }

The caller includes it in the next request:

{ "username": "alice", "password": "123456", "state": "a1b2c3d4" }

All RADIUS response attributes are returned in the attrs array, encoded as hex strings. The caller is responsible for decoding the attributes it cares about.

{
"type": "ACCEPT",
"attrs": [
{ "type": 18, "hex": "57656c636f6d6521" },
{ "type": 8, "hex": "0a000001" }
]
}
Field Description
type RADIUS attribute type code (integer, 1–255)
hex Attribute value encoded as a hex string

To enable detailed logging, add the following to log4j2.xml:

<!-- Handler-level logs (request received, response type, errors) -->
<AsyncLogger name="foss.platform.modules.radius.impl.RadiusRequestHandler" level="DEBUG"/>
<!-- RadSec connection lifecycle (connect, disconnect, reconnect) -->
<AsyncLogger name="foss.platform.modules.radius.impl.TcpTlsRadiusClient" level="DEBUG"/>
<!-- PAP/UDP request lifecycle -->
<AsyncLogger name="foss.platform.modules.radius.impl.UdpRadiusClient" level="DEBUG"/>

Required level by message type:

  • INFO
    • Module start — transport mode, host, port, timeout, number of configured request_attrs
  • DEBUG
    • Access-Request sent (username, module name)
    • Response received (type: ACCEPT / REJECT / CHALLENGE)
    • RadSec connect / disconnect / reconnect
    • Late or unknown response identifier ignored
  • WARN
    • ssl_verify_host: false — hostname verification disabled
    • ssl_trust_all: true — all certificate validation disabled
  • ERROR
    • Request failed (with full stack trace)
    • RadSec packet write failure
    • Invalid packet length received