FreeRADIUS is a great RADIUS server, but custom integration with it has pretty much always left developers with the choice of rlm_python, rlm_ruby, or rlm_perl.
Understandably, rlm_python is not an option for me, so I’ve been doing some work with rlm_perl, and pretty much the first thing I did there, was to use Gearman, and serialisation to get a FreeRADIUS request out of perl as quick as possible, into a gearman queue, and then and into my chosen worker platform of choice — PHP.
Besides, does one REALLY want to drag an entire interpreter, business logic and it’s potential pitfalls into the FreeRADIUS core, and potentially affect it’s stability ?
FreeRADIUS also makes heavy use of threads, so to integrate a random language is quite a bit of a pain, and most of the language modules are non-thread safe so you cannot really benefit from FreeRADIUS thread scaling.
I don’t mind perl, and I’ve worked in it for long enough, but once one looks at the bridge that the above builds to get into a messaging layer, it kind of makes one think… Can it be better ?
Enter rlm_zmq
I’ve built this FreeRADIUS module over the last two days, firstly, because I haven’t really played with zeromq before, and secondly because I wanted to see if I can make the bridge a bit shorter, and faster.
Well, the results are pretty cool. 4500 requests per second for authorisation only in FreeRADIUS, and 3500 requests per second if I use rlm_zmq in every possible processing section in FreeRADIUS (such as accounting, post-auth etc).
ZMQ still requires a “broker” or “queue” manager of some kind if you’re doing the sort of fan-out to fan-out of multiple worker thing that’s required to get some nice scale.
The basic zmq socket architecture is request reply, along these lines:
freeradius_rlm_zmq(zmq socket pool) ----> queue.php <------ worker(s).php
queue.php is a simple message router, that routes between FreeRADIUS threads and worker processes.
In essence, very similar to a standard gearman architecture, but much more ‘native’. ZeroMQ sockets pretty much behave like sockets, except a bit more clever. Gearman has a lot more functionality than zeromq, and I might just attempt rlm_gearman next.
Either way, gone are the days of having to build language specific modules for FreeRADIUS, I think. If you can deserialize json, and can use any of the many language bindings for ZeroMQ, you can now do RADIUS.
rlm_zmq basically adds Mongrel2-like functionality to FreeRADIUS, giving you the option of 30+ languages and a number of N-to-N messaging patterns and load distribution capabilities.
rlm_zmq is pretty much alpha, but it’s fairly stable, and hasn’t yet eaten all my memory alive after hours of hammering with radperf which is always a good thing. In fact, I think it’s about as stable as rlm_perl 🙂
This was a fun project with pretty cool results.