Radiator Server Documentation — v10.33.3
Table of Contents
  • tls
  • Parameters
  • Example: HTTPS Server
  • Example: RadSec Server (RADIUS over TLS)
  • Example: TACACS+ over TLS
  • Example: Mutual TLS (mTLS)
  • EAP-TLS handshake logging
  • Example JSON log records
  • See Also

tls

The tls clause configures Transport Layer Security (TLS) for server listeners. This configuration applies to all server types that support TLS:

  • HTTP servers - Enables HTTPS with HTTP/1.1 and HTTP/2 support
  • RADIUS servers - Enables RadSec (RADIUS over TLS, RFC 6614) on port 2083
  • TACACS+ servers - Enables TACACS+ over TLS

Parameters

ParameterDescriptionRequired
certificateServer certificate name (from certificates block)Yes
certificate_keyServer private key name (from certificates block)Yes
server_ca_certificateAdditional certificates to append to the presented server certificate chain, typically intermediatesNo
require_client_certificateWhether clients must present a certificateNo
client_ca_certificateCA certificate for validating client certificatesConditional
@verificationCustom certificate verification pipelineNo
min_protocol_versionMinimum TLS protocol version (tlsv12 for TLS 1.2, tlsv13 for TLS 1.3)No
max_protocol_versionMaximum TLS protocol version (tlsv12 for TLS 1.2, tlsv13 for TLS 1.3)No
tls13_session_ticketsNumber of TLS 1.3 session tickets to send (0 to disable)No
tls13_session_ticket_lifetimeAdvertised TLS 1.3 ticket lifetime as a duration (e.g. 24h, 30m, 0s); 0 disables resumption tickets entirelyNo
keylog_filenameFile path for TLS key logging (for debugging with Wireshark)No

require_client_certificate defaults to true when omitted. Set require_client_certificate false; for one-way TLS listeners such as a normal HTTPS endpoint.

The client_ca_certificate parameter is required when require_client_certificate is set to true.

server_ca_certificate is optional. Use it when the certificate configured in certificate does not already contain the full chain that clients should receive from the server.

tls13_session_tickets controls TLS 1.3 session tickets only. TLS 1.3 early data (0-RTT) is always disabled irrespective of this setting.

tls13_session_ticket_lifetime sets the advertised ticket_lifetime value carried in each TLS 1.3 NewSessionTicket message. The value accepts standard duration units (for example 24h, 30m, 90s); a bare number is interpreted as milliseconds for consistency with other Radiator duration parameters. The TLS 1.3 ticket_lifetime field is expressed in whole seconds, so sub-second positive values (such as 100ms) are rejected at configuration load to avoid silently disabling resumption. Setting it to 0 (or 0s) disables resumption ticket issuance entirely, equivalent to tls13_session_tickets 0;. When the parameter is omitted, a stateful resumption store is used with a 24-hour advertised lifetime.

Example: HTTPS Server

certificates {
    x509 "SERVER_CERT" {
        filename "/var/lib/radiator/certs/server.pem";
    }
    key "SERVER_KEY" {
        filename "/var/lib/radiator/certs/server-key.pem";
    }
}

servers {
    http "HTTPS_SERVER" {
        listen {
            protocol tls;
            port 8443;
            ip 0.0.0.0;

            tls {
                certificate "SERVER_CERT";
                certificate_key "SERVER_KEY";
                require_client_certificate false;
            }
        }
    }
}

Example: RadSec Server (RADIUS over TLS)

RadSec typically requires mutual TLS (mTLS) where both server and client authenticate with certificates:

certificates {
    x509 "RADSEC_CERT" {
        filename "/var/lib/radiator/certs/radsec-server.pem";
    }
    key "RADSEC_KEY" {
        filename "/var/lib/radiator/certs/radsec-server-key.pem";
    }
    x509 "RADSEC_SERVER_CA" {
        filename "/var/lib/radiator/certs/radsec-ca.pem";
    }
    x509 "RADSEC_CLIENT_CA" {
        filename "/var/lib/radiator/certs/radsec-client-ca.pem";
    }
}

servers {
    radius "RADSEC" {
        listen {
            protocol tls;
            port 2083;
            ip 0.0.0.0;

            tls {
                certificate "RADSEC_CERT";
                certificate_key "RADSEC_KEY";
                server_ca_certificate "RADSEC_SERVER_CA";

                # RadSec requires client certificates
                require_client_certificate true;
                client_ca_certificate "RADSEC_CLIENT_CA";

                @verification {
                    if any {
                        cert.valid != true;
                        # Require certificate issued under network device policy
                        cert.policy != "1.3.6.1.4.1.99999.1.2.3";
                        # Require certificate from partner organization
                        cert.subject.o != "Partner Network Inc";
                    } then {
                        reject;
                    } else {
                        accept;
                    }
                }
            }
        }

        clients "RADSEC_CLIENTS";
    }
}

