摘要
- Proxy-State 是代理为自己安排的返回状态。其他代理必须保全其内容及同类属性之间的顺序,却不能把其中的私有编码当成自己的协议指令。
- 代理不一定把此前收到的 Proxy-State 全部继续向前传递;如果选择暂存,就必须在回复下游时重新附上。因此,原样归还不等于每个值都到过最终服务器。
- 保全状态、执行本地策略和保护相邻连接是不同的工作。它们可以同时存在,却不能互相替代,更不能合并成一份端到端的信任保证。
没有继续前进,也必须回来
设想一份接入请求经过两个 RADIUS 代理。第二个代理看到了第一个代理放进去的 Proxy-State,却没有把它发给下一站。请求照样继续,远端也给出了答复。只看向前传递的报文,人们可能认为,某段状态已经在中途丢失。
按照 2000 年 6 月的 RFC 2865,事情未必如此。转发服务器可以不把此前收到的 Proxy-State 放进下一份请求,条件是在回复原来的客户端之前,把那些值重新附上。它有义务归还,并不一定有义务让每个值走完整条路径。
这个例子不是一宗网络事故,而是协议允许的两种实现选择之间的区别。代理可以继续携带别人的状态,也可以承担本地保存和恢复的工作。两种做法在内部可能很不一样,对下游的承诺却相同:属于别人的私有状态,不能被悄悄改写,也不能在返回时无故消失。
因此,Proxy-State 不是一张完整的路径清单。看到某个值回来,不能据此断言它经过了所有远端节点。看不到它出现在后一段请求里,也不能仅凭这一点判定前面的代理违反了协议。判断要落在正确的接口上:接收了什么,回复时交还了什么。
一个客户端,可能同时也是服务器
在典型的拨号接入场景中,RADIUS 客户端是网络接入服务器,而不是坐在终端前的用户。接入设备把认证请求交给一台服务器;这台服务器如果不能或不负责在本地处理,就把请求转给远端。对前一站,它是服务器;对后一站,它又承担客户端角色。
转发可以依据认证域等配置进行。同一台设备也可以为某些域转发,为另一些域直接提供服务。多个转发服务器能够串起来,不过协议特别提醒必须避免引入循环。Proxy-State 的存在本身不会自动算出正确路线,更不会把一条代理链变成无环网络。
这种安排在漫游中有实际用途:用户通过一家网络接入,认证判断却可能需要交给另一家机构。1999 年 6 月的信息类文档 RFC 2607 讨论了代理带来的密钥关系简化、能力调整、策略执行和记账处理。它同时直言,当时的安全假设并不适合直接扩展为大范围互联网部署。历史中的“有人已经这样做”,与“这样做已经足够安全”,不是同一个判断。
最后一个同类属性,不是报文最后一项
Proxy-State 并非 2000 年才出现。1997 年 4 月的 RFC 2138 已经定义了它;后来的 RFC 2865 更明确地说明了代理链中的处理规则。每个转发服务器可以加一项自己的 Proxy-State,但不能一次加上多项;新增的一项必须排在已有 Proxy-State 后面。
回复回来时,如果代理此前加过自己的那一项,就删除最后一个 Proxy-State,也就是属于自己的那一个,再继续向下游发送。前面的值要留给前面的代理。它没有必要理解别人的编码,就能知道这次该取走哪一项。
这里的“最后”是同类属性之间的相对位置,不是整个报文的绝对尾部。RFC 2865 要求保留同类型属性的顺序,却不要求不同类型之间固定排序,也不允许接收方强求同类型属性连续出现。两个 Proxy-State 中间可以夹着别的属性,最后一个 Proxy-State 后面也可以还有其他类型。
把这个过程比作逐层放入、逐层取出的标签,有助于理解归属。但如果把比喻画成报文尾部一段必须连续排列的栈,就比协议多规定了一件事。实现互通所需要的是相对顺序和正确的移除对象,不是某个开发者偏好的排版。
不解释,不等于看不见
RFC 2865 把 Proxy-State 的具体用途留给站点或应用实现。它要求代理把此前服务器添加的值当作不应由自己解释的字节,不能让那些私有内容左右自身的协议操作。共同约定停在属性边界,不延伸到每一家内部如何组织数据。
这种克制甚至关系到普通的字符串处理。Proxy-State 的值是二进制八位字节序列,不是遇到零字节就结束的文本。长度字段决定范围;其中的零字节也是数据。一个自认为在“整理格式”的中间件,如果截断、去空格、转换大小写或改写编码,可能正好破坏了只有原代理才懂的状态。
但“不透明”不是“加密”的同义词。它规定其他实现如何对待内容,并不承诺内容在链路上不可见,也不保证恶意代理无法复制或篡改它。私有编码可以避免无谓的语义耦合,不能代替安全机制。
当前 IANA 的 RADIUS 属性登记表 给 State、Class 和 Proxy-State 分别列出 24、25 和 33 号以及相应数据类型。登记解决的是大家怎样辨认属性,不是每个代理如何解释自己的值,更不是哪家网络有权准许某个用户接入。编号提供共同参照,不能替运行中的判断作证。
三种状态,三种去处
名称相近,容易把 State、Class 和 Proxy-State 当成同一类会话标识。它们的生命期却不同。State 可以由服务器放进 Access-Challenge,再由客户端原样带入后续 Access-Request,帮助延续认证过程。Class 可以出现在 Access-Accept 中;在支持记账的情况下,基础规范要求尽量把它原样带入记账请求。Proxy-State 则是转发代理要在回程取回的那份状态。
2007 年 12 月的 RFC 5080 又把认证过程的边界说得更清楚:新的或重新开始的认证请求,不能因为用户和端口仍相同,就继续套用上一轮的 State。用户身份相同,不代表仍是同一段交互。代理链也不能把三个不同用途的字段都简化成“这个用户的编号”。
记账还有另一层容易混淆的确认。2000 年 6 月的信息类文档 RFC 2866 规定,Accounting-Response 以收到并记录成功为前提,记录不了就不应按该规则确认。它不是单纯说网卡收到了包。但经过采用不同转发方式的代理后,也不能把某一站的确认扩大解释成所有机构都已经保存了同样的记录。责任落在哪一跳,仍要看具体安排。
拒绝接入,也要完成返回
远端服务器返回 Access-Accept、Access-Reject 或 Access-Challenge 时,都要把收到的 Proxy-State 按原顺序带回。状态的返回职责并不依赖用户最终获准接入。一个拒绝决定,也需要沿着正确的代理关系回到发起方。
与此同时,代理并非只会机械搬运。RFC 2865 允许它为执行本地策略而修改某些属性,但明确保护已经存在的 Proxy-State、State 和 Class。这是一条有范围的限制,不是整份报文绝对不可变。机构可以管理自己的接入政策,却不能以此把别人的私有状态当作随意重写的附属物。
原有交换中的认证也按相邻关系重新处理。代理核验上游响应,失败则丢弃;核验通过后取走自己的状态,恢复下游请求的 Identifier,并使用与下游共享的秘密重新计算响应认证值。整条链不是在传递一个从头到尾都没变过的认证信封。某一跳验证成功,不能单独证明所有前面的策略判断都未经改变。
后来的保护,没有抹掉中间人
2012 年 5 月的实验性 RFC 6614 为 RADIUS 引入 TLS 传输方案,但代理仍然需要处理消息。2025 年 4 月的实验性 RFC 9765 进一步定义 RADIUS/1.1,让相应的 TLS、DTLS 连接不再依赖原有的 MD5 和共享秘密报文机制。这里描述的是协议演变,不是建议今天继续部署旧的认证方法。
更新仍有边界。代理的前后两段连接可以独立选择相应传输安排,一段受到保护,不代表后面每段都相同;文档的发表也不是所有运行设备已经采用它的证据。逐跳安全的进步,不能被写成已经获得端到端保密和一致策略的结论。
Proxy-State 留下的经验比“代理需要状态”更精确。网络可以共同规定如何保全别人的信息,而不要求大家把私有信息变成共同语言。这样的共同层并不含糊:原样、顺序、归还、归属都很严格。它克制的地方,是没有把知道怎样转发,误当成有资格解释一切。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
