网络状态检测的利器 - ss命令

416 阅读8分钟

这是我参与11月更文挑战的第2天

ss命令,它是 socket statistic的缩写,用于统计Linux系统中socket连接相关的信息,和其他的工具相比,ss命令可以显示更多关于 TCP和状态相关的信息

语法

ss [ OPTIONS ]

在Linux系统中,默认已经安装了 ss 命令,下面介绍该命令常用的一些功能

ss 和 netstat 命令

netstat 命令和 ss 命令比较类似,主要功能也是统计系统中socket相关信息,和 netstat相比,ss 命令在跟踪TCP连接和套接字方面速度更快,功能更强大,下面是 ss 和 netstat 统计速度的对比

[cgyx@cghost35 ~]$ time ss -a | wc -l
439

real    0m0.014s
user    0m0.004s
sys     0m0.010s

[cgyx@cghost35 ~]$ time netstat -a | wc -l
366

real    0m0.029s
user    0m0.005s
sys     0m0.008s

从上面例子可以看出,ss 统计439条socket信息花费了0.014s, netstat 统计366条socket信息花费了0.029s,ss 统计信息的速度更快,所以实际使用中一般都是用 ss 替代 netstat

显示套接字摘要

列出当前已经连接、关闭、等待的TCP连接,当系统中已经存在大量的套接字连接的时候,通过查看套接字摘要信息可以快速了解系统中套接字的总体情况

