FreeRADIUS InkBridge

Python

FreeRADIUS can call Python scripts in order to utilize third party libraries which are only available in Python, or to execute particularly complex policy.

Requires Python 3.8 or later

Global configuration

Due to limitations in Python, the search path for modules can only be set globally, rather than per module instance.

This is set in the Python global config.

Module configuration

Each rlm_python module instance should set a module option which is the default Python module from which functions will be called.

An instantiate and detach function can be defined to run code during server start up and shutdown.

When rlm_python is called in a processing section, by default the function called is based on the section name. e.g. if the call is made in recv Access-Request then, recv_access_request will be called if it exists, otherwise recv will be called.

In order to override the function being called, configuration options such as func_recv_access_request or func_recv can be used. e.g.

func_recv_access_request = authorize

could be used to use previous function names.

In addition, the Python module can be changed on a per function basis with configuration options such as mod_recv_access_request or mod_recv.

If rlm_python is called with a suffix, e.g.

python.my_function

then, by default my_function will be called in the default module. As with other calls the module can be specified with mod_my_function and the actual function with func_my_function.

Python function behaviour

Each function is called with an object representing the request, which contains objects representing the attribute lists.

Attributes can be accessed using Python dict syntax, e.g. p.request['User-Name'] which is an object representing that attribute.

When an attribute is referenced in string context (e.g. wrapped in str()) then the string representation of the attribute value will be returned.

Each attribute object has a value which can be used to get or set its value in the appropriate native Python type based on the type of the attribute in the dictionary e.g.

p.reply['Class'].value = b'abc'

If functions returns None (plain return' no return), this is treated as `ok.

Specific return codes can be accessed with pre-defined constants in the freeradius module. e.g.

return freeradius.RLM_MODULE_UPDATED

The Python instantiation function can return -1 to signal failure and abort startup.

freeradius Python module

FreeRADIUS provides a module, freeradius, which can be used by any Python scripts used by rlm_python.

This module provides:

Constants

Constants are provided for return codes and log level.

The return code constants are all of the form freeradius.RLM_MODULE_<RCODE> e.g. freeradius.RLM_MODULE_OK. Log level constants are of the form freeradius.L_<level> e.g. freeradius.L_DBG.

In addition, if the module config contains a config subsection, that is parsed to form a dictionary e.g.

config {
	name = "value"
}

will result in freeradius.config['name'] having the vaule value.

Function

The function freeradius.log() can be called to write log messages via the FreeRADIUS logging mechanisms.

import freeradius
freeradius.log(message_string, freeradius.L_XXX)

Its arguments are:

  • The message to log

  • (optional) log type (e.g. freeradius.L_DBG)

  • (optional) log level - the FreeRADIUS debug level at which this message should be logged. (e.g. L_DBG_LVL_2)