美文网首页
tcp三次握手之SYN_RCV

tcp三次握手之SYN_RCV

作者: 欧阳_z | 来源:发表于2020-09-02 15:59 被阅读0次

    1、正常情况下当服务器收到 SYN 后,会立刻回复 SYN+ACK ,出现新连接,需要建立一个半连接的队列来维护未完成的握手信息。如果队列溢出则不能接受新的连接,比如 SYN 泛洪攻击。

    (1)tcp_max_syn_backlog
    半连接队列大小由参数 tcp_max_syn_backlog 决定:

    $ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
    128
    

    (2)tcp_syncookies
    队列满了之后,不一定会丢弃连接,可以打开 tcp_syncookies 功能:
    0 表示关闭,
    2 表示无条件使用,
    1 则表示仅当 SYN 半连接队列放不下时再用它。
    由于 cookie 占用序列号的空间,导致TCP可选功能失效,所以应该设置为 1

    $ cat /proc/sys/net/ipv4/tcp_syncookies 
    1
    

    (3)实验:模拟 SYN Flood 攻击

    (A)客户端丢弃掉第三次握手的ACK的报文,这样服务端收不到ACK就只能处于半连接队列:

    sudo iptables -A OUTPUT -p tcp -d 192.168.136.131 -m tcp --tcp-flags ACK ACK -j DROP
    

    (B)在服务端把半连接队列设置小一些,
    (C)关闭 tcp_syncookies

    $ sudo sh -c "echo 2 > /proc/sys/net/ipv4/tcp_max_syn_backlog"
    $ sudo sh -c "echo 0 > /proc/sys/net/ipv4/tcp_syncookies"
    

    (D)在客户端循环发送多个请求:

    $ for i in {1..9}; do ssh 192.168.136.131 & done
    

    (E)这样就可以在服务端观察半连接队列溢出情况了:

    $ netstat -s | grep "SYNs to LISTEN"
        36 SYNs to LISTEN sockets dropped
    

    (4)tcp_synack_retries
    服务端发送 SYN+ACK 后,如果没有收到 ACK,就会一直重发 SYN+ACK。重发次数由 tcp_synack_retries 决定:

    $ cat /proc/sys/net/ipv4/tcp_synack_retries
    5
    

    耗时:默认重发 5 次,总耗时是 1+2+4+8+16+32=63 秒。

    (5)tcp_abort_on_overflow
    服务器收到 ACK 后,会把连接从 半连接队列移出,移入 accept 队列,等待进程调用 accept 函数把连接取出。如果进程不能及时调用 accept 函数,就会造成 accept 队列溢出,连接被丢弃。

    如果设置了 tcp_abort_on_overflow 为 1,会向客户端发送 RST 通知客户端,默认是 0,不通知客户,等客户重发请求,如果那时 accept 队列没有满,则可以建立连接。

    $ cat /proc/sys/net/ipv4/tcp_abort_on_overflow 
    0
    $ cat /proc/sys/net/core/somaxconn
    128
    

    设置 accept 队列的长度:可以通过 上面的somaxconn,也可以通过 int listen(int sockfd, int backlog); 的第二个参数 backlog 来设置。

    相关文章

      网友评论

          本文标题:tcp三次握手之SYN_RCV

          本文链接:https://www.haomeiwen.com/subject/scjwsktx.html