FreeRadius : 模块开发(一)

来源:互联网 发布:vue.js和angularjs区别 编辑:程序博客网 时间:2024/05/24 01:04

这篇文章主要总结一些模块开发的基础知识。

http://wiki.freeradius.org/contributing/Modules3

引文是为FreeRadius3.X增加一个模块的帮助文档,在这里做一些翻译。

doc/developer

给开发者的文档,对与模块开发的说明在这里:

https://github.com/FreeRADIUS/freeradius-server/blob/v4.0.x/doc/developer/module_interface.rst

服务器的职责

这个文档首先说明了Freeradius服务器主要工作。Freeradius服务器就是一个认证服务器(AAA服务器,认证、授权、计帐),它只做如下工作:

  • 获取一个RADIUS request
    • 处理该request
    • 在database中查找信息
  • 将信息存储在database中
  • 返回一个response

所以Freerasdius不需定时器等其他复杂的设计,因为那样会让服务器不稳定、不安全、不易维护。(KISS原则即视感)

一些思考:看到这里感觉FR就是在TCP/IP的基础上,进行分包的处理:接收一个请求request包;分析这个包;处理逻辑;返回响应response。
服务器的业务逻辑重点就是分包的处理。底层的IO由网络库来支持好,那么程序员的工作效率会有所提高吧。muduo网络库、handy网络库是C++网络库,libevent是C网络库,应该感谢这些作者。

模块简介

一个模块由若干组件构成:

  • authorization(授权):检查用户是否存在,确定一个认证过程,设置一些response中的attribute
  • authentication(认证):验证密码是否正确
  • accounting(计帐): 将request记录在log中

A module declares which components it supports by putting function pointers in its “module_dl_t rlm_*” structure.

组件其实就是函数,也就是说一个模块需要实现一些特定的函数,供FR调用。这些函数的指针存放在一个叫modult_t的结构中。

模块的配置

要想使用某个模块,需要在radiusd.conf中的modules{}块中添加该模块的实例:

module_name [instance_name] {  param1 = value1  param2 = value2  param3 = value3  ...}

module_name可以在安装目录下的lib文件夹中查找,我的安装目录是/usr/local,因此/usr/local/lib下包含所有安装的模块,名字为rlm_xxx.so

instance_name用于区分同一个module的不同实例,如果只有一个实例可以忽略不写。

param是模块定义的参数,通常是指定database的位置、开启某些功能。它们由服务器直接传递给模块。

当服务器接收到一个Access-Request时,authorize{} 块被调用(它会选定某种Auth-Type),然后authenticate{}中的对应的Auth-Type{}块被调用。最后post-auth{}块被调用。

模块的生命周期

当服务器启动时或接收到SIGHUP而重新初始化时,服务器会读取modules{}块,在该块中的module会被加载,并且它的init()方法会被调用。(没明白init)

接着module的instantiate()被调用,server会给该函数传递两个参数:

  • CONF_SECTION *cs:通过cs可以访问到在前面设置的模块参数等。
  • void *instance : 该模块实例的指针。
int instantiate(CONF_SECTION *cs, void *instance)

模块的authorize(), authenticate(), preaccounting(), and accounting()也以同样的方式被调用,它们的原型如下所示:

int authorize(void *instance, REQUEST *request)int authenticate(void *instance, REQUEST *request)int preaccounting(void *instance, REQUEST *request)int accounting(void *instance, REQUEST *request)

instance与上面相同,是模块的handle,request则代表请求。它们会使用instance中保存的database来处理该request。

当服务器关闭时,模块的detach被调用,它会释放在instantiate中获取的资源。当一个模块的所有实例被detached了,模块的destroy被调用,它释放在init中获取的资源。

src/modules/stable

将模块名字添加到这个文件中,模块会被编译。

服务器处理流程

FreeRADIUS uses a thread pool to serve requests. Each request is processed
synchronously, and processing passes through a series of stages, and a list
of modules in each stage.

The request is processed as follows

  • The radius packet is received by a listener - see listen.c
  • The radius packet is parsed and validated into a request - see ?
  • The request is processed - see process.c
  • The server passes through each authentication stage
    • authorize
    • if Proxy-To-Realm is set:
    • pre-proxy
    • send proxy request
    • post-proxy
    • else
    • authenticate
    • post-auth
  • Authentication stages are lists of modules - see modcall.c
0 0
原创粉丝点击