[root@ecs-centos-7 ~]# ss -s
Total: 185 (kernel 264)
TCP:   7 (estab 2, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6
*         264       -         -         
RAW       0         0         0        
UDP       7         4         3        
TCP       7         4         3        
INET      14        8         6        
FRAG      0         0         0 

显示网络连接

当不使用任何选项时,ss将显示已建立连接的处于非监听状态的套接字列表,由于原始结果太长,下面的例子只截取了一部分

[root@ecs-centos-7 ~]# ss
Netid  State      Recv-Q Send-Q                 Local Address:Port                                  Peer Address:Port 
u_str ESTAB      0      0                         /run/dbus/system_bus_socket 12050                 * 11962
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.56:ssm-cssps            
tcp    ESTAB      0      4200                     192.168.0.9:ssh                                   27.38.240.56:rsmtp                
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.56:pearldoc-xact   

上面例子中列说明:

  • Netid

socket类型,在上面的例子中,有 TCP、u_str(unix流)等套接字

  • State

套接字处于什么状态,下面是TCP套接字的所有状态及说明, 实际上就是TCP的三次握手和四次挥手的所有状态

LISTEN:  服务端侦听套接字等待客户端的连接

SYN-SENT: 客户端已发送套接字连接请求报文,等待连接被服务器接收

SYN-RECEIVED: 服务器端接收连接请求报文后,等待客户端的确认连接的回复报文

ESTABLISHED: 服务端和客户端之间成功建立了一条有效的连接,可以互相传输数据

FIN-WAIT-1: 服务器或客户端调用close函数主动向对方发出终止连接的请求报文,同时等待对方确认终止连接的回复报文

FIN-WAIT-2: 主动关闭连接端收到对方确认终止连接的回复报文,同时等待对方连接终止的请求报文,这时的状态是TCP连接的半关闭状态,可以接受数据,但是不能发送数据

CLOSE-WAIT: 被动关闭端收到主动关闭端终止连接的请求报文后,向主动关闭端发送确认终止连接的回复报文,同时被动关闭端等待本地用户终止连接,这时被动关闭端的状态是TCP连接的半关闭状态,可以发送数据,但是不能接收数据

CLOSING: 服务器和客户端同时向对方发送终止连接(调用close函数)请求报文,并且双方都是在收到对方发送的终止连接回复报文之前收到了对方的发送的终止连接请求报文,这个时候双方都进入了CLOSING状态,进入CLOSING状态之后,只要收到了对方对自己终止连接的回复报文,就会进入TIME-WAIT状态,所以CLOSING状态的持续时间会特别短,一般很难捕获到

LAST-ACK: 被动关闭端发送完全部数据之后,向主动关闭端发送终止连接的请求报文,等待主动关闭端发送终止连接的回复报文

TIME-WAIT: 主动关闭端收到被动关闭端终止连接的请求报文后,给被动关闭端发送终止连接的回复报文,等待足够时间以确保被动关闭端收到了主动关闭段发送的终止连接的回复报文

CLOSED: 完全没有连接,套接字连接已经终止了
  • Recv-Q

在 ESTAB 状态下,表示内核中还有多少字节的数据没有被上层应用读取,如果这里数值很大,应用程序可能发生了阻塞

  • Send-Q

在 ESTAB 状态下,表示内核发送队列中还有多少字节的数据没有收到确认的ACK,如果这个数值很大,表明接收端的接收以及处理需要加强

  • Local Address:Port

本地地址和端口

  • Peer Address:Port

远程地址和端口

显示侦听状态的套接字

使用 -l 选项可以列出所有处于侦听(LISTEN)状态的套接字

[root@ecs-centos-7 ~]# ss -l
Netid  State    Recv-Q Send-Q   Local Address:Port  Peer Address:Port  
tcp    LISTEN     0      100    127.0.0.1:smtp          *:*                    
tcp    LISTEN     0      128    *:ssh                   *:*                    
tcp    LISTEN     0      100    [::1]:smtp              [::]:*                    
tcp    LISTEN     0      254    [::]:mysql              [::]:*                    
tcp    LISTEN     0      128    [::]:ssh                [::]:*  

显示所有的套接字

使用 -a选项可以列出所有的状态的套接字,由于所有的套接字列表太多,下面的例子中只列出了少许的数据

[root@ecs-centos-7 ~]# ss -a
Netid  State      Recv-Q Send-Q         Local Address:Port  Peer Address:Port
tcp    LISTEN     0      100              127.0.0.1:smtp        *:*                    
tcp    LISTEN     0      128               *:ssh                *:*                    
tcp    ESTAB      0      16644            192.168.0.9:ssh      27.38.240.99:21669  
tcp    ESTAB      0      0                192.168.0.9:ssh    27.38.240.103:kyoceranetdev        
tcp    LISTEN     0      100              [::1]:smtp            [::]:*                    
tcp    LISTEN     0      254              [::]:mysql            [::]:*                    
tcp    LISTEN     0      128              [::]:ssh              [::]:*  

根据协议类型显示

可以通过 TCP、UDP、Unix、Raw、IPV4、IPV6 这些协议类型显示套接字,下面以常用的TCP/UDP/IPV4协议举例说明

ss -ua : 显示Unix套接字
ss -wa : 显示Raw套接字
ss -6a : 显示IPV6套接字
  • TCP套接字

使用 -t 选项(TCP), 让结果只列出TCP套接字

[root@ecs-centos-7 ~]# ss -a -t
State      Recv-Q Send-Q                    Local Address:Port                                     Peer Address:Port                
LISTEN     0      100                           127.0.0.1:smtp                                                *:*                    
LISTEN     0      128                                   *:ssh                                                 *:*                    
ESTAB      0      52                          192.168.0.9:ssh                                      27.38.240.99:21787                
ESTAB      0      0                           192.168.0.9:ssh                                      27.38.240.99:21669                
ESTAB      0      0                           192.168.0.9:ssh                                     27.38.240.103:kyoceranetdev        
LISTEN     0      100                               [::1]:smtp                                             [::]:*                    
LISTEN     0      254                                [::]:mysql                                            [::]:*                    
LISTEN     0      128                                [::]:ssh                                              [::]:*
  • UDP套接字

使用 -u 选项(UCP), 让结果只列出UCP套接字

[root@ecs-centos-7 ~]# ss -a -u
State      Recv-Q Send-Q                    Local Address:Port                                     Peer Address:Port                
UNCONN     0      0                                     *:bootpc                                              *:*                    
UNCONN     0      0                           192.168.0.9:ntp                                                 *:*                    
UNCONN     0      0                             127.0.0.1:ntp                                                 *:*                    
UNCONN     0      0                                     *:ntp                                                 *:*                    
UNCONN     0      0      [fe80::f816:3eff:fee0:4fb8]%eth0:ntp                                              [::]:*                    
UNCONN     0      0                                 [::1]:ntp                                              [::]:*                    
UNCONN     0      0                                  [::]:ntp                                              [::]:*    
  • ipv4 套接字

使用 -4 选项(IPV4), 让结果只列出IPV4的套接字

[root@ecs-centos-7 ~]# ss -4a
Netid  State      Recv-Q Send-Q                 Local Address:Port                                  Peer Address:Port                
udp    UNCONN     0      0                                  *:bootpc                                           *:*                    
udp    UNCONN     0      0                        192.168.0.9:ntp                                              *:*                    
udp    UNCONN     0      0                          127.0.0.1:ntp                                              *:*                    
udp    UNCONN     0      0                                  *:ntp                                              *:*                    
tcp    LISTEN     0      100                        127.0.0.1:smtp                                             *:*                    
tcp    LISTEN     0      128                                *:ssh                                              *:*                    
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.99:21787  

识别进程名字

有时我们查询到指定的套接字了,但是无法知道套接字是哪个应用程序在使用,这时可以使用 -p 选项

[root@ecs-centos-7 ~]# ss -a -t -p
State      Recv-Q Send-Q                    Local Address:Port                                     Peer Address:Port 
LISTEN     0      254                                [::]:mysql                                            [::]:* 

上面的例子中,从Local Address:Port 列可以知道,这个套接字时mysql在使用,如果没有加 -p选项的话,这里显示的时mysql的端口号3306

通过端口和进程名筛选

有时候我们启动应用程序的时候,发现端口已经被占用了,此时先要查找出占用目标端口的应用程序,然后关闭它,再启动我们自己的应用程序

  • 通过端口筛选
[root@ecs-centos-7 ~]# ss -ap sport eq 3306
Netid  State      Recv-Q Send-Q                 Local Address:Port                                  Peer Address:Port                
tcp    LISTEN     0      254                             [::]:mysql                                         [::]:*   

上面的例子中,sport 表示源,对应的 dport 表示目标,命令查找端口3306是被哪个进程使用了,最终发现3306是mysql在使用

通过端口筛选还支持小于、大于、小于等于、大于等于、不等于,具体的说明如下:

ss -ap sport le 3306 : 筛选出源端口小于等于3306的套接字
ss -ap sport lt 3306 :筛选出源端口小于3306的套接字
ss -ap sport ge 3306 : 筛选出源端口大于等于3306的套接字
ss -ap sport gt 3306 : 筛选出源端口大于3306的套接字
ss -ap sport ne 3306 : 筛选出源端口不等于3306的套接字
  • 通过进程名筛选
[root@ecs-centos-7 ~]# ss -an sport eq mysql
Netid  State      Recv-Q Send-Q                 Local Address:Port                                  Peer Address:Port                
tcp    LISTEN     0      254                             [::]:3306                                         [::]:*   

上面的例子中筛选出进程名为mysql的套接字, 执行的命令中 -n选项是不解析服务名字,加了此选项就显示成端口了,不会解析成服务名称了

通过IP地址筛选

  • 通过目标地址筛选

下面例子是筛选出目标IP地址为27.38.240.99的套接字,dst 是目标地址

[root@ecs-centos-7 ~]# ss -a dst 27.38.240.99
Netid  State      Recv-Q Send-Q                 Local Address:Port                                  Peer Address:Port                
tcp    ESTAB      0      52                       192.168.0.9:ssh                                   27.38.240.99:21907                
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.99:21787                
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.99:23260                
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.99:22810                
  • 通过源地址筛选

下面例子是筛选出源IP地址为192.168.0.99的套接字,src 是源地址

[root@ecs-centos-7 ~]# ss -a src 192.168.0.9
Netid  State      Recv-Q Send-Q                 Local Address:Port                                  Peer Address:Port                
udp    UNCONN     0      0                        192.168.0.9:ntp                                              *:*                    
tcp    ESTAB      0      52                       192.168.0.9:ssh                                   27.38.240.99:21907                
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.99:21787                
tcp    ESTAB      0      0                        192.168.0.9:ssh                                   27.38.240.99:23260