radqueue - RADIUS accounting solid state queue daemon

Purpose

In some environments reliability of accounting messages is very important. Packet looses, network problems, maintenance poweroffs - all this can lead to loosing information about accounting. This is especially a problem when precious resources are assigned to open sessions and Accounting Stop message was lost. Features like rdd graphs of bandwidth usage of ppp users will require that no single accounting packet is lost.

Stateless nature of RADIUS protocol leads to problems with session tracking and handling. In Lintrack easy and efficient way was needed to let know scripts/other programs about opened sessions and other necessary information (pid of program associated with sessions and such).

Concept

Radqueue uses a concept of delayed delivery: when accounting packet "can't go through", just wait and send it other time. Stored in queue, accounting information can wait patiently. Same queue will be used as "session-tracker". New entries will appear when session opens and closing session will remove them.

With little modification to radius library and one additional system daemon (radqueue) this goals can be achieved.

Implementation details

As this is not official standard and radqueue functionality is still experimental, this may change in the future. For most accurate information - look into the source.

Spool dir

As an example:

/var/spool/radius# ls -al
total 4
drwxrwx--- 4 radqueue radqueue 1024 Oct  5 20:17 .
drwxrwxr-x 5 root     root     1024 Oct  5 19:27 ..
drwxrwx--- 2 root     radqueue 1024 Oct  5 20:08 4525665308B7
drwxrwx--- 2 root     radqueue 1024 Oct  5 20:57 45256869089C

Both 4525665308B7 and 45256869089C are session dirs. Each name of the dir is unique id of the session that it handles. Such dir is created by process trying to send Acct-Start packet using libradius-asn library. Library transparently intercepts such packet (and each following Interim-Update and Acct-Stop) and stores it inside of session dir. Radqueue will watch spool dir for session dirs using inotify.

/var/spool/radius/4525665308B7# ls -al
total 5
drwxrwx--- 2 root     radqueue 1024 Oct  5 20:08 .
drwxrwx--- 4 radqueue radqueue 1024 Oct  5 20:17 ..
-rw-rw---- 1 root     radqueue    2 Oct  5 20:08 nas-port
-rw-rw---- 1 root     radqueue    4 Oct  5 20:08 start-pid
-rw-rw---- 1 root     radqueue    7 Oct  5 20:08 user-name

These are files created when session-dir is created. Their content is obvious. What is worth mentioning is that start-pid is kind of lock - it's created last. Radqueue will not deal with session dir untill it's ready. Other than this - it stores pid of session opener process.

Using inotify mechanism radqueue daemon will watch all session dirs for new acct files (as a matter of fact it uses "closing of file opened for writting" event for that). Each new file of name acct-* will start session dir flush mechanisms. The oldest of acct-* file will be delivered. If it succeed - next one will be used. If packet was of Acct-Stop type, radqueue will delete session dir.

Full flush interval, packet dropping and closing old sessions

Radqueue will regularly try to flush all session dirs - even if there was no activity inside them. This time can be changed using command line option.

As RADIUS standard requires RADIUS servers to drop invalid packets so there is no feedback about that fact. When for some reason accounting packet is invalid it will stuck in session dir queue. To deal with that radqueue use "badness counters" - one per session dir. It's zeroed when current packet was delivered and increased each time previous (note: previous in time, not necessary in same queue) packet was delivered and current is not. If this happens several times, there is great chance that current packet is just invalid and it will be dropped, and other actions will be taken just as it was delivered - so it's just a matter of time for every session on the working system to be flushed and disk space to be saved. Each packet dropped because of invalidity will be reported and if this is common problem - should be investigated and may mean possible configuration mistake or bug in the code.

After NAS reboot all sessions opened previously at NAS are invalid. To mark them closed radqueue --stop-all must be invoked (most probably by init scripts). With this switch radqueue will just add Acct-Stop packet to each session dir, marking it closed. After that radqueue will exit. Using previously mentioned methods normal-mode radqueue daemon will handle possible accounting packets, even if they are invalid and then delete old session - just like it was normal Acct-Stop.

Security

Whole security is using unix filesystem permission control. Spool directory (/var/spool/radius) is writeable for users belonging to radclient group. Processes that will use radqueue have to be added to this group.