介绍
在本实验中,你将学习如何使用 netstat 命令来分析 Linux 系统上的网络活动。你将探索网络端口、套接字(sockets)和活动连接等基本概念,以深入了解服务如何在网络上进行通信。
你将首先列出所有活动的套接字,然后过滤结果以关注正在监听的 TCP 和 UDP 端口,并将它们映射到正在运行的服务。为了让你看到这些概念的实际应用,你将通过浏览一个网站来生成一个新的连接,然后使用 netstat 来识别新创建的 ESTABLISHED 会话及其关联的临时端口。
使用 netstat -a 列出所有活动和监听的套接字
在此步骤中,你将开始使用 netstat 命令探索系统的网络活动。此命令是网络管理员和开发人员的基本工具,可提供对网络连接、路由表和接口统计信息的洞察。我们将从 -a 选项开始,该选项指示 netstat 显示所有活动的套接字,包括与远程系统的连接以及正在“监听”新传入连接的端口。
首先,请确保你位于默认工作目录中。本实验中的所有命令都将在终端中运行。
现在,让我们列出所有套接字。在终端中,输入以下命令并按 Enter:
netstat -a
你将看到大量的输出。不用担心,我们将对其进行分解。输出显示了所有类型的套接字,包括 TCP、UDP 和 UNIX 域套接字。
让我们检查一下输出的结构。它应该与此类似(你系统上的确切详细信息会有所不同):
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp 0 0 localhost:6010 0.0.0.0:* LISTEN
tcp 0 52 labex-vm:ssh 192.168.0.10:54321 ESTABLISHED
tcp6 0 0 [::]:http-alt [::]:* LISTEN
udp 0 0 0.0.0.0:bootpc 0.0.0.0:*
...
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] DGRAM 23456 /run/systemd/notify
unix 2 [ ACC ] STREAM LISTENING 34567 /tmp/.X11-unix/X0
...
以下是 Internet 连接最重要的列的细分:
- **
Proto**:套接字使用的协议,例如tcp(用于 TCPv4)、tcp6(用于 TCPv6)或udp。 Local Address:你系统的 IP 地址以及它为此连接使用的端口号。端口是冒号 (:) 后面的数字。地址为0.0.0.0或[::]表示该端口正在监听你机器上所有可用的网络接口。- **
Foreign Address**:远程系统的 IP 地址和端口号。如果状态为LISTEN,则通常为0.0.0.0:*或[::]:*,表示它正在等待来自任何地址的连接。 - **
State**:这对 TCP 连接至关重要。LISTEN:应用程序正在指定的Local Address端口上等待传入连接。这是服务器端状态。ESTABLISHED:连接已激活,可以在本地和远程地址之间传输数据。- 其他状态,如
TIME_WAIT或CLOSE_WAIT,与关闭 TCP 连接的过程有关。
花点时间滚动浏览输出,并识别 LISTEN 状态下的任何条目。这些代表你系统上已准备好接受网络连接的服务。这是对传输层(第 4 层)的直接观察。
使用 sudo netstat -tulnp 过滤监听的 TCP/UDP 端口
在上一步中,netstat -a 命令为我们提供了所有套接字的完整但冗长的列表。为了使这些信息更有用,我们需要对其进行过滤。在此步骤中,你将学习如何使用 netstat 的特定选项来仅显示正在监听的 TCP 和 UDP 端口,最重要的是,识别使用它们的程序。
要查看与端口关联的程序名称,通常需要管理员权限,因为该进程可能由系统或其他用户拥有。这就是我们使用 sudo 命令的原因。在 LabEx 环境中,你可以无需密码使用 sudo。
让我们运行一个更具针对性的 netstat 命令。在终端中,输入以下内容:
sudo netstat -tulnp
让我们分解这些选项,因为它们经常组合使用:
t:显示 TCP 连接。u:显示 UDP 连接。l:仅显示监听的套接字。这是我们查看哪些服务正在等待连接的主要过滤器。n:显示数字地址。这可以防止netstat尝试将 IP 地址和端口号解析为主机名和服务名(例如,它显示22而不是ssh),这使得命令运行速度大大加快。p:显示套接字所属程序的进程 ID (PID) 和名称。这需要sudo才能查看所有进程。
按 Enter 后,你的输出将更短且信息更丰富。它看起来会像这样:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 779/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3422/sshd
udp 0 0 127.0.0.53:53 0.0.0.0:* 779/systemd-resolve
请注意末尾的新列:PID/Program name。这是关键信息。你现在可以直接将监听端口映射到打开它的确切应用程序。例如,在上面的输出中,你可以看到端口 22(SSH 的标准端口)正被进程 ID 为 3422 的 sshd 程序使用。
此命令对系统管理员来说非常强大。它允许你快速验证哪些服务正在运行并暴露在网络上,这对于故障排除和安全审计都至关重要。
将监听端口映射到正在运行的服务
在此步骤中,你将巩固对正在运行的应用程序与监听网络端口之间联系的理解。你已经看到了如何使用 netstat 列出已有的服务。现在,你将启动自己的简单 Web 服务,并观察它出现在 netstat 输出中,从而实时演示这种关系。
我们将使用 Python 内置的 http.server 模块来快速启动一个 Web 服务器。这是一个方便的开发和测试工具。
首先,让我们启动 Web 服务器。我们将指示它监听端口
8080,这是 Web 服务的常用备用端口。在终端中,运行以下命令。请注意,你的终端似乎会“挂起”,因为它现在正在积极运行服务器。python3 -m http.server 8080你应该会看到指示服务器已启动的输出:
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...此终端现在被 Web 服务器进程占用。你需要一个新的终端来运行其他命令。在 LabEx 环境中,你可以通过单击终端窗口中的“加号”图标或使用菜单(
File -> New Tab)来打开一个新的终端标签页。在你的新终端标签页中,再次运行
netstat命令以查看监听端口的列表。sudo netstat -tulnp仔细检查输出。你现在将看到端口
8080的新条目。Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 779/systemd-resolve tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3422/sshd tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 12345/python3 udp 0 0 127.0.0.53:53 0.0.0.0:* 779/systemd-resolve ...如你所见,系统现在报告
python3程序(具有特定的 PID,例如12345)处于端口8080上的LISTEN状态。你已成功启动了一个服务,并确认它正在监听网络连接。现在,让我们停止该服务。返回你的第一个终端标签页(运行 Python 服务器的那个),然后按
Ctrl+C。这将中断并终止服务器进程。返回第二个终端标签页,最后一次运行
netstat命令。sudo netstat -tulnp端口
8080的那一行将消失,证明当应用程序终止时,它不再监听该端口。
通过浏览网站创建新连接
在此步骤中,你将把焦点从服务器端的监听端口转移到客户端的主动连接。到目前为止,你已经观察了等待他人连接的服务。现在,你将从你的机器发起一个到远程服务器的连接,并观察连接的形成。我们将使用命令行工具 curl 来模拟访问网站。
为了观察这个短暂的事件,我们将使用 watch 命令,它会重复运行另一个命令,使我们能够近乎实时地看到 netstat 输出的变化。
首先,让我们设置监控窗口。在终端中,运行以下命令。这将每两秒执行一次
netstat -antp并显示结果,持续刷新屏幕。watch netstat -antpa:显示所有套接字。n:显示数字地址。t:仅显示 TCP 连接。p:显示 PID/程序名称。
你的终端现在将被
netstat输出填充,它会自动更新。保持此终端打开并可见。现在,你需要打开一个新终端标签页来发出创建连接的命令。单击终端标签栏上的“加号”图标。
在新终端标签页中,你将使用
curl来获取 LabEx 网站的主页。>符号将 HTML 输出重定向到/dev/null,这样它就不会弄乱你的屏幕。curl https://www.labex.io > /dev/null一旦你按下
Enter,迅速将视图切换回你的第一个终端标签页(运行watch的那个)。你将看到一个新连接出现几秒钟。它看起来会像这样:Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name ... tcp 0 0 172.17.0.2:45678 104.21.5.141:443 ESTABLISHED 13579/curl ...- 注意
State是ESTABLISHED,表示一个活动连接。 Foreign Address显示了labex.io服务器的 IP 地址和端口443(HTTPS 的标准端口)。PID/Program name列清楚地标识了curl是发起此连接的程序。Local Address使用一个高编号的随机端口(如示例中的45678)。这是一个临时端口(ephemeral port),我们将在下一步中讨论它。
- 注意
一旦
curl命令完成下载(速度非常快),你将看到连接状态变为TIME_WAIT或FIN_WAIT,然后从列表中完全消失。你现在可以停止
watch命令。转到第一个终端标签页并按Ctrl+C。你也可以关闭第二个终端标签页。
识别 ESTABLISHED 会话和临时端口
在最后这个步骤中,你将通过检查一个持久的活动连接来巩固你的理解。这将使你能够清晰地识别一个网络“会话”,并了解你的系统如何使用临时的或“临时”端口进行客户端通信。
netstat 输出中的 ESTABLISHED 连接代表一个活动会话(OSI Layer 5),其中两个应用程序已准备好交换数据。在上一步中,curl 会话非常短暂。为了更轻松地研究会话,我们将使用 SSH 创建一个保持打开状态的会话。
首先,让我们定义一个重要的概念:临时端口(ephemeral ports)。当你的计算机(客户端)连接到服务器上的一个知名端口(如 SSH 的端口 22 或 HTTPS 的端口 443)时,你的操作系统必须为其对话的一方分配一个端口。它会从一个高编号的范围(通常高于 32768)中选择一个临时的、未使用的端口。这就是所谓的临时端口。这种机制允许你的单台机器与同一服务器端口建立许多独立的连接,例如,打开多个浏览器标签页访问同一网站。
为了创建一个稳定、可观察的会话,你将从你的实验机器通过 SSH 连接回它自身。在终端中,运行以下命令:
ssh localhost第一次执行此操作时,你可能会看到一条关于主机真实性的消息。这是正常的。
The authenticity of host 'localhost (127.0.0.1)' can't be established. ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Are you sure you want to continue connecting (yes/no/[fingerprint])?输入
yes并按Enter继续。它会显示一个输入密码的提示。你不需要输入密码,只需保持在此处。
通过单击“加号”图标打开一个新终端标签页。我们需要这个新终端来运行
netstat,而不会干扰我们当前的 SSH 会话。在新终端中,再次运行
netstat,但这次我们将使用grep命令过滤输出,只显示包含ESTABLISHED的行。这使得查找活动会话更加容易。netstat -antp | grep ESTABLISHED输出将显示所有当前活动的 TCP 连接。你可能会看到一条警告,提示并非所有进程都能被识别,这是预期的,因为我们没有使用
sudo。你应该会看到你与实验环境的原始 SSH 连接,以及你刚刚创建的到localhost的新连接。(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 172.16.50.192:22 47.251.66.143:36882 ESTABLISHED - tcp 0 0 127.0.0.1:46280 127.0.0.1:22 ESTABLISHED 5449/ssh tcp 0 0 127.0.0.1:22 127.0.0.1:46280 ESTABLISHED -让我们分析一下由
127.0.0.1地址标识的新localhost连接:- 连接的服务器端是
127.0.0.1:22,这是监听端口 22 的 SSH 服务器(sshd)。它有一个来自127.0.0.1:46280的已建立连接。程序信息是-,因为sshd进程由 root 用户拥有,而我们没有使用sudo。 - 客户端是
127.0.0.1:46280连接到127.0.0.1:22。程序被清楚地标识为5449/ssh。 - 端口
46280是临时端口。你的系统为这个特定的 SSH 会话的客户端端随机选择了它。如果你要打开另一个ssh localhost连接,它将使用一个不同的临时端口。
- 连接的服务器端是
最后,关闭会话。切换回你运行
ssh localhost的终端标签页,输入exit,然后按Enter。exit这将终止连接。如果你在另一个终端中再次运行
netstat -antp | grep ESTABLISHED,你将看到localhost会话已消失。
总结
在这个实验中,你学习了如何使用 netstat 命令来分析 Linux 系统上的网络活动。你首先使用 netstat -a 列出了所有活动和监听的套接字,包括 TCP、UDP 和 UNIX 域套接字。然后,你通过应用 -t、-u、-l、-n 和 -p 等标志来细化输出,以便专门筛选监听的 TCP 和 UDP 端口,显示数字地址,并识别与每个端口关联的进程 ID 和名称。
在此基础上,你练习了如何解读命令的输出,将监听端口与其对应的服务进行映射。为了观察连接的实际情况,你通过连接到一个网站来发起一个新的网络会话。这使你能够识别处于 ESTABLISHED 状态的连接,并理解临时端口的作用,临时端口是分配给网络通信客户端的临时端口。



