2026-03-06

v10.32.3

Summary
  • Fix Message-Authenticator attribute handling in logging and backend queries

  • Improved dynamic counter creation with explicit namespace control

  • Configurable counter and histogram history settings (samples and intervals) via pattern matching

  • Template ZIP import now validates that the archive contains only .radtmpl files at the root level

  • The rewrite action now supports the g regex flag for global replacement (/-/g)

  • Management UI improvements: log panel, saved views, deploy flow, log grid filtering and fields column

  • Protocol constants like radius.ACCESS_REQUEST and http.OK now resolve correctly when used outside their native protocol context

  • Add @pipeline syntax for named pipeline blocks and deprecate bare pipeline and template keywords

  • radiator-client: new annotated hex dump in --verbose mode, new --dry-run and --hex-dump flags

  • Add radiusproxy.request.attrs and radiusproxy.reply.attrs bare accessors for reading all proxy attributes as a JSON array

Message-Authenticator improvements

  • Message-Authenticator is now visible in logs. Previously the Message-Authenticator attribute was missing from radius.request.attrs and radius.reply.attrs log entries. It is now included.

  • Message-Authenticator is always added to backend query requests. RADIUS requests sent via backend queries did not include a Message-Authenticator. It is now always added for improved security.

  • Eliminated duplicate Message-Authenticator attributes. In some proxying scenarios a second Message-Authenticator could end up in the outgoing packet. Only a single, correctly computed Message-Authenticator is now present.

Dynamic Counter Namespaces and Configuration

Counter creation now provides explicit namespace control and per-counter configuration via pattern matching.

Breaking Change: Explicit Namespace Required

The count action no longer automatically adds a custom:: prefix. To create counters in the custom namespace, specify it explicitly:

Before:

post-authentication {
    count "login_attempts";
    # Previously created: custom::login_attempts
}

After:

post-authentication {
    # Without :: - uses current handler/backend namespace
    count "login_attempts";
    # Creates: handler::<policy>::<handler>::login_attempts

    # With custom:: prefix - explicit custom namespace
    count "custom::login_attempts";
    # Creates: custom::login_attempts
}

New: Pattern-Based Counter and Histogram Configuration

Configure history settings (samples and intervals) for groups of counters and histograms using pattern matching:

statistics {
    defaults {
        samples 600;      # 10 hours at 1m intervals
        interval 1m;
    }

    # High-frequency monitoring for authentication counters
    counter "/handler::.*::auth.*/" {
        samples 8640;     # 24 hours at 10s intervals
        interval 10s;
    }

    # Custom application metrics
    counter "/custom::.*/" {
        samples 288;      # 24 hours at 5m intervals
        interval 5m;
    }

    # Exact match for critical counter
    counter "critical_errors" {
        samples 1440;     # 24 hours at 1m intervals
        interval 1m;
    }

    # Configure all SQL backend latency histograms
    histogram "/backend::SQL::.*::latency/" {
        samples 720;      # 6 hours at 30s intervals
        interval 30s;
    }
}

Pattern matching uses regular expressions for flexible counter and histogram configuration. Exact matches take priority over patterns.

Histograms track latency distributions using HDRHistogram and expose quantile data (p25, p50, p75, p80, p90, p95, p99, p100) via the Management API. Bucket boundaries are managed automatically and cannot be configured.

Documentation

Template import validation

The template import endpoint (POST /configuration/template/import) now rejects ZIP archives that contain non-.radtmpl files or files in subdirectories. Previously, importing a configuration ZIP into the templates section would silently extract all files without validation.

rewrite global replacement via g flag

The rewrite action now supports the g (global) regex flag to replace all occurrences of a pattern, not just the first match.

rewrite aaa.identity /-/g "";

The previous all parameter was structurally impossible to use due to a parser bug and has been removed. Use the g flag on the regex instead.

See updated documentation in rewrite.

Management UI Improvements

  • Log panel: A resizable bottom panel for viewing logs from any page without navigating away
  • Saved views: Save and restore log grid filter and column configurations as named presets
  • Simplified deploy flow: Configuration check runs automatically on deploy; separate test buttons removed
  • Configuration search: Search across all configuration files from the toolbar
  • Fields column improvements: Collapsed fields render as styled chips; right-click filters by all fields (AND); filter popover always lists individual fields
  • Log grid context menu: Added "Clear all filters" action; column autosize max width capped at 500px