Example: TACACS+ over TLS

Add a tls { ... } block to a TACACS+ server listen { protocol tls; ... } section. The TLS listener honors ip-accept, listener timeout, keepalive, and per-client timeout exactly like the plain TCP listener.

servers {
    tacacs-plus "TACACS_TLS" {
        listen {
            protocol tls;
            port 300;
            ip 0.0.0.0;
            ip-accept "TACACS_TLS_ACCESS";
            timeout 30s;

            tls {
                certificate "TACACS_SERVER_CERT";
                certificate_key "TACACS_SERVER_KEY";
                require_client_certificate true;
                client_ca_certificate "TACACS_CLIENT_CA";
            }
        }

        clients "TACACS_TLS_CLIENTS";
        policy "POLICY_TACACS_PLUS";
    }
}

Notes:

  • TACACS+ TLS and RadSec listeners support proxy-protocol v2;. The proxy sends the PROXY header before the TLS handshake. Radiator reads the header first, then uses the real client address from it for client matching.
  • Prefer running TACACS+ TLS and TACACS+ TCP on separate ports (and ideally separate tacacs-plus server blocks). Distinct ports keep the configuration easier to reason about, simplify firewall rules, and avoid surprises when the same client address appears under both transports. If you must share the address space, TACACS+ clients can declare protocol tls; in their source block to disambiguate; see clients.tacacs-plus for the matching rules.
  • For TACACS+ over TLS deployment details, including listener, client, and obfuscation settings, see TACACS+ Authentication, Authorization, and Accounting.

For policy, multistage authentication, and operational guidance, see TACACS+ Authentication, Authorization, and Accounting.

Example: Mutual TLS (mTLS)

When client certificate verification is required:

certificates {
    x509 "SERVER_CERT" {
        filename "/var/lib/radiator/certs/server.pem";
    }
    key "SERVER_KEY" {
        filename "/var/lib/radiator/certs/server-key.pem";
    }
    x509 "SERVER_CA" {
        filename "/var/lib/radiator/certs/ca.pem";
    }
    x509 "CLIENT_CA" {
        filename "/var/lib/radiator/certs/client-ca.pem";
    }
}

servers {
    http "MTLS_SERVER" {
        listen {
            protocol tls;
            port 8443;
            ip 0.0.0.0;

            tls {
                certificate "SERVER_CERT";
                certificate_key "SERVER_KEY";
                server_ca_certificate "SERVER_CA";

                # Require and validate client certificates
                require_client_certificate true;
                client_ca_certificate "CLIENT_CA";
            }
        }
    }
}

EAP-TLS handshake logging

EAP-TLS and the EAP methods that tunnel TLS inside it (EAP-TTLS, EAP-PEAP, EAP-TEAP) emit a structured logging scope around the inner TLS handshake. The records below show example log entries. Fragment records do not include payload bytes; use a packet capture and keylog_filename for byte-level analysis in Wireshark.

Example JSON log records

A successful EAP-TLS handshake over TLS 1.3 (with --json-log-format):

