连接建立阶段是整个会话中信息量最大的部分:握手往返次数、首包长度、参数呈现顺序都会留下特征,而这些特征与数据内容无关,纯粹由协议设计决定。伪装做的是在可观察层面做一致化处理。
数据开始传输之前,连接必须先建立。这个过程必须暴露一些信息:告诉对端我要建立连接、协商用什么参数、确认双方状态。这些信息是协议运转的必要条件,无法省略。
问题在于,不同协议在建立阶段暴露的信息形态不同。自定义协议往往有独特的往返次数与首包长度,这些特征在数据加密之后依然存在——因为它们属于协议元数据层面,加密保护的是载荷,不是握手结构本身。
因此伪装的目标很明确:让握手过程在可观察特征上与常规加密会话保持一致,使基于静态特征的匹配无法把这类连接单独挑出来。这与加密是两件互补的事——加密让内容不可读,伪装让结构不显眼。
握手往返一致化
一次连接建立需要用几个往返,是由协议设计决定的固定值。观察者不需要解密任何内容,仅通过统计连接建立阶段的往返次数,就可以对协议类型做出分类。这是成本最低、也最容易被大规模部署的识别方式。
把自定义协议的握手往返次数对齐到常规加密会话的常见取值。实现上不是简单地减少往返,因为减少往返会破坏协议自身的协商逻辑;而是在保持协商完整的前提下,把多次往返合并到与目标一致的节奏上。
合并往返会略微增加首包到首个应用数据之间的时间。这个增量在建立连接时发生一次,对长时间会话影响可忽略,但对频繁重建连接的场景是可观测的。客户端在检测到连接重建频繁时,会调整策略以减少合并带来的额外时延。
首包长度与参数呈现顺序处理
连接的第一个数据包携带了协商所需的信息,其长度由参数数量与编码方式决定。不同协议的首包长度往往集中在不同的区间,形成可区分的特征。此外,参数在首包中的呈现顺序也可能带有协议指纹。
对齐首包长度到常规加密会话的常见区间,并对参数呈现顺序做规范化处理。这两项都不影响协商结果的正确性,只是改变了它们在报文中的组织形式。
首包处理与流量整形存在重叠区:整形负责会话中所有包的长度分布,而伪装只管首包。两者的分工是明确的——首包按伪装的目标形态处理,后续包交由整形引擎按分布式策略处理,避免同一数据包被两个环节重复调整。
伪装能做到什么,不能做到什么
识别与伪装始终处于相互演进的状态:一方处理掉某类特征,另一方就会转向其他可用的观察维度。宣称绝对不可识别既不可验证,也会让用户对风险产生错误预期。更负责的表述是:降低被简单静态特征匹配命中的概率,并持续跟进调整。