直接通过 man 8 netstat
查看帮助时就可以发现这样的一句话 This program is obsolete. Replacement for netstat is ss.
,而且后面还有几个相关的等价示例介绍。
所以这里简单介绍与 ss 相关的指令。
简介
ss 用于显示 socket 状态,包括了 TCP、UDP、RAW、Unix Domain Sockets 等,与内核之间通过 netlink 机制进行通讯的,相比 Netstat 来说要快速的多,据说即使都使用 procfs,ss 也要快一些,不过没验证过。
如果要使用 netlink 机制,需要内核中相关模块的支持,如 tcp_diag
、udp_diag
、inet_diag
、sock_diag
等,也就是 socket 相关的诊断模块,内核中是否有相关的模块可以通过 lsmod | grep diag
命令查看。
ss 使用的就是 TCP 协议栈中 tcp_diag
模块,一个用于分析统计的模块,可以获得 Linux 内核中第一手的信息。如上所述,如果系统中没有 tcp_diag
,实际上 ss 也可以正常运行,只是效率会变得稍慢。
关于 ss 的帮助信息,可以直接通过 ss -h
查看,或者 man 8 ss
查看。
-h, --help 帮助信息
-V, --version 程序版本信息
-n, --numeric 不解析服务名称
-r, --resolve 解析主机名
-a, --all 显示所有套接字(sockets)
-l, --listening 显示监听状态的套接字(sockets)
-o, --options 显示计时器信息
-e, --extended 显示详细的套接字(sockets)信息
-m, --memory 显示套接字(socket)的内存使用情况
-p, --processes 显示使用套接字(socket)的进程
-i, --info 显示TCP内部信息
-s, --summary 显示套接字(socket)使用概况
-4, --ipv4 仅显示IPv4的套接字(sockets)
-6, --ipv6 仅显示IPv6的套接字(sockets)
-0, --packet 显示PACKET套接字(socket)
-t, --tcp 仅显示TCP套接字(sockets)
-u, --udp 仅显示UCP套接字(sockets)
-d, --dccp 仅显示DCCP套接字(sockets)
-w, --raw 仅显示RAW套接字(sockets)
-x, --unix 仅显示Unix套接字(sockets)
-f, --family=FAMILY 显示FAMILY类型的套接字(sockets),支持unix,inet,inet6,link,netlink
-A, --query=QUERY, --socket=QUERY 指定scoket类型
QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]
-D, --diag=FILE 将原始TCP套接字(sockets)信息转储到文件
-F, --filter=FILE 从文件中都去过滤器信息
接下来,我们看些 ss 经常会使用到的示例。
使用示例
通过 ss 命令,可以查看网络的统计信息,查看相关类型的接口等,如下的示例很多可以从 man 8 ss
中查看,在此仅标记下。
监听端口
查看所有打开监听的网络连接端口,可以通过 -p 选项同时显示相应的进程
# ss -pl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 80 :::mysql :::* users:(("mysqld",pid=7241,fd=20))
TCP 连接信息
显示所有的 TCP 连接信息,其中 Recv-Q
表示收到的请求,Send-Q
表示可以接收的请求队列大小。
$ ss -ta
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 127.0.0.1:smux *:*
LISTEN 0 0 *:3690 *:*
LISTEN 0 0 *:ssh *:*
ESTAB 0 0 192.168.120.204:ssh 10.2.0.68:49368
UNIX socket信息
----- 所有链接到X Server的链接
$ ss -x src /tmp/.X11-unix/*
----- 查看本地MySQL socket链接信息
# ss -x src /tmp/mysql.sock
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
u_str ESTAB 0 0 /tmp/mysql.sock 14595374 * 14594660
TCP 状态过滤
通过 TCP 状态进行过滤,总共有两种方法过滤:A) 根据状态;B) 过滤规则。
----- 所有状态为established的SMTP、SSH连接
$ ss -o state established '( dport = :smtp or sport = :smtp )'
$ ss -o state established '( dport = :ssh or sport = :ssh )'
----- 处于 FIN-WAIT-1状态的源端口为80或者443,目标网络为193.233.7/24所有tcp套接字
$ ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
----- 根据端口状态过滤lt, gt, eq, ne, le, ge
$ ss -ltn sport le 500
----- 通过TCP状态过滤,其中的过滤状态可以通过ss -h查看
$ ss -4 state FILTER-NAME-HERE
匹配进程、远程地址和端口号
匹配进程、远程地址和端口号,基本语法为 ss [dst|src] ADDRESS:PORT
。
$ ss dst 192.168.1.5
$ ss dst 192.168.119.113:http
$ ss src 192.168.119.113:443
本地或者远程端口
将本地或者远程端口和一个数比较,选择一个端口的范围,语法为 ss [dport|sport] OP PORT
。
# ss sport = :http
# ss dport \> :1024
----- 其中OP操作可以为如下其中的一个比较操作
<= or le : 小于或等于端口号
>= or ge : 大于或等于端口号
== or eq : 等于端口号
!= or ne : 不等于端口号
< or gt : 小于端口号
> or lt : 大于端口号
显示统计信息
$ ss -s
Total: 1009 (kernel 1079)
TCP: 57 (estab 23, closed 16, orphaned 2, synrecv 0, timewait 6/0), ports 0
Transport Total IP IPv6
* 1079 - -
RAW 2 1 1
UDP 29 26 3
TCP 41 34 7
INET 72 61 11
FRAG 0 0 0
其它
net-tools
这里简单列举通过老的 net-tools 的工具包进行检查。
----- 查看链接状态,并对其进行统计,如下的两种方法相同
$ netstat -atn | awk '/^tcp/ {++s[$NF]} END {for(key in s) print s[key], "\t", key}' | sort -nr
$ ss -ant | awk ' {++s[$1]} END {for(key in s) print s[key], "\t", key}' | sort -nr
----- 查找较多time_wait连接
$ netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20
----- 对接的IP进行排序
$ netstat -ntu | awk '/^tcp/ {print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
----- 查看80端口连接数最多的20个IP
$ netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}' |sort -rn|head -n20
----- 80端口的各个TCP链接状态
$ netstat -n | grep `hostname -i`:80 |awk '/^tcp/{++S[$NF]}END{for (key in S) print key,S[key]}'