Allow context-independent constant resolution

Protocol constants such as radius.ACCESS_REQUEST and http.OK now work correctly when referenced from a different protocol context. Previously, using radius.ACCESS_REQUEST in an HTTP server handler returned nothing because the RADIUS sub-context was not available, even though the value is a static constant that does not depend on any runtime context.

Define named pipelines with @pipeline syntax

The @pipeline prefix is now the recommended syntax for defining named pipelines. The bare pipeline and template keywords are deprecated and emit warnings when used.

Before (deprecated)

pipeline "MY_PIPELINE" {
    accept;
}

After

@pipeline "MY_PIPELINE" {
    accept;
}

Existing configurations using pipeline or template will continue to work but will produce deprecation warnings in the server log.

radiator-client: Verbose Output, Dry Run, and Hex Dump

New --verbose annotated hex dump format

The --verbose (-v) flag now produces a structured, annotated hex dump of each RADIUS packet. The output includes #-prefixed comment lines for metadata so it can be directly re-fed to --hex or --hex-input-file for packet replay.

Each packet section shows:

  • Header: Code, Identifier, Length, Authenticator, and a hex dump of the 20-byte header
  • Attributes: Type, Length, Format, Name, Value, and a per-attribute hex dump. For vendor-specific attributes (VSAs), the output also includes Vendor-ID, Vendor-Name, and Vendor-Type

New --dry-run flag

Build and display the RADIUS request packet without sending it to the server. Works for both normal and raw (--hex / --hex-input-file) modes. In JSON mode (--json), prints the request as a JSON object. Useful for inspecting what would be sent before actually sending it.

New --hex-dump flag

Print a full raw hex dump after each packet table output. Unlike --verbose, which shows an annotated per-attribute hex dump, --hex-dump displays the entire packet as a single contiguous hex dump. The flag is available on both the main command and the format-packet subcommand.

Other improvements

  • Attribute value formatting uses an en-dash separator and includes the hex value for enum types, e.g. ethernet – 15 (0x0f)
  • Long hex byte values in the table are truncated to 16 bytes with a byte count suffix; full values are still shown in JSON mode
  • Incompatible flag combinations for --hex and --hex-input-file are now rejected at argument parsing time instead of at runtime
  • hex_str_to_bytes now strips #-prefixed comment lines and accepts any ASCII whitespace, making annotated hex output from --verbose valid round-trip input

Documentation

Add radiusproxy.request.attrs and radiusproxy.reply.attrs bare accessors

The bare radiusproxy.request.attrs and radiusproxy.reply.attrs accessors (without a specific attribute name) now return all proxy request or reply attributes as a JSON array of {name, value} objects. This mirrors the existing radius.request.attrs / radius.reply.attrs behavior available in the main RADIUS context.

This is useful for logging all proxied attributes in @pre-proxying and @post-proxying hooks without having to enumerate each attribute individually.

Example

backends {
    radius "UPSTREAM" {
        @pre-proxying {
            copy {
                User-Name;
                User-Password;
                Service-Type;
                cisco-avpair;
            }

            log "PROXY_LOG" {
                json {
                    "proxy_request_attrs" radiusproxy.request.attrs;
                }
            }
        }

        @post-proxying {
            copy {
                Class;
                Cisco-AVPair;
            }

            log "PROXY_LOG" {
                json {
                    "proxy_reply_attrs" radiusproxy.reply.attrs;
                }
            }
        }
    }
}

The logged JSON output will contain all attributes as an array:

{
  "proxy_reply_attrs": [
    {"name": "user-name", "value": "mikem"},
    {"name": "service-type", "value": "framed-user"}
  ]
}

See Execution Context for more details.

Known Issues

When the /var/lib/radiator directory has 15_certificates.radconf file, and the file has not been edited once, the rpm package upgrade will show a warning warning: file /var/lib/radiator/15_certificates.radconf: remove failed: No such file or directory. The warning is harmless and can be ignored, as the 15_certificates.radconf file has been renamed.