用 netstat 或者 ss ,来查看套接字、网络栈、网络接口以及路由表的信息,个人更推荐,使用 ss 来查询网络的连接信息,因为它比 netstat 提供了更好的性能(速度更快)。
使用示例:
# head -n 3 表示只显示前面3行 # -l 表示只显示监听套接字 # -n 表示显示数字地址和端口(而不是名字) # -p 表示显示进程信息 $ netstat -nlp | head -n 3
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:24007 0.0.0.0:* LISTEN 14447/glusterd
# -l 表示只显示监听套接字 # -t 表示只显示 TCP 套接字 # -n 表示显示数字地址和端口(而不是名字) # -p 表示显示进程信息 $ ss -ltnp | head -n 3
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 10 *:24007 *:* users:(("glusterd",pid=14447,fd=10))
LISTEN 0 128 127.0.0.1:10248 *:* users:(("kubelet",pid=9901,fd=27))
关于Recv-Q 和 Send-Q
一、当套接字处于连接状态(Established)时
Recv-Q 表示套接字缓冲还没有被应用程序取走的字节数(即接收队列长度)。而 Send-Q 表示还没有被远端主机确认的字节数(即发送队列长度)。
二、当套接字处于监听状态(Listening)时
Recv-Q 表示当前全连接队列使用的长度。而 Send-Q 表示全连接队列的最大长度。
所谓全连接,是指服务器收到了客户端的 ACK,完成了 TCP 三次握手,然后就会把这个连接挪到全连接队列中。这些全连接中的套接字,还需要被 accept() 系统调用取走,服务器才可以开始真正处理客户端的请求。
与全连接队列相对应的,还有一个半连接队列。所谓半连接是指还没有完成 TCP 三次握手的连接,连接只进行了一半。服务器收到了客户端的 SYN 包后,就会把这个连接放到半连接队列中,然后再向客户端发送 SYN+ACK 包。
协议栈统计信息
$ netstat -s ... Tcp: 3244906 active connection openings 23143 passive connection openings 115732 failed connection attempts 2964 connection resets received 1 connections established 13025010 segments received 17606946 segments sent out 44438 segments retransmitted 42 bad segments received 5315 resets sent InCsumErrors: 42 ... $ ss -s Total: 186 (kernel 1446) TCP: 4 (estab 1, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0 Transport Total IP IPv6 * 1446 - - RAW 2 1 1 UDP 2 2 0 TCP 4 3 1 ...
这些协议栈的统计信息都很直观。ss 只显示已经连接、关闭、孤儿套接字等简要统计,而 netstat 则提供的是更详细的网络协议栈信息。
全/半连接队列溢出的次数查看
netstat -s | egrep "listen|LISTEN" 8111 times the listen queue of a socket overflowed
10771 SYNs to LISTEN sockets dropped
第一行表示全连接队列的溢出,第二行表示半连接队列溢出,注意这是一个累加的结果,看的是增量而不是总量
上面的命令每隔几秒执行一次如果数字在增加说明队列满了已经溢出
关于全连接队列和半连接队列
半连接队列 syns queue
全连接队列 accept queue
三次握手中,在第一步server收到client的syn后,把这个连接信息放到半连接队列中,同时回复syn+ack给client(第二步);
syn flood 攻击就是针对半连接队列的,攻击方不停建立连接但是只做第一步,第二部收到ack+syn后直接丢弃导致server上的半连接队列满了无法正常接受其他正常请求。
第三步的时候server收到client的ack,如果这时全连接队列没满,那么从半连接队列拿出这个连接的信息放入到全连接队列中,否则按tcp_abort_on_overflow指示的执行。