tcp三次握手之SYN_RCV

2020-09-02  本文已影响0人  欧阳_z

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 来设置。

上一篇 下一篇

猜你喜欢

热点阅读