我们经常使用的netstat其实早已弃用,取而代之是来自iproute iproute2中的ss(socket statistics)命令,它能比netstat显示更多信息而且更快. netstat命令 读取各种/proc 文件收集信息. 然而当有很多连接时它的性能下降很快,使得变的很慢.
ss命令能够从内核空间直接得到信息,ss命令选项与netstat非常相似,容易替代.
root@10.1.1.43:~# ss -help
Usage: ss [ OPTIONS ]
ss [ OPTIONS ] [ FILTER ]
-h, --help this message 帮助
-V, --version output version information 版本信息
-n, --numeric don't resolve service names 不解析服务名称
-r, --resolve resolve host names 解析主机名
-a, --all display all sockets 显示所有套接字sockets
-l, --listening display listening sockets 显示监听状态的套接字sockets
-o, --options show timer information 显示计时器信息
-e, --extended show detailed socket information 显示详细的套接字信息
-m, --memory show socket memory usage 显示套接字内存使用情况
-p, --processes show process using socket 显示使用套接字的进程
-i, --info show internal TCP information 显示TCP内部信息
-s, --summary show socket usage summary 显示套接字使用概况
-4, --ipv4 display only IP version 4 sockets 显示ipv4的套接字
-6, --ipv6 display only IP version 6 sockets 显示ipv6的套接字
-0, --packet display PACKET sockets 显示PACKET套接字
-t, --tcp display only TCP sockets 仅显示TCP套接字
-u, --udp display only UDP sockets 仅显示UDP套接字
-d, --dccp display only DCCP sockets 仅显示DCCP套接字
-w, --raw display only RAW sockets 仅显示RAW套接字
-x, --unix display only Unix domain sockets 仅显示Unix套接字
-f, --family=FAMILY display sockets of type FAMILY 显示 FAMILY类型的套接字(sockets),FAMILY可选,支持 unix, inet, inet6, link, netlink
-A, --query=QUERY, --socket=QUERY
QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]
-D, --diag=FILE Dump raw information about TCP sockets to FILE 将原始TCP套接字信息转储到文件
-F, --filter=FILE read filter information from FILE 从文件中都去过滤器信息
FILTER := [ state TCP-STATE ] [ EXPRESSION ]
以下是一些关于ss命令检查网络连接和套接字状态
1.列出所有连接
该输出包括所有tcp,udp,unix套接字连接细节.
root@10.1.1.176:~# ss | less
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46622
ESTAB 0 0 10.1.1.176:46618 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46619 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46619
ESTAB 0 52 10.1.1.176:22000 10.1.6.56:51512
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46618
ESTAB 0 0 10.1.1.176:46622 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46620 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46620
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
2.输出过滤tcp,udp 或者unix 连接
默认'-t' 参数仅报告建立连接established和已连接connected.它不报告tcp套接字监听listening,与'-t'一起使用'-a',一次显示所有.
root@10.1.1.176:~# ss -t
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46622
ESTAB 0 0 10.1.1.176:46618 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46619 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46619
ESTAB 0 0 10.1.1.176:22000 10.1.6.56:51512
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46618
ESTAB 0 0 10.1.1.176:46622 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46620 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46620
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
root@10.1.1.176:~# ss -A tcp #意义同上
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46622
ESTAB 0 0 10.1.1.176:46618 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46619 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46619
ESTAB 0 0 10.1.1.176:22000 10.1.6.56:51512
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46618
ESTAB 0 0 10.1.1.176:46622 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46620 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46620
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
3.不解析主机名
为了输出更快,使用'n'参数可以避免解析ip到主机名
root@10.1.1.176:~# ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46622
ESTAB 0 0 10.1.1.176:46618 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46619 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46619
ESTAB 0 0 10.1.1.176:22000 10.1.6.56:51512
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46618
ESTAB 0 0 10.1.1.176:46622 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46620 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46620
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
4.只显示监听套接字
root@10.1.1.176:~# ss -ltn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 10.1.1.176:8080 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 *:22000 *:*
LISTEN 0 10 *:8000 *:*
LISTEN 0 50 10.1.1.176:3306 *:*
LISTEN 0 50 10.1.1.176:3307 *:*
LISTEN 0 128 10.1.1.176:6379 *:*
5.输出进程名和pid
root@10.1.1.176:~# ss -ltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 10.1.1.176:http-alt *:* users:(("ruby",13744,13),("ruby",13704,13),("ruby",13676,13))
LISTEN 0 128 *:http *:* users:(("nginx",11650,8),("nginx",11649,8),("nginx",11648,8),("nginx",11647,8),("nginx",11646,8))
LISTEN 0 128 *:22000 *:* users:(("sshd",1885,3))
LISTEN 0 10 *:8000 *:* users:(("python",16496,3))
LISTEN 0 50 10.1.1.176:mysql *:* users:(("mysqld",13394,10))
LISTEN 0 50 10.1.1.176:3307 *:* users:(("mysqld",17257,10))
LISTEN 0 128 10.1.1.176:6379 *:* users:(("redis-server",12198,4))
6.输出汇总统计
root@10.1.1.176:~# ss -s
Total: 66 (kernel 67)
TCP: 17 (estab 10, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 11
Transport Total IP IPv6
* 67 - -
RAW 0 0 0
UDP 0 0 0
TCP 17 17 0
INET 17 17 0
FRAG 0 0 0
7.显示时间信息
使用'-o'选项.每个连接时间信息将被显示.
root@10.1.1.176:~# ss -tn -o
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46622
ESTAB 0 0 10.1.1.176:46618 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46619 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46619
ESTAB 0 300 10.1.1.176:22000 10.1.6.56:51512 timer:(on,372ms,0)
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46618
ESTAB 0 0 10.1.1.176:46622 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46620 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46620
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
8. 显示ipv4 或 ipv6 套接字连接
只显示ipv4套接字连接使用'-f inet' 或者'-4'
root@10.1.1.176:~# ss -tl -f inet
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 10.1.1.176:http-alt *:*
LISTEN 0 128 *:http *:*
LISTEN 0 128 *:22000 *:*
LISTEN 0 10 *:8000 *:*
LISTEN 0 50 10.1.1.176:mysql *:*
LISTEN 0 50 10.1.1.176:3307 *:*
LISTEN 0 128 10.1.1.176:6379 *:*
只显示ipv4套接字连接使用'-f inet6
' 或者'-6'
root@10.1.1.176:~# ss -tl6
State Recv-Q Send-Q Local Address:Port Peer Address:Port
9.过滤tcp连接状态
ss命令支持过滤只显示特殊的连接.
$ ss [ OPTIONS ] [ STATE-FILTER ] [ ADDRESS-FILTER ]
显示ipv4 tcp 套接字 连接状态
root@10.1.1.176:~# ss -t4 state established
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 10.1.1.176:6379 10.1.1.176:46622
0 0 10.1.1.176:46618 10.1.1.176:6379
0 0 10.1.1.176:46619 10.1.1.176:6379
0 0 10.1.1.176:6379 10.1.1.176:46619
0 0 10.1.1.176:22000 10.1.6.56:51512
0 0 10.1.1.176:6379 10.1.1.176:46618
0 0 10.1.1.176:46622 10.1.1.176:6379
0 0 10.1.1.176:46620 10.1.1.176:6379
0 0 10.1.1.176:6379 10.1.1.176:46620
0 0 10.1.1.176:22000 10.1.6.139:45300
显示套接字状态为 time-wait
root@10.1.1.176:~# ss -t4 state time-wait
Recv-Q Send-Q Local Address:Port Peer Address:Port
可以是以下状态
1. established
2. syn-sent
3. syn-recv
4. fin-wait-1
5. fin-wait-2
6. time-wait
7. closed
8. close-wait
9. last-ack
10. closing
11. all - All of the above states
12. connected - All the states except for listen and closed
13. synchronized - All the connected states except for syn-sent
14. bucket - Show states, which are maintained as minisockets, i.e. time-wait and syn-recv.
15. big - Opposite to bucket state.
像很多状态如syn-sent,syn-recv 大部分时间不显示任何套接字,停留在套接字的时间很短,我们可以使用watch命令在一段时间的检测这些套接字的状态.
root@10.1.1.176:~# watch -n 1 "ss -t4 state syn-sent"
10.过滤连接地址和端口号
除了tcp套接字,ss 命令也支持过滤基于地址和端口好的套接字.
root@10.1.1.176:sites-enabled# ss -nt sport = :80 or sport = :22000
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:80 10.1.6.56:52634
ESTAB 0 0 10.1.1.176:80 10.1.6.56:52636
ESTAB 0 0 10.1.1.176:22000 10.1.6.56:51512
ESTAB 0 0 10.1.1.176:80 10.1.6.56:52635
ESTAB 0 0 10.1.1.176:80 10.1.6.56:52637
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
root@10.1.1.176:sites-enabled# ss -nt dport gt :1024
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46622
ESTAB 0 0 10.1.1.176:46618 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46619 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46619
ESTAB 0 264 10.1.1.176:22000 10.1.6.56:51512
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46618
ESTAB 0 0 10.1.1.176:46622 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:46620 10.1.1.176:6379
ESTAB 0 0 10.1.1.176:6379 10.1.1.176:46620
ESTAB 0 0 10.1.1.176:22000 10.1.6.139:45300
下面是支持的语法
<= or le : Less than or equal to port
>= or ge : Greater than or equal to port
== or eq : Equal to port
!= or ne : Not equal to port
< or gt : Less than to port
> or lt : Greater than to port
附录:
TCP正常连接建立和终止所对应的状态
状态变迁:
1.全部11种状态:
1.1 客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT
1.2 服务器独有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK
1.3 共有的: (1)CLOSED (2) ESTABLISHED
2.建立连接时的状态变迁:
开始,建立连接之前服务器和客户端的状态都为CLOSED.服务器创建socket后开始监听,变为LISTEN状态.客户端请求建立连接,向服务器发送SYN报文,客户端的状态变为SYN_SENT.服务器收到客户端的报文后向客户端发送ACK和SYN报文,此时服务器的状态变为SYN_RCVD.然后,客户端收到ACK,SYN,就向服务器发送ACK,客户端状态变为ESTABLISHED,服务器收到客户端的ACK后也变为ESTABLISHED.此时,3次握手完成,连接建立!
3.断开连接时的状态变迁
由于tcp连接是全双工的.客户端先向服务器发送FIN报文,请求断开连接,其状态变为FIN_WAIT1.服务器收到FIN后向客户端发生ACK,服务器状态变为CLOSE_WAIT.客户端收到ACK后就进入FIN_WAIT2状态.此时连接已经断开了一半.如果服务器还有数据要发送给客户端,就会继续发送.直到发完了,就发送FIN报文,此时服务器进入LAST_ACK状态.客户端收到服务器的FIN后,马上发送ACK给服务器,此时客户端进入TIME_WAIT状态,在过了2MSL长的时间后进入CLOSED状态.服务器收到客户端的ACK就进入CLOSED状态.
CLOSING状态.CLOSEING状态表示客户端发生了FIN,但没有收到服务器的ACK,却收到了服务器的FIN.这种情况发送在服务器发送的ACK丢包的时候,因为网络传输有时会有意外.
CLOSED:表示初始状态
LISTEN:表示服务器端的某个socket处于监听状态,可以接受连接.
SYN_SENT:在服务端监听后,客户端socket执行connect连接时,客户端发生SYN报文,此时客户端就进入SYN_SENT状态,等待服务端的确认.
SYN_RCVD:表示服务端接受到了SYN报文,在正常情况下,这个状态是服务器端的socket在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂.除非故意将三次TCP握手过程中最后一个ACK报文不发送.因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISED状态.
ESTABLISHED:表示连接已经建立了.
FIN_WAIT_1:这个是已经建立连接之后,其中一方请求终止连接,等待对方的FIN报文.FIN_WAIT_1状态时当socket在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该socket即进入到FIN_WAIT_1状态.而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般比较难见,而FIN_WAIT_2状态还有可以看到.
FIN_WAIT_2:实际上FIN_WAIT_2状态下的socket,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接.
TIME_WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到closed可用状态.如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态.
CLOSE_WAIT:表示在等待关闭
LAST_ACK:它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文.当收到ACK报文后,也即可以进入到CLOSED可用状态了.
更多语法细节可以安装iproute2-doc
查看文件 /usr/share/doc/iproute2-doc/ss.html