双因子验证是常见的身份验证需求。FreeRADIUS中如何配置双因子验证呢?我们以LDAP目录服务器中的用户密码验证和OTP服务器中的OTP Code验证来构成双因子,介绍在FreeRADIUS中的配置方法。
RADIUS定义了多步骤验证的交互协议
1. Access-Request 第一次身份验证
2. Access-Challenge 第一次验证通过,要求提供进一步的身份验证
3. Access-Request 第二次身份验证
4. Access-Accept 第二次验证通过
基于此我们把 2FA 过程定义如下:
客户端发起第一次访问验证请求 Access-Request,带上用户名和密码。
服务端通过 LDAP 模块做验证;如果通过,返回 Access-Challenge,带上会话跟踪状态码State。
客户端发起第二次访问验证请求 Access-Request,带上用户名和OTP Code和第一次返回的会话状态码 State。
服务端核对 State,并通过 OTP 模块做验证;如果通过,返回 Access-Accept。
以上任何一步出错或验证未通过,均返回 Access-Reject。
根据上述过程,我们在 FreeRADIUS 服务器端进行相应的配置。
/etc/raddb/sites-available/default
authorize {
if (!State) {
if (&User-Password) {
update control {
Auth-Type := ldap
}
else {
reject
}
}
else {
# TODO: Check State.
update control {
# OTP Auth, python script based.
Auth-Type := otp_auth
}
}
}
authenticate {
Auth-Type ldap {
# ldap 身份验证
ldap
if (ok) {
update reply {
State := "%"
Reply-Message := "Please enter OTP"
}
update control {
Response-Packet-Type := Access-Challenge
}
}
}
Auth-Type otp_auth {
otp_auth
}
}
ldap模块的配置
/etc/raddb/modules-available/ldap:
ldap {
server = ' IP of OpenLDAP Server'
# Other User binding settings.
}
otp_auth 模块的配置。默认安装里面是没有 otp_auth 这个模块的。我们需要自己开发这样的模块;或者使用 perl 或 python 模块来实现相应的功能。
perl 模块的文档
http://networkradius.com/doc/current/raddb/mods-available/perl.html
关键的配置是指向我们所开发的 perl 模块
/etc/raddb/modules-available/perl
perl {
module =
}
python 模块的文档
https://wiki.freeradius.org/modules/Rlm_python
此外,熟悉Apache或Nginx的朋友,会发现 FreeRADIUS 的配置结构与它们相似。FreeRADIUS 对请求处理过程所提供的表达能力基于unlang。unlang 与它的配置语法是兼容的,并进一步提供了简单的逻辑处理能力。unlang 的参考文档地址是
networkradius.com/doc/current/unlang/home.html
更多参考资料:
wiki.freeradius.org/config/Configuration-files
wiki.freeradius.org/config/Virtual-server
wiki.freeradius.org/config/Sites-configuration
wiki.freeradius.org/guide/2FA-Active-Directory-plus-Proxy
wiki.freeradius.org/contributing/Modules3
networkradius.com/doc/current/index.html
networkradius.com/doc/current/unlang/home.html