通过查看内核源代码,我试图对Linux内核IPSec网络有更多的了解。我从概念上理解,IPSec使用序列号和重放窗口来防止重放攻击,即,如果接收方接收到的数据包的序列号不在重放窗口内,或者它以前已经接收过,则它会丢弃该数据包并递增重放计数器。
我试图将其与定义如下的结构xfrm_replay_state_esn相关联:
struct xfrm_replay_state_esn {
unsigned int bmp_len;
__u32 oseq;
__u32 seq;
__u32 oseq_hi;
__u32 seq_hi;
__u32 replay_window;
__u32 bmp[0];
};我试着搜索文档,但它很少,而且我也找不到具有各种功能和结构的人,所以我不明白各个字段与什么相关。
发布于 2020-08-09 05:53:59
Linux 是一个针对内核的IPSec实现。名称XFRM代表根据IPSec协议的IP分组的转换的“转换”。
以下RFC与IPSec相关:
IPSec协议允许32位或64位大小的序列号。64位序列号被称为扩展序列号(ESN)。
在AH和ESP的RFC中定义了防重放机制。该机制保持输入分组的可接受序列号的窗口。该窗口从迄今为止接收到的最高序列号向后延伸,定义了可接受序列号的下限。当接收到低于该界限的序列号时,它将被拒绝。当接收到比当前最高序列号更高的序列号时,该窗口被前移。当在窗口内接收序列号时,该机制将在核对表中标记该序列号,以确保窗口中的每个序列号仅被接收一次。如果序列号已被标记,则拒绝该序列号。
该检查表可以实现为位图,其中窗口中的每个序列号由单个比特表示,0表示尚未接收到该序列号,1表示已经接收到该序列号。
根据这些信息,xfrm_replay_state_esn结构中字段的含义可以如下所示。该结构保存具有扩展序列号(64位)的防重放机制的状态:
seq和seq_hi表示。每一个都是一个32位的整数,所以它们加在一起可以表示一个64位的数字,其中seq表示低32位,seq_hi表示higher 32位。将64位值分成两个32位值而不是将其表示为单个64位变量的原因是,IPSec协议要求进行优化,其中仅在包中包括序列号的较低32位。因此,将低32位作为结构中的单独变量更方便,这样就可以直接访问它,而不需要求助于bit-operations.oseq和oseq_hi中跟踪o正在使用的包的序列号计数器。如前所述,64位数字由两个32位变量表示。replay_window表示。可接受的最小序列号(如果由seq和seq_hi表示的序列号减去replay_window加1表示)。bmp表示。它被定义为一个零大小的数组,但当结构的内存被分配时,额外的内存被保留在结构之后,然后可以通过bmp[i]访问(当然,这只是*(bmp+i)的语法糖)。位图的大小保存在bmp_len中。它当然与窗口大小有关,即窗口大小除以8*sizeof(u32),向上舍入。我推测它是显式存储的,以避免频繁地重新计算此值。https://stackoverflow.com/questions/44938767
复制相似问题