什么是监听端口
首先我们了解一下TCP/IP协议中的端口指的是什么?如果把IP地址比作一间房子 ,端口就是出入这间房子的门。真正的房子只有一个或者几个门,但是一个IP地址下的端口可以有65536(即:256×256)个之多!端口是通过端口号来标记的,端口号只有整数,范围是从0到65535(256×256-1)。
在互联网上主机与主机之间通过TCP/IP协议发送和接收数据包,各个数据包根据其目的主机IP地址来进行路由。当数据包顺利的被传送到目的主机后,它要如何进入主机呢?当然是要通过端口(现实中的门)进入了。我们知道大多数操作系统都支持多应用程序(多进程)同时运行,不同的应用具有不同的处理功能,那么目的主机应该把接收到的数据包传送给哪一个应用程序呢?这就要靠端口了,一个应用对应一个或多个端口,这样我们就可以把数据包传递给对应的程序了。这就是监听端口的由来。
同一个端口只能被一个应用程序使用。如果多个应用使用了相同端口,就会出现端口冲突问题。这种情况通常我们不需要担心,因为端口冲突会导致应用程序无法启动。
比如:我们系统上已经启动了一个Apache Web服务,它使用了80和443端口,当我们尝试启动Nginx时将无法启动,因为HTTP(80)和HTTPS(443)端口已在使用。
查看监听端口命令:netstat
netstat是一个命令行工具,使用它我们可以查看网络连接的信息,包括正在监听的端口号。
要列出正在监听的所有TCP或UDP端口,包括使用端口和套接字状态的服务,请使用以下命令:
[deploy@bdserver ~]# sudo netstat -tunlp
选项说明:
- t - 显示TCP端口。
- u - 显示UDP端口。
- n - 显示数字地址而不是解析主机。
- l - 仅显示侦听端口。
- p - 显示监听端口对应的进程PID和名称。只有当用户拥有root或sudo权限时,才会显示此信息。
示例输出:
[deploy@bdserver ~]# sudo netstat -tunlp
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:7300 0.0.0.0:* LISTEN 78226/node /root/wo
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 73751/mongod
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 72507/redis-server
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 106488/nginx: maste
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1078/sshd
tcp6 0 0 :::3306 :::* LISTEN 106062/mysqld
tcp6 0 0 :::781 :::* LISTEN 56548/./bcm-agent
tcp6 0 0 :::111 :::* LISTEN 1/systemd
tcp6 0 0 :::22 :::* LISTEN 1078/sshd
udp 0 0 127.0.0.1:323 0.0.0.0:* 1201/chronyd
udp 0 0 0.0.0.0:793 0.0.0.0:* 6130/rpcbind
udp 0 0 0.0.0.0:68 0.0.0.0:* 584/dhclient
udp 0 0 0.0.0.0:111 0.0.0.0:* 1/systemd
udp6 0 0 ::1:323 :::* 1201/chronyd
udp6 0 0 :::793 :::* 6130/rpcbind
udp6 0 0 :::111 :::* 1/systemd
示例中的几个重要列名解释:
- Proto - 套接字使用的协议。
- Local Address - 进程监听的IP地址和端口号。
- PID/Program name - PID和进程名称。
我们可以使用grep命令过滤输出内容。例如,我们只查看在TCP端口22上监听的信息,就可以输入以下命令:
[deploy@bdserver ~]# sudo netstat -tnlp | grep :22
示例,只输出占用22端口的信息:
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1078/sshd
tcp6 0 0 :::22 :::* LISTEN 1078/sshd
如果没有任何内容输出,则表示该端口并未进行监听或者端口对应的应用程序未运行。
我们也可以筛选其他内容,如PID,协议,状态等。
虽然netstat有些过时,并正在被其它命令替代,但它仍然是最常用的网络异常诊断命令。
查看监听端口命令:ss
ss是新的监听端口查看命令。比起netstat,它缺少一些功能,但暴露了更多的TCP状态,而且速度稍快。命令选项大致相同,因此从netstat转为使用ss并不困难。要获取所有监听端口的列表,我们输入如下ss命令:
[deploy@bdserver ~]# sudo ss -tunlp
输出几乎与netstat命令的输出相同:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 0 0 127.0.0.1:323 *:* users:(("chronyd",pid=1201,fd=1))
udp UNCONN 0 0 *:793 *:* users:(("rpcbind",pid=6130,fd=10))
udp UNCONN 0 0 *:68 *:* users:(("dhclient",pid=584,fd=6))
udp UNCONN 0 0 *:111 *:* users:(("rpcbind",pid=6130,fd=5),("systemd",pid=1,fd=79))
udp UNCONN 0 0 ::1:323 :::* users:(("chronyd",pid=1201,fd=2))
udp UNCONN 0 0 :::793 :::* users:(("rpcbind",pid=6130,fd=11))
udp UNCONN 0 0 :::111 :::* users:(("rpcbind",pid=6130,fd=7),("systemd",pid=1,fd=81))
tcp LISTEN 0 128 *:7300 *:* users:(("node /root/work",pid=78226,fd=21))
tcp LISTEN 0 128 127.0.0.1:27017 *:* users:(("mongod",pid=73751,fd=11))
tcp LISTEN 0 128 127.0.0.1:6379 *:* users:(("redis-server",pid=72507,fd=4))
tcp LISTEN 0 128 *:111 *:* users:(("rpcbind",pid=6130,fd=4),("systemd",pid=1,fd=78))
tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=106489,fd=6),("nginx",pid=106488,fd=6))
tcp LISTEN 0 128 *:22 *:* users:(("sshd",pid=1078,fd=3))
tcp LISTEN 0 128 :::3306 :::* users:(("mysqld",pid=106062,fd=14))
tcp LISTEN 0 128 :::781 :::* users:(("bcm-agent",pid=56548,fd=8))
tcp LISTEN 0 128 :::111 :::* users:(("rpcbind",pid=6130,fd=6),("systemd",pid=1,fd=80))
tcp LISTEN 0 128 :::22 :::* users:(("sshd",pid=1078,fd=4))
查看监听端口命令:lsof
lsof是一个功能强大的命令行实用工具,它将列出当前系统中进程已打开的文件信息。lsof作为Linux下的一个非常实用的系统级的监控、诊断工具,它被广泛的使用。由于lsof需要访问核心内存和各种文件,所以最好使用root或者sudo用户执行lsof命令。
要获取所有lsof类型的监听TCP端口的列表:
[deploy@bdserver ~]# sudo lsof -nP -iTCP -sTCP:LISTEN
选项说明:
- -n - 不要将端口号转换为端口名称。
- -p - 不要解析主机名,显示数字地址。
- -iTCP -sTCP:LISTEN - 仅显示TCP状态LISTEN的网络文件。
示例输出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 78u IPv4 23624 0t0 TCP *:111 (LISTEN)
systemd 1 root 80u IPv6 23626 0t0 TCP *:111 (LISTEN)
sshd 1078 root 3u IPv4 19279 0t0 TCP *:22 (LISTEN)
sshd 1078 root 4u IPv6 19281 0t0 TCP *:22 (LISTEN)
rpcbind 6130 rpc 4u IPv4 23624 0t0 TCP *:111 (LISTEN)
rpcbind 6130 rpc 6u IPv6 23626 0t0 TCP *:111 (LISTEN)
bcm-agent 56548 root 8u IPv6 45645802 0t0 TCP *:781 (LISTEN)
redis-ser 72507 redis 4u IPv4 3538462 0t0 TCP 127.0.0.1:6379 (LISTEN)
mongod 73751 mongod 11u IPv4 3540908 0t0 TCP 127.0.0.1:27017 (LISTEN)
node 78226 root 21u IPv4 3547459 0t0 TCP *:7300 (LISTEN)
mysqld 106062 mysql 14u IPv6 628403 0t0 TCP *:3306 (LISTEN)
nginx 106488 root 6u IPv4 629126 0t0 TCP *:80 (LISTEN)
nginx 106489 www 6u IPv4 629126 0t0 TCP *:80 (LISTEN)
列名说明:
COMMAND,PID,USER-命令名称,PID和运行用户。
NAME - 端口号。
示例,使用lsof命令查看3306端口监听情况:
[deploy@bdserver ~]# sudo lsof -nP -iTCP:3306 -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 106062 mysql 14u IPv6 628403 0t0 TCP *:3306 (LISTEN)
从输出信息可以看出,3306正在监听,且对应的应用程序为MySQL数据库。
lsof更多信息,请参考:lost命令手册