{
  "timestamp": "2026-05-21T10:14:07.482914Z",
  "level": "DEBUG",
  "namespace": ["server", "radius", "AUTH_RADIUS_UDP"],
  "message": "TLS handshake complete",
  "fields": {
    "context_id": "e7c1d2c6-4a3f-4f9c-8f9a-2d4f1b1c9a44",
    "eap_type": "tls",
    "eap_identifier": 12,
    "eaptls.version": 0,
    "tls.role": "server",
    "tls.timeout_ms": 5000,
    "tls.max_fragment_size": 1024,
    "tls.version": "TLSv1_3",
    "tls.ciphersuite": "TLS13_AES_256_GCM_SHA384",
    "tls.key_exchange_group": "X25519",
    "tls.session_resumed": false,
    "tls.exporter.label": "EXPORTER_EAP_TLS_Key_Material",
    "tls.msk.exported": true,
    "tls.msk.len": 128,
    "tls.eap_tls13_trailer": true,
    "tls.peer_cert.subject": "cn=testUser,o=Radiator Software,c=FI",
    "tls.peer_cert.issuer": "cn=Radiator Intermediate CA I2,o=Radiator Software,c=FI",
    "tls.peer_cert.chain_len": 2,
    "tls.peer_cert.serial": "1a:2b:3c",
    "tls.peer_cert.not_before": 1716285247,
    "tls.peer_cert.not_before_timestamp": "2024-05-21T09:54:07Z",
    "tls.peer_cert.not_after": 1747821247,
    "tls.peer_cert.not_after_timestamp": "2025-05-21T09:54:07Z",
    "tls.peer_cert.fingerprint_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    "tls.peer_cert.sans": "dns:testuser.radiatorsoftware.example.com",
    "tls.peer_cert.authority_key_identifier": "5c8fb3d99eabd69c6f884fa4aab442b5292f2f6b",
    "tls.peer_cert.subject_key_identifier": "9d2892c2c6730bd7ee8b069d115ffe5e77d1dc7f",
    "tls.peer_cert.intermediates": [
      {
        "chain_index": 1,
        "subject": "cn=Radiator Intermediate CA I2,o=Radiator Software,c=FI",
        "issuer": "cn=Radiator Root CA,o=Radiator Software,c=FI",
        "serial": "10:02",
        "not_before": 1704067200,
        "not_before_timestamp": "2024-01-01T00:00:00Z",
        "not_after": 1861833600,
        "not_after_timestamp": "2028-12-31T00:00:00Z",
        "fingerprint_sha256": "cfec366a0526a404cfe154527822b93fb9a8cdfbabf6fc259c0b24ea0ff8176e",
        "authority_key_identifier": "884a0c7f8a3f38d8c2e886c83276f6d0a3b5cc37",
        "subject_key_identifier": "5c8fb3d99eabd69c6f884fa4aab442b5292f2f6b"
      }
    ],
    "identity": "testUser@radiatorsoftware.example.com",
    "calling_station_id": "22-44-66-00-11-22",
    "called_station_id": "22-44-66-11-22-33:test.radiator",
    "nas_identifier": "ap-lobby-1",
    "nas_port": 0,
    "nas_ip_address": "192.0.2.10"
  }
}

A handshake failure where the Windows supplicant rejected the server certificate or certificate chain. Depending on the Windows version and certificate problem, the alert can appear as AccessDenied, InternalError, or another fatal TLS alert:

{
  "timestamp": "2026-05-21T10:15:21.107834Z",
  "level": "WARN",
  "namespace": ["server", "radius", "AUTH_RADIUS_UDP"],
  "message": "TLS handshake failed",
  "fields": {
    "context_id": "1f8d3b4a-3b9d-49a1-b2a4-8a3f4b6c8d10",
    "eap_type": "ttls",
    "eap_identifier": 4,
    "tls.role": "server",
    "tls.timeout_ms": 5000,
    "tls.max_fragment_size": 1024,
    "identity": "anonymous@radiatorsoftware.example.com",
    "calling_station_id": "AA-BB-CC-11-22-33",
    "called_station_id": "11-22-33-AA-BB-CC:corp-wifi",
    "nas_identifier": "ap-floor3-east",
    "handshake.error.source": "tls",
    "handshake.error.kind": "alert_received",
    "handshake.error.detail": "received fatal alert: AccessDenied"
  }
}

An outbound fragment record produced at Trace level when max-fragment-size forces the server certificate flight to be split across several EAP-TLS fragments:

{
  "timestamp": "2026-05-21T10:14:07.481102Z",
  "level": "TRACE",
  "namespace": ["server", "radius", "AUTH_RADIUS_UDP"],
  "message": "EAP-TLS fragment sent to peer",
  "fields": {
    "context_id": "e7c1d2c6-4a3f-4f9c-8f9a-2d4f1b1c9a44",
    "eap_type": "tls",
    "eap_identifier": 3,
    "tls.role": "server",
    "tls.max_fragment_size": 256,
    "tls.bytes_total": 2104,
    "frag.index": 1,
    "frag.size": 252,
    "frag.remaining": 1852,
    "frag.more": true,
    "frag.length_included": true
  }
}

See Also

Navigation
  • @init

  • @verification

  • aaa

  • backends

  • caches

  • captures

  • certificates

  • clients

  • conditions

  • dictionary

  • hmac-otp

  • include

  • ip-accept

  • license

  • logging

  • management

  • proxy-protocol

  • scripts

  • servers

    • buffer

    • clients

    • http

    • ip

    • keepalive

    • policy

    • port

    • pre-client

    • protocol

    • radius

    • timeout

    • tls

  • statistics

  • stats

  • ui