摘要
- RADIUS 的单字节 Identifier 只在特定客户端端点和待处理时间窗内帮助匹配请求与应答;客户端还必须用该请求的 16 字节 Request Authenticator 和共享密钥验证 Response Authenticator。
- 发往同一服务器、内容不变的重传必须保留 Identifier、Request Authenticator 和源端口。服务器识别重复包后重发缓存的原应答而不再次执行认证;属性改变则意味着新的请求。
256 个格子从来不是全球流水号
RADIUS 报文开头依次是 Code、八位 Identifier、Length、16 字节 Authenticator 和属性列表。这个布局很容易诱使人把 Identifier 读成“交易号”。但八位只有 256 个取值,一个接入服务器可以同时处理许多用户、重传丢失的 UDP 包、切换备用服务器,还可能完成多轮质询。
RFC 2865 对这个字段的措辞很克制:它“帮助”匹配请求和应答。RFC 5080 随后明确,客户端在同一源地址和源 UDP 端口上,不得在前一请求收到有效应答或超时之前复用 Identifier,并建议按最久未使用的顺序分配。
因此,37 的意义不是永久的“第 37 次认证”,而是“这个端点当前仍在等待的 37”。待处理状态结束后,37 可以再次出现,含义也随之重生。1997 年 1 月的第一份 RADIUS RFC——RFC 2058——已经采用这种小而局部的命名方式;同年 4 月的 RFC 2138 和 2000 年的 RFC 2865 保留了这个结构。
协议没有建立一个为所有认证请求发号的中央登记簿。它选择让短编号只在一段活跃上下文中有意义。
应答不是把问题原样抄回去
Access-Request 的 Authenticator 是 16 字节随机值,称为 Request Authenticator。RFC 2865 要求每次使用新 Identifier 时更换它,并要求其在共享密钥寿命内尽量不可预测、时空唯一。
这不是单纯把编号空间从 8 位扩成 128 位。若同一共享密钥下重复使用请求值,攻击者可能重放曾经截获的应答;若未来请求值可以预测,攻击者可能提前诱使服务器生成可供冒充的答案。它同时承担关联和抗伪造材料的角色。
Access-Accept、Access-Reject 或 Access-Challenge 会复制原请求的 Identifier,但 Response Authenticator 不是简单回显。服务器对响应的 Code、Identifier、Length、原请求的 Request Authenticator、响应属性和共享密钥做 MD5 计算。
客户端收到包后,先用八位数找到一个候选待处理请求,再用那个请求的 Request Authenticator 与共享密钥验算。一个迟到的旧应答即使也叫 37,只要它绑定的是上一次的 Request Authenticator,就无法通过当前请求的校验,必须静默丢弃。
八位数缩小查找范围;16 字节值把答案绑到具体问题;共享密钥证明这一跳的对端掌握共同秘密;待处理状态限定时间。任何一项单独拿出来,都不是完整身份。
“再发一次”必须保持为同一件事
经典 RADIUS 运行在 UDP 上。接入决定需要在数秒内得到,而不是等待传输层几分钟后交付一份已经失去价值的旧数据。客户端因此在传输层上方保存请求副本,自己管理计时器,可以重发或尝试备用服务器。
但重发会提出一个比丢包更重要的问题:下一份数据报,是同一决定的再次投递,还是值得服务器重新判断的新问题?
RFC 2865 划出了机械而明确的边界。向同一服务器重传未改变的属性时,NAS 必须保留原 Identifier、Request Authenticator 和源端口。任何属性发生变化,就必须使用新的 Identifier 和 Request Authenticator。
所以,第二个 UDP 包不必然是第二次登录。只要内容和交易材料不变,它仍是第一次尝试在寻找一条可达的回程。反过来,加入 Event-Timestamp、替换口令响应或改变所请求的服务,都不是给旧请求“补充一点信息”,而是发起新问题。即使用户名不变、操作者也认为意图相同,线上的请求身份已经改变。
重放一个结论,比重做一次决定更安全
丢包之后,服务器可能收到完全相同的 Access-Request。如果每个副本都进入后台,计数器可能增加两次,一次性凭据可能被消费两次,审计系统可能记录两次登录,昂贵的身份查询也会重复执行。
RFC 5080 因此把重复检测写成服务器必须实现的行为,并要求缓存已经发出的 Access-Accept、Access-Reject 或 Access-Challenge。若重复请求在应答发出之后到达,服务器原样重发缓存的应答,不再处理请求;若原请求尚在处理中,重复包静默丢弃,不启动并行认证,也不制造临时结论。
缓存匹配不只看 Identifier。它包括源地址、源端口、接收套接字、Identifier 和 Request Authenticator,通常只保留五到三十秒。前四项相同而 Request Authenticator 不同,会使旧缓存项失效。协议拒绝让“看起来很像”覆盖真正区分尝试的材料。
这里保存的不是一个永恒 verdict。短期缓存只为修补不可靠传输:服务器已经做过一次判断,客户端可能只是没收到。重发原答案恢复了交付,而没有虚构第二次业务动作。
内容一变,旧答案就失去发言资格
设想客户端第一次请求仍在某台服务器上处理,却因为超时改变一个属性,生成新的 Identifier 与 Request Authenticator 再发一次。旧服务器稍后给出的应答可能在密码学上完全有效,但它只回答旧问题。
RFC 5080 要求客户端丢弃早先尝试的应答,以当前请求收到的结果为准,即使两个时刻或两台服务器得出相反结论。有效签名材料只能说明“这是那个问题的真实回答”,不能让那个问题永久保持待决。
Access-Challenge 把这种区别展示得最清楚。服务器可以返回 State,并要求用户给出下一轮响应。NAS 会创建新的 Access-Request,使用新的 Identifier 和 Request Authenticator,带回 State 并加入新答案。State 连接的是认证会话的多轮上下文;它没有把多轮报文压成一笔交易。
“还是这个用户”属于应用层判断,“还是这个请求”则由精确属性和交易材料决定。协议必须对后者严格,不能凭人类对前者的直觉做替换。
第一个有效应答关闭窗口
重传和备用服务器可能让多个应答返回。客户端处理第一个能够针对待处理请求通过 Response Authenticator 校验的应答。请求一旦不再待处理,后到包就成为非请求应答,必须静默丢弃。
这条规则不会自动消除服务器之间的策略差异。主服务器可能 Reject,备用服务器可能 Accept;用户库、策略和多轮状态是否一致,仍由运营者负责。交易规则只阻止迟到包重新打开客户端已经完成的决定。
Access-Accept 也不会凭空创造服务能力。RFC 2865 要求 NAS 在无法提供服务器指定的服务时把它视为拒绝。合法报文证明某一跳给出了与请求绑定的结果,不等于 VLAN、路由、端口或其他能力已经实际生效。
代理会终止旧证明,再建立新证明
RADIUS 经常经过代理。转发服务器收到下游响应后,先用它与下游共享的密钥验证 Response Authenticator,移除自己加入的最后一项 Proxy-State,把 Identifier 恢复为上游 NAS 所期待的值,再用上游共享密钥计算新的 Response Authenticator。
于是,NAS 拿到的不是家庭服务器贯穿全链路的一枚签名,而是直接 RADIUS 对端给出的这一跳证明。Proxy-State 帮助答案沿链路返回,对没有创建它的节点应保持不透明;它本身不授予网络接入权。
只记录“ID 37,Accept”几乎没有取证价值。可解释的记录至少需要标明哪一跳、客户端地址与端口、接收套接字、待处理时长、Request Authenticator 的受保护指纹、代理路径、重复缓存动作,以及 NAS 最终执行了什么。共享密钥、用户口令和敏感质询内容则不应进入普通日志。
重试也可能组成一场拥塞
RFC 5080 记录过另一种失败:一些客户端使用一秒甚至更短的固定重试间隔,没有拥塞退避。一次断电后,数千台 NAS 同时恢复、同时请求、同时超时,再同时重传,足以把认证系统压垮。
建议算法让超时逐步增长,加入抖动,并设置单次间隔、次数和总时长上限。这里的随机性用于打散群体节奏,不要求密码学强度;Request Authenticator 的不可预测性服务于安全,两者不能因为都叫“随机”就共用低质量生成器。
过载时,服务器可优先处理带有效 State 的后续轮次,使已经开始的会话更有机会完成;代理也可先转发家庭服务器的应答,再接纳更多新请求。这是稳定性排序,不是对某个用户授予更高权利。
TLS 后来移动边界,但没有改写 UDP 历史
RFC 6614 在 2012 年把 RADIUS 放入 TLS/TCP,却保留历史报文的共享密钥与 MD5 处理,并以固定的 radsec 作为旧计算所需密钥。TLS 保护连接,经典头部机制仍在隧道内运行。
2025 年的 RFC 9765 重新处理了这层重复。双方在 TLS 1.3 或更高版本上通过 ALPN 明确协商 RADIUS/1.1 后,共享密钥与 MD5 报文机制才被移除,原 16 字节 Authenticator 空间改作不透明 Token,旧 Identifier 的关联功能也由 Token 取代。
这是与现有 BTW RADIUS/1.1 稿件的分界,不是本篇主体。它不改变普通 RADIUS/UDP,也不让代理链上的其他跳自动升级。它只再次证明:无论真实性由哪一层承担,请求和响应仍需要足够大的、受上下文约束的关联值。
这个证明从未等于用户身份
经典 Response Authenticator 是历史协议机制,不是今天推荐采用 MD5 的理由。它只能说明一份响应来自掌握这一跳共享密钥的系统,并与某个仍待处理的请求相符。它不能独立证明用户是谁,不能证明服务器策略正确、会计记录已提交、代理没有滥权,也不能证明 Accept 之后的业务流量真的通过。
RFC 可以证明规范如何定义和修正机制,不能证明任何产品符合规范,更不能给出当前部署比例。RADIUS 留下的长期教训不是“小编号也足够安全”,而是编号的权力来自它仍然活着的上下文。把上下文丢掉、只把短编号留进报表,才会把一个严谨的临时名称变成误导性的永久证据。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
