certificates
certificates
The certificates clause defines named X.509 certificate and private key
objects that other parts of the configuration reference (for example TLS
listeners, EAP‑TLS / PEAP / TTLS methods, management HTTPS, RADIUS/TLS, or
internal components requiring a certificate/key pair). Centralizing these
definitions avoids repeating file paths and eases rotation.
A definition is purely a reference wrapper around on‑disk PEM files; the server loads and holds them in memory after parsing.
Structure
certificates {
x509 "SERVER_CERT" {
filename "/etc/radiator/certs/server.pem";
}
x509_directory "CLIENT_CA_DIRECTORY" {
directory "/etc/radiator/certs/clients";
interval 30m;
}
key "SERVER_KEY" {
filename "/etc/radiator/private/server-key.pem";
# password "correcthorsebatterystaple";
}
}
You can define any number of certificate (x509), certificate directory (x509_directory), and private key (key) blocks.
Names are case sensitive. Reusing a name will cause a configuration error.
Blocks and Statements
| Element | Context | Required | Description |
|---|---|---|---|
x509 "NAME" { ... } | certificates | No (≥1 if you need TLS) | Declares a certificate by name |
filename "path"; | Inside x509 | Yes | Absolute or relative path to PEM certificate |
x509_directory "NAME" { ... } | certificates | No | Declares a named directory of PEM CA certificates |
directory "path"; | Inside x509_directory | Yes | Path to a directory containing PEM CA certificates |
interval ...; | Inside x509_directory | No | Refresh schedule for rescanning the directory. Supports shared interval forms. Default 1m. |
key "NAME" { ... } | certificates | No (required if private key needed) | Declares a private key by name |
filename "path"; | Inside key | Yes | Path to PEM encoded private key |
password "**obscured**"; | Inside key | No | Passphrase for encrypted key (if the PEM is encrypted) |
Relative paths are resolved relative to the working directory of the running process (typically the directory where you start the server). Prefer absolute paths for production.
Certificate directories
Use x509_directory for CA bundles that are maintained as individual PEM files in a directory.
Directories referenced by live TLS consumers refresh on their configured schedule.
Unreferenced directories do not perform periodic reload work. Unreadable or malformed files
are skipped while loading the remaining usable trust anchors.
Radiator rescans the directory periodically and reloads the certificates without requiring a
configuration change. If interval is omitted, the directory is rescanned every 1m.
certificates {
x509_directory "CLIENT_CA_DIRECTORY" {
directory "/etc/radiator/certs/clients";
interval 30m;
}
}
For interval syntax and supported forms, see interval.
Usage in Other Clauses
Example: EAP‑TLS inside an AAA handler:
@authentication {
backend "USERS";
eap {
eap_tls {
tls {
certificate "SERVER_CERT";
certificate_key "SERVER_KEY";
# client_ca_certificate "CLIENTS_CA";
# require_client_certificate true;
}
}
}
}
Example: TLS listener (shape depends on the server protocol block):
servers {
radius "auth-tls" {
listen {
protocol tcp;
ip 0.0.0.0;
port 2083;
ip 0.0.0.0;
}
# certificate/key reference occurs in the TLS sub-block for the listener
policy "RADIUS";
}
}
(Refer to the server / EAP method documentation for the exact statement names
and where to reference certificate and certificate_key.)
Directory-backed CA bundles can be referenced anywhere a CA certificate object is accepted:
certificates {
x509_directory "CLIENT_CA_DIRECTORY" {
directory "/etc/radiator/certs/clients";
interval 30m;
}
}
@authentication {
eap {
eap_tls {
tls {
client_ca_certificate "CLIENT_CA_DIRECTORY";
}
}
}
}
Debug Logging
When debug logging is enabled (RADIATOR_LOG_LEVEL=debug or --debug), the server logs
certificate details as each certificate is added to a TLS context. This helps
verify correct certificate loading and troubleshoot TLS configuration issues.
Example log entry in JSON format:
{
"level": "DEBUG",
"namespace": ["configuration", "certificates"],
"message": "Certificate added to TLS context",
"fields": {
"tls_context": "server_cert_chain",
"cert_config": "SERVER_CERT",
"chain_position": "0",
"subject": "c=AU,cn=test.server.example.com",
"issuer": "c=AU,cn=Example CA",
"san": "ip:10.20.30.101, dns:test.server.example.com",
"not_before": "2025-01-01T00:00:00Z",
"not_after": "2027-01-01T00:00:00Z",
"serial": "20:25:01:01:00:01"
...
}
}
The tls_context field indicates where the certificate is used:
server_cert_chain- Server certificate and chainserver_client_ca- CA certificates for client verificationclient_cert_chain- Client certificate and chain (for outbound TLS)client_server_ca- CA certificates for server verification (for outbound TLS)
Certificate Revocation Lists (CRL)
Radiator can reject peer certificates that have been revoked by their issuing
CA. The recommended way to publish CRLs to Radiator is a crl_directory,
which is a directory of CRL files on the server filesystem that Radiator
rescans in the background. For static deployments where the CRL never
changes, a single crl block can be used instead; a single crl block is
only re-read on a configuration reload, so it is not suitable for
deployments where revocations are added over time.
certificates {
crl_directory "ALL_CRLS" {
directory "/etc/radiator/certs/crls";
interval 1h;
}
crl "ISSUER_CRL" {
filename "/etc/radiator/certs/issuer.crl";
}
}
| Element | Context | Required | Description |
|---|---|---|---|
crl_directory "NAME" { ... } | certificates | No | Declares a directory of CRL files rescanned periodically |
directory "path"; | Inside crl_directory | Yes | Path to a directory containing CRL files |
interval ...; | Inside crl_directory | No | Rescan interval using shared forms (duration, cron, optional random). Default 1m. See interval. |
allow_stale yes|no; | Inside crl_directory | No | Accept peers when every CRL in the directory is stale. Default no |
crl "NAME" { ... } | certificates | No | Declares a CRL loaded from a single PEM or DER file |
filename "path"; | Inside crl | Yes | Path to the CRL file (mutually exclusive with content) |
content "..."; | Inside crl | Yes | Inline PEM/DER bytes (mutually exclusive with filename) |
allow_stale yes|no; | Inside crl | No | Accept peers even when the CRL is past nextUpdate. Default no |
Freshness and allow_stale
crl_directory supports the shared interval forms documented in
interval, including cron schedules and optional
random jitter.
Each CRL carries a nextUpdate timestamp from its issuer. Once that time has
passed, TLS verification rejects peers covered by that CRL unless a validation
allowance applies.
Set allow_stale yes; on a crl or crl_directory block to permit stale CRLs
and unknown revocation status. Certificates listed as revoked are still rejected.
The allowance applies to all CRL sources referenced by the same TLS block.
An AAA certificate-verification policy can override the TLS verification result.
Expiry reporting includes sources whose expiry is enforced by a live TLS consumer. Local certificate deadlines include the configured grace period. Disabled local expiry checks, stale-tolerant CRL use, and CRL use with an AAA verification policy do not produce date-based alerts. A shared source still produces alerts when another consumer enforces its expiry.
Live updates
CRL directories referenced by live TLS consumers are reloaded on the configured
interval without requiring a configuration reload. Unreferenced directories do
not perform periodic reload work. A changed snapshot disconnects dependent TLS
connections and retires their resumption state. Peers must reconnect and
authenticate against the new snapshot; established sessions are not renegotiated.
See server TLS - session resumption and CRL enforcement.
Referencing a CRL
Reference a crl or crl_directory from a TLS block via the crl statement
(repeatable). Both single-file CRLs and CRL directories are valid targets:
servers {
radius "RADSEC" {
listen {
protocol tcp;
ip 0.0.0.0;
port 2083;
tls {
certificate "RADSEC_CERT";
certificate_key "RADSEC_KEY";
server_ca_certificate "RADSEC_SERVER_CA";
require_client_certificate true;
client_ca_certificate "RADSEC_CLIENT_CA";
crl "ALL_CRLS";
}
}
}
}