Skip to content

NETWAYS/rt-extension-sessionstoreredisttl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RT::Extension::SessionStoreRedisTTL

Expiring Redis web sessions for Request Tracker 6 — plus cryptographically strong session IDs.

RT 6 can keep web sessions in Redis with $WebSessionClass = 'Apache::Session::Redis'. That backend writes every key with a plain SET and no expiry, so session keys pile up in Redis forever (a busy instance ends up with hundreds of thousands of dead keys). $AutoLogoff makes idle sessions functionally invalid but never deletes their data, and rt-clean-sessions only reaps SQL-backed sessions.

This extension ships a drop-in $WebSessionClass, RT::Session::RedisTTL, that keeps the proven Apache::Session::Redis serialization (Base64/Storable, hex IDs — so a blessed RT::CurrentUser survives the round trip) but:

  • writes keys with a Redis expiry (SET … EX), defaulting the TTL to $AutoLogoff, so idle sessions expire on their own; and
  • by default generates session IDs from the system CSPRNG instead of the weak md5(time/rand/pid) the stock backend uses.

Only the store driver and (optionally) the ID generator change. The serialized payload and ID format are identical to Apache::Session::Redis, so existing sessions stay readable and valid — rolling this out logs nobody out.

Why not Apache::Session::Browseable::Redis

It supports a TTL out of the box, but is hardcoded to a JSON serializer (to_json without convert_blessed). RT stores a blessed RT::CurrentUser in the session; JSON silently drops it on the round trip, so the session comes back broken. The problem is purely the serializer — so this extension keeps Base64/Storable and adds the TTL at the store layer instead.

Installation

perl -I. Makefile.PL    # -I. is required: modern Perl drops "." from @INC
make
make install            # may need root

Then add to /opt/rt/etc/RT_SiteConfig.pm:

Plugin('RT::Extension::SessionStoreRedisTTL');
Set( $WebSessionClass, 'RT::Session::RedisTTL' );
Set( %WebSessionProperties, server => '127.0.0.1:6379' );

Activating the plugin is required — it puts the extension's lib/ on @INC, which is how the store driver gets found (it is loaded by name at request time). Then clear the Mason cache (rm -rf /opt/rt/var/mason_data/obj) and restart the webserver.

Configuration

TTL

The key TTL (seconds) is resolved in this order:

  1. an explicit TTL in %WebSessionPropertiesTTL => 0 opts out (plain SET, no expiry);
  2. else $AutoLogoff * 60 — the idle window after which RT logs the user out — if $AutoLogoff is set and non-zero;
  3. else an 8h floor. RT's $AutoLogoff defaults to 0 (off), so this guarantees keys always expire instead of accumulating forever.
Set( %WebSessionProperties,
    server => '127.0.0.1:6379',
    TTL    => 43200,   # seconds; optional, see resolution order above
);

update is aliased to insert, so the TTL is refreshed on every write — a sliding idle expiry; active sessions are never reaped. Pick a TTL >= $AutoLogoff so an idle key does not vanish before RT's own logout window.

$RedisSessionSecureID (default: on)

Session IDs are drawn from the system CSPRNG. To fall back to the legacy MD5 generator:

Set( $RedisSessionSecureID, 0 );

Security

The stock generator, Apache::Session::Generate::MD5, builds the ID as md5_hex(md5_hex( time() . {} . rand() . $$ )). Its unpredictability comes only from Perl's rand() (a non-cryptographic drand48 PRNG), an anonymous hash's address, the pid and the wall-clock second. The MD5 step adds no entropy — and switching to SHA-256 or any other digest would not help, because a hash of low-entropy input is still low-entropy. (RT's own RT::AuthToken::_GenerateToken uses the same time/rand/{} pattern with SHA-512.)

So this extension sources IDs from the OS CSPRNG (Crypt::URandom: getrandom(2) / /dev/urandom) by default, keeping the 32-hex-character format so the inherited validator still accepts old MD5 IDs. It is a strict security improvement with no compatibility cost.

The TTL value comes from configuration ($AutoLogoff or an explicit TTL), never from anything client-supplied, and is validated to a positive integer before it reaches Redis.

Migrating existing keys

Old keys written without a TTL persist until they are next written (then they gain one). To retire the accumulated keyspace in one go, flush the session DB during a maintenance window before cutover — this only logs everyone out, it does not lose ticket data:

redis-cli -n 0 FLUSHDB

Requirements

License

GPL v2. Copyright (c) 2026 NETWAYS GmbH.

About

Expiring Redis web sessions for Request Tracker 6, with CSPRNG session ids

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages