Certificate Revocation Lists
How Radiator Server uses CRLs to reject revoked TLS peers, and when CRL changes take effect.
Certificate Revocation Lists
A Certificate Revocation List (CRL) is a signed file from a Certificate Authority (CA) that names the certificates the CA has revoked before their normal expiry. Radiator Server reads CRLs and uses them during TLS handshakes to reject peers whose certificate has been revoked.
This article explains how Radiator handles CRLs in practice: where you put the files, when changes take effect, and what you see in the logs. For the configuration reference see certificates clause.
When to Use a CRL
Use a CRL when you need to:
- Revoke a stolen or compromised client certificate before it expires.
- Stop accepting a deprovisioned RadSec proxy or RADIUS/TLS peer.
- Enforce a CA's revocation policy on EAP-TLS, PEAP, or TTLS clients.
Radiator does not download CRLs from the network. You publish the CRL as a file on the server filesystem and Radiator picks it up.
How to Publish CRLs
In most deployments, use a crl-directory:
certificates {
crl-directory "ALL_CRLS" {
directory "/etc/radiator/certs/crls";
interval 1h;
}
}
A crl-directory is a directory on the server filesystem that holds one CRL per file. Radiator reads the directory at startup and rescans it on the configured interval. New, removed, and changed files are picked up automatically without a configuration reload.
A crl-directory accepts files with extension .crl, .pem, or .der. Other files in the directory are ignored. An empty directory is a valid configuration; it just means no certificates are revoked yet.
For static deployments where the CRL never changes (for example a CA that does not publish CRL updates), you can use a single crl block instead. A single crl block is read once at configuration load and is not re-read until you reload the configuration. If you ever need to add a revocation, you have to reload Radiator. For this reason, prefer crl-directory whenever the CRL is expected to change over time.
A TLS block can reference any number of crl and crl-directory entries with the crl statement (repeatable). Radiator merges all of them into one CRL set per handshake. If a TLS block references no CRL, no revocation check is performed in that block.
When CRL Changes Take Effect
A new revocation entry takes effect on the next handshake after Radiator picks up the new CRL:
| Source | When the new CRL is loaded |
|---|---|
crl-directory | On the next refresh tick after the file changes |
crl | Only on a configuration reload |
For crl-directory, the reference from a tls { ... } block does not need to be re-declared; the new CRLs are used automatically on the next handshake.
Already-established TLS sessions are not affected. They keep running until they close on their own. See TLS Session Resumption for the implication on long-lived sessions.
What Happens at Startup
When Radiator starts (or reloads the configuration), each CRL source is read from disk:
- A
crl-directorysource reads every accepted file. If a single file fails to open, is too big, or fails to parse, Radiator logs a warning and skips that file. The remaining files still load. - A
crlsource reads one file. If the file is a PEM bundle that contains more than one CRL, Radiator keeps only the first CRL and logs a warning. Usecrl-directoryif you need multiple CRLs.
For each CRL parsed, Radiator inspects the nextUpdate field and writes a freshness log line:
Tracewhen the CRL is fresh.Warnwhen the CRL expires within the next 24 hours.Errorwhen the CRL is already pastnextUpdate.
If you only watch Warn and Error lines, you will see soon-to-expire CRLs in advance and stale CRLs immediately.
What Happens on Every Refresh
For each crl-directory, Radiator runs a background task that rescans the directory on the configured interval. On every tick the task:
- Reads the directory.
- Compares the new contents against the current CRL set.
- If nothing changed, logs a
Traceline and does nothing else. - If something changed, replaces the CRL set and logs an
InfolineCRL directory snapshot changedwith the new CRL count. - If the directory cannot be read, logs an
Errorline and keeps the previous CRL set in place. Radiator does not drop CRLs on a transient read failure.
If a refresh is still running when the next tick fires (for example because the disk is slow), the new tick is skipped. Refreshes do not pile up.
After a refresh publishes a new CRL set, the next TLS handshake on any listener that references this CRL source uses the new CRLs automatically.
What Happens on a Handshake
When a peer presents a certificate, Radiator runs the standard TLS path verification and, in addition, checks the certificate against the merged CRL set for that TLS block. The result is one of:
- Accept: the certificate is not on any CRL and the verifier is happy.
- Reject: the certificate is on a CRL, or the CRL itself is unusable. Radiator logs a
WarnlineTLS handshake rejected by CRLwith a rejectionkind, the peer subject, and the issuer. The handshake fails. The peer must present a non-revoked certificate to connect.
The rejection kind is one of:
revoked- the peer's certificate is on a CRL.unknown_revocation_status- revocation status cannot be determined (no usable CRL covers this issuer).expired_revocation_list- the CRL that covers this issuer is pastnextUpdate.
The Warn line also increments a counter, so a steady rate of rejections is easy to spot.
allow-stale
A stale CRL (one whose nextUpdate has passed) cannot prove that a certificate is still valid. The default is to reject any peer whose chain depends on a stale CRL with expired_revocation_list.
Set allow-stale yes; on a crl or crl-directory block to relax this rule. With allow-stale yes, Radiator accepts peers when the CRL is past nextUpdate. Two properties to keep in mind:
- A revoked certificate that appears in a stale CRL is still rejected. Only the "unknown" status is relaxed.
- The flag applies to the whole TLS block, not to one CRL. If any CRL referenced from a TLS block has
allow-stale yes, every CA referenced from that TLS block is treated under the relaxed policy.
Use allow-stale yes only when CRL distribution is unreliable and brief over-acceptance is acceptable.
CRLs and AAA Pipelines
In setups that authenticate via an AAA pipeline (for example EAP-TLS with a custom verification policy), the AAA pipeline is the final authority on whether to accept the peer. If the CRL check rejects the certificate but the AAA pipeline accepts it, Radiator accepts the connection. This is intentional: an operator policy can override revocation.
Radiator makes overrides visible:
- A
Debugline is emitted on every override. - The same line is automatically promoted to
Warnonce per minute, with a counter.
If you want CRLs to actually block revoked peers in this setup, the AAA pipeline must look at the certificate verification result and fail the policy when the certificate was revoked.
TLS Session Resumption
TLS session resumption (the TLS 1.2 session cache and TLS 1.3 session tickets) lets a peer skip the full handshake and reuse a previous session. A resumed session does not re-run certificate verification, so a peer that was revoked after its first handshake can keep resuming until the session expires.
If prompt revocation is required:
- Disable TLS 1.3 session tickets on the listener.
- Disable TLS 1.2 SessionID resumption on the listener, or keep TLS 1.2 session lifetimes short when resumption is required.
See server TLS - session resumption and CRL enforcement for the recommended settings.
Operational Tips
- Pick an
intervalthat matches the CA's CRL publishing cadence. A much shorter interval only causes no-op refreshes (logged atTrace) and is harmless. A much longer interval delays revocation enforcement. See interval for syntax variants and context-specific support. - Watch the
CRL directory snapshot changedandTLS handshake rejected by CRLlog lines and counters. They show that the refresh path and the revocation path work end to end. - Watch the CRL freshness
WarnandErrorlines. A stale CRL almost always means a publishing pipeline somewhere has stopped. - For multi-CRL deployments, use
crl-directoryinstead of one big PEM bundle. A bundle silently keeps only the first CRL.
Related Pages
- certificates clause - configuration reference for
crl,crl-directory, andallow-stale. - server TLS - referencing CRLs from a server-side TLS block, and session resumption settings.
- Duration Units - syntax for the
intervalvalue.
About Radiator software development security
Architecture Overview
Backend Load Balancing
Basic Installation
Built-in Environment Variables
Byte Size Units
Certificate Revocation Lists
Comparison Operators
Configuration Editor
Configuration Import and Export
Containers
Cron and interval timers
Data Types
Duration Units
Environment Variables
Execution Context
Execution Pipelines
Filters
Getting a Radiator License
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Linux systemd support
Local AAA Backends
Log storage and formatting
Management API privilege levels
Namespaces
Password Hashing
Password Rehashing During Login
Probabilistic Sampling
Prometheus scraping
PROXY Protocol Support
Radiator server health and boot up logic
Radiator sizing
Radiator software releases
RadiatorDB
RadiatorDB Backup
RadiatorDB CLI
RadiatorDB Installation
RadiatorDB REST API
Rate Limiting
Rate Limiting Algorithms
Reverse Dynamic Authorization
Service Level Objective
TACACS+ Authentication, Authorization, and Accounting
Template Rendering CLI
Timestamp Format
Timestamps
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?
YubiKey Authentication
YubiKey Context Variables
About Radiator software development security
Architecture Overview
Backend Load Balancing
Basic Installation
Built-in Environment Variables
Byte Size Units
Certificate Revocation Lists
Comparison Operators
Configuration Editor
Configuration Import and Export
Containers
Cron and interval timers
Data Types
Duration Units
Environment Variables
Execution Context
Execution Pipelines
Filters
Getting a Radiator License
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Linux systemd support
Local AAA Backends
Log storage and formatting
Management API privilege levels
Namespaces
Password Hashing
Password Rehashing During Login
Probabilistic Sampling
Prometheus scraping
PROXY Protocol Support
Radiator server health and boot up logic
Radiator sizing
Radiator software releases
RadiatorDB
RadiatorDB Backup
RadiatorDB CLI
RadiatorDB Installation
RadiatorDB REST API
Rate Limiting
Rate Limiting Algorithms
Reverse Dynamic Authorization
Service Level Objective
TACACS+ Authentication, Authorization, and Accounting
Template Rendering CLI
Timestamp Format
Timestamps
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?
YubiKey Authentication
YubiKey Context Variables