Linux的连接与协议栈状态的查看方法

netstat查看连接状态分布

用netstat查看连接状态的分布(用yum安装:yum install -y net-tools):

$ netstat -nat|awk '{print awk $NF}'|sort|uniq -c|sort -n
      1 CLOSE_WAIT
      1 FIN_WAIT2
      1 State
      1 established)
      3 LAST_ACK
     30 FIN_WAIT1
    151 LISTEN
    280 TIME_WAIT
   1548 ESTABLISHED

查看本地临时端口占用情况

$ netstat -ntp |grep "11.0.110.0"  |awk '{print $4}' |sort |uniq |wc
  18171   18171  308907

查看本地源端口范围:

$ sysctl  net.ipv4.ip_local_port_range  
$ cat /proc/sys/net/ipv4/ip_local_port_range

设置本地源端口范围:

sysctl -w net.ipv4.ip_local_port_range="1024 64000"

临时端口不足时,Nginx会报下面的错误:

 (99: Cannot assign requested address) while connecting to upstream, client: 192.168.0.2, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.0.30"

netstat/ss查看单个连接状态

用netstat查看详细连接,-t查看tcp连接,-u查看udp连接,-p显示对应进程:

$ netstat -ntp
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 11.0.157.1:32888        11.0.157.6:8080         TIME_WAIT   -
tcp        0      0 11.0.157.1:45894        11.0.157.4:8080         TIME_WAIT   -
tcp        0      0 11.0.157.1:35826        11.0.157.9:8080         TIME_WAIT   -
tcp        0      0 11.0.157.1:57348        11.0.157.3:8080         TIME_WAIT   -
tcp        0      0 127.0.0.1:54728         127.0.0.1:10248         TIME_WAIT   -

ss命令是netstat的替代命令:

$ ss -ntp
State      Recv-Q Send-Q     Local Address:Port         Peer Address:Port
ESTAB      0      0           10.19.180.92:10250        10.19.14.106:38292     users:(("kubelet",pid=15242,fd=41))
ESTAB      0      0           10.19.180.92:35154        10.19.61.146:2379      users:(("flanneld",pid=1042,fd=10))
ESTAB      0      0           10.19.180.92:45380        10.19.162.39:6443      users:(("kube-proxy",pid=14013,fd=8))

当套接字是连接状态时,Established:

Recv-Q:套接字接收队列中还没有被应用程序读取的字节数。

Send-Q:套接字发送队列中还没有被远端主机确认的字节数。

当套接字是监听状态时,Listening,显示的半连接状态,即服务端收到客户端SYN,还没有完成三次握手的TCP连接:

Recv-Q:TCP协议栈中的半连接队列长度的当前值,syn backlog当前值。

Send-Q:TCP协议栈中的半连接队列长度的最大值,syn backlog最大值。

套接字是Established状态时,如果Recv-Q和Send-Q不为零,说明接收的数据无法被应用程序及时读取,以及应用的数据无法及时发送,是异常情况。

问题:如果是UDP协议呢?Rece-Q和Send-Q的含义是什么?同Established。

netstat查看协议栈状态

netstat -s打印出整个协议栈的状态,按照协议类型分开展示:

$ netstat -s
Ip:
    3635473208 total packets received
    2855004908 forwarded
    0 incoming packets discarded
    769088666 incoming packets delivered
    3701098707 requests sent out
    44 dropped because of missing route
Icmp:
    100236 ICMP messages received
    0 input ICMP message failed.
    ICMP input histogram:
        destination unreachable: 995
        redirects: 4
        echo requests: 99229
        echo replies: 8
    114887 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 15658
        echo replies: 99229
IcmpMsg:
        InType0: 8
        InType3: 995
        InType5: 4
        InType8: 99229
        OutType0: 99229
        OutType3: 15658
Tcp:
    3716853 active connections openings
    1228040 passive connection openings
    570 failed connection attempts
    610 connection resets received
    17 connections established
    33850465 segments received
    43122661 segments send out
    15575 segments retransmited
    4 bad segments received.
    1018 resets sent
Udp:
    735086502 packets received
    6 packets to unknown port received.
    33475 packet receive errors
    797838180 packets sent
    33475 receive buffer errors
    0 send buffer errors
UdpLite:
TcpExt:
    28250 invalid SYN cookies received
    3961 resets received for embryonic SYN_RECV sockets
    21371 packets pruned from receive queue because of socket buffer overrun
    72874448 TCP sockets finished time wait in fast timer
    1396 packets rejects in established connections because of timestamp
    6946924 delayed acks sent
    128318 delayed acks further delayed because of locked socket
    Quick ack mode was activated 49028 times
    1292037 packets directly queued to recvmsg prequeue.
    33405 bytes directly in process context from backlog
    566548477 bytes directly received in process context from prequeue
    420652665 packet headers predicted
    1255272 packets header predicted and directly queued to user
    285092354 acknowledgments not containing data payload received
...

限制半开连接

半开连接最大数量:

sysctl net.ipv4.tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 256

限制半开连接建立速度:

# 限制 syn 并发数为每秒 1 次
$ iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT

# 限制单个 IP 在 60 秒新建立的连接数为 10
$ iptables -I INPUT -p tcp --dport 80 --syn -m recent --name SYN_FLOOD --update --seconds 60 --hitcount 10 -j REJECT

启动synccookie:

sysctl -w net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syncookies = 1

参考