3.6 SYN Cookie

TCP SYN Cookie是一种防御SYN Flood攻击的策略。当服务器接收到SYN请求时,不立即建立连接信息,而是生成cookie作为序列号,并在SYN|ACK中传递。客户端响应ACK后,服务器通过ACK中的信息重建连接。攻击者必须完成完整三次握手,增加了攻击成本。然而,若客户端未开启时间戳,某些选项可能无法使用。
摘要由CSDN通过智能技术生成
在三次握手过程中,server端的TCP收到SYN请求后会建立一个request_sock保存在syn_table中。如果有恶意攻击者大量发送IP地址或端口不同的SYN包,则server端TCP的syn_table很快会被占满,而普通用户对server的正常访问会因为syn_table已满而被拒绝。这就是SYN Flood攻击。SYN Cookie技术就是为了应对SYN Flood攻击而产生的,它的原理是,在TCP服务器收到SYN包并返回SYN|ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值,在发送SYN|ACK时将这个cookie作为其序列号。在收到ACK包时,TCP服务器根据确认号得到之前的cookie,再根据这个cookie值检查这个ACK包的合法性。如果合法,再分配sock保存未来的TCP连接的信息。
    如果要Linux内核支持SYN Cookie功能,必须开启CONFIG_SYN_COOKIES编译选项。下面分析一下TCP对SYN Cookie功能的实现。

    TCP服务器在接收到SYN时,会调用tcp_v4_conn_request函数:

 1465 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1466 {
1467     struct tcp_options_received tmp_opt;
1468     struct request_sock *req;
1469     struct inet_request_sock *ireq;
1470     struct tcp_sock *tp = tcp_sk(sk);
1471     struct dst_entry *dst = NULL;  
1472     __be32 saddr = ip_hdr(skb)->saddr;
1473     __be32 daddr = ip_hdr(skb)->daddr;
1474     __u32 isn = TCP_SKB_CB(skb)->when;
1475     bool want_cookie = false;
1476     struct flowi4 fl4;   
1477     struct tcp_fastopen_cookie foc = { .len = -1 };
1478     struct tcp_fastopen_cookie valid_foc = { .len = -1 };
1479     struct sk_buff *skb_synack;    
1480     int do_fastopen;     
...
1486     /* TW buckets are converted to open requests without
1487      * limitations, they conserve resources and peer is
1488      * evidently real one.
1489      */
1490     if (inet_csk_reqsk_queue_is_full(sk) && !isn) {//如果存储request sock的accept队列已满且SYN包没有命中TIME_WAIT socekt
1491         want_cookie = tcp_syn_flood_action(sk, skb, "TCP");//如果用户使用sysctl_tcp_syncookies开启了syn cookie功能,则want_cookie为1
1492         if (!want_cookie)//如果使用syn cookie机制,不需要保存request sock,所以不需要受到accept queue的限制
1493             goto drop;   
1494     }
...
1506     req = inet_reqsk_alloc(&tcp_request_sock_ops);//申请一个request sock,但不会保存到accept queue中
1507     if (!req)
1508         goto drop;
...
1517     tcp_parse_options(skb, &tmp_opt, 0, want_cookie ? NULL : &foc);//如果使用syn cookie,则不能使用fast open功能,因为无处存储相关信息
1518                 
1519     if (want_cookie && !tmp_opt.saw_tstamp)//使用syn cookie时如果对端没有开启时间戳选项
1520         tcp_clear_options(&tmp_opt);  //则本端不支持SACK和窗口扩大选项,因为无处存储相关信息
...
1523     tcp_openreq_init(req, &tmp_opt, skb);
...
1537     if (want_cookie) {//使用syn cookie的话,
1538         isn = cookie_v4_init_sequence(sk, skb, &req->mss);//生成syn cookie并以之作为SYN|ACK的起始序列号
1539         req->cookie_ts = tmp_opt.tstamp_ok;
1540     } else if (!isn) {
...
1578     tcp_rsk(req)->snt_isn = isn;   
...
1598     skb_synack = tcp_make_synack(sk, dst, req,
1599         fastopen_cookie_present(&valid_foc) ? &valid_foc : NULL); 
...
1607     if (likely(!do_fastopen)) {
1608         int err;
1609         err = ip_build_and_send_pkt(skb_synack, sk, ireq->loc_addr,
1610              ireq->rmt_addr, ireq->opt);
1611         err = net_xmit_eval(err);
1612         if (err || want_cookie)//发送完SYN|ACK后,丢弃此request sock
1613             goto drop_and_free;
...
1629 drop_and_free:
1630     reqsk_free(req);
  1490:只有accpet队列满时才会启用syn cookie
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值