RadSecProxy 的 rewrite 模块 是一个轻量级规则引擎,可以在代理层修改或删除 RADIUS 属性(AVP),常用于给用户名补上 realm、删除不需要的属性等。

最近在做多层 RADIUS/RadSec Proxy 实验时,重新研究了 RadSecProxy 的 rewrite 模块。
本文记录我在 Ubuntu 环境下的配置结构、rewriteIn / rewriteOut 的使用方式,以及官方支持的指令说明。
这篇文章既是笔记,也希望对做 FreeRADIUS + RadSecProxy 结合实验的同学有帮助。


📁 一、目录结构:模块化配置

RadSecProxy 默认只有一个 radsecproxy.conf,但如果实验节点较多,建议改成分文件夹结构,这样更方便维护。

我的目录结构如下 👇:

1
2
3
4
5
6
7
8
9
10
11
12
/usr/local/etc/
├── radsecproxy.conf
├── radsecproxy.d/
│ ├── 00-logging.conf
│ ├── 05-rewrite.conf
│ ├── 10-listen.conf
│ ├── 20-tls.conf
│ ├── 30-clients.conf
│ ├── 40-radius-a.conf
│ ├── 41-radius-b.conf
│ └── 50-realms.conf
└── start-radsec.sh

主配置文件只保留核心内容:

1
2
# /usr/local/etc/radsecproxy.conf
include radsecproxy.d/*.conf

好处:

  • 类似 FreeRADIUS 的结构,按功能分块;
  • 修改单个节点(如 40-radius-a.conf)时更直观;
  • 容易在多机器环境下同步或版本控制。

✉️ 二、rewrite 模块的用途

rewrite 是 RadSecProxy 的轻量级规则引擎,可以在代理层修改或删除 RADIUS 属性(AVP)。
常用于:

  • 给用户名补上 realm;
  • 删除不需要的属性;
  • 在上行包中添加实验标识(如 Route-ID)。

rewrite 模块支持两个方向:

类型 触发方向 常见用途
RewriteIn 收到下游包时 修改或补齐属性(例如 User-Name)
RewriteOut 发往上游包时 添加额外字段或诊断标识

⚙️ 三、rewrite 文件示例

我将 rewrite 规则单独放在:

1
/usr/local/etc/radsecproxy.d/05-rewrite.conf

内容如下:

1
2
3
4
5
6
7
8
9
# 如果 User-Name 中没有 @,自动补上 realm
rewrite add_realm {
ModifyAttribute User-Name:/^([^@]+)$/\[email protected]/
}

# 在发往上游的包中添加调试标识
rewrite add_diagnostic {
AddAttribute Reply-Message:proxy=gotolab-radius-test
}

在对应配置文件中启用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# /usr/local/etc/radsecproxy.d/30-clients.conf
client radius-a {
type udp
host 192.168.8.2195
secret testing123
RewriteIn add_realm
}

# /usr/local/etc/radsecproxy.d/40-radius-a.conf
server radius-a {
type tls
host 192.168.8.228
secret rasdecproxy123456578
RewriteOut add_diagnostic
}

🧠 四、rewriteIn 与 rewriteOut 的区别

项目 rewriteIn rewriteOut
执行时机 收到下游的 Access-Request 时 发往上游服务器时
修改方向 入站(incoming) 出站(outgoing)
可修改属性 普通 RADIUS AVP 普通 RADIUS AVP
不可操作 EAP-Message(二进制内容) 同左
是否可判别 Accept/Reject ❌ 无法区分响应类型 ❌ 无法区分响应类型

⚠️ rewrite 无法识别返回包类型(Accept / Reject),它只基于“包方向”工作。
如果需要按结果做判断,可在 FreeRADIUS 侧添加自定义 AVP,例如 My-Result


🔧 五、rewrite 模块官方指令一览(2025 最新版)

以下为 RadSecProxy 官方支持的 rewrite 指令(参见文末链接):

指令 说明
RemoveAttribute attribute 删除指定属性(例如 User-Name)
RemoveVendorAttribute vendor[:subattribute] 删除厂商属性或其子属性
ModifyAttribute attribute:/regex/replace/ 用正则替换普通属性值
ModifyVendorAttribute vendor:subattribute:/regex/replace/ 用正则替换厂商属性值
AddAttribute attribute:value 添加普通属性
AddVendorAttribute vendor:subattribute:value 添加厂商属性
SupplementAttribute attribute:value 如果属性不存在则添加
SupplementVendorAttribute vendor:subattribute:value 如果厂商属性不存在则添加
WhitelistMode on/off 开启白名单模式(其余属性会被删除)
WhitelistAttribute attribute 白名单保留普通属性
WhitelistVendorAttribute vendor[:subattribute] 白名单保留厂商属性

client / server 块中启用:

1
2
RewriteIn  <rewrite-name>
RewriteOut <rewrite-name>

⚠️ 旧语法 Rewrite <rewrite-name> 已被废弃(deprecated),建议使用新写法。


🧩 六、rewrite 的限制与调试技巧

限制:

  • 不能直接修改 EAP-Message;
  • 不支持 FreeRADIUS 式条件(if / else / expr);
  • rewrite 的执行顺序是静态绑定;
  • 无法区分 Access-Accept / Reject;
  • 所有同名属性都会被匹配。

调试技巧:

  • 把日志级别设为 4 或更高:

    1
    2
    LogLevel 4
    LogDestination stderr
  • 启动时加 -f 参数:

    1
    radsecproxy -f -d 4

可以在日志中看到 rewrite 执行的匹配、添加和替换行为。


💬 七、实践经验与建议

🧩 推荐分目录结构(radsecproxy.d/)管理配置;
⚙️ rewrite 仅用于静态规则,逻辑判断放 FreeRADIUS;
🔄 rewriteOut 可添加路径标识,方便多层代理实验;
🧠 生产环境建议关闭 DebugLevel,避免性能影响;
🚫 rewrite 不支持 Lua、Python 或 Redis 调用,如需动态逻辑可转交上游 RADIUS。


✨ 八、总结

RadSecProxy 的 rewrite 模块虽然不如 FreeRADIUS 的 unlang 灵活,
但它轻量、稳定,非常适合在 TLS Proxy 层进行轻量改写与属性清洗。
配合模块化目录结构,可以让多节点实验更清晰、更可维护。

我目前的用法是:

1
2
rewrite 层负责静态加工
FreeRADIUS 层负责动态逻辑与日志分析

这种分层设计,在 Wi-Fi 联邦认证系统或分布式 Proxy 环境中尤其高效。


📌 参考资料