使用 Linux netstat 命令分析网络端口和会话

CompTIABeginner
立即练习

介绍

在本实验中,你将学习如何使用 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_WAITCLOSE_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 为 3422sshd 程序使用。

此命令对系统管理员来说非常强大。它允许你快速验证哪些服务正在运行并暴露在网络上,这对于故障排除和安全审计都至关重要。

将监听端口映射到正在运行的服务

在此步骤中,你将巩固对正在运行的应用程序与监听网络端口之间联系的理解。你已经看到了如何使用 netstat 列出已有的服务。现在,你将启动自己的简单 Web 服务,并观察它出现在 netstat 输出中,从而实时演示这种关系。

我们将使用 Python 内置的 http.server 模块来快速启动一个 Web 服务器。这是一个方便的开发和测试工具。

  1. 首先,让我们启动 Web 服务器。我们将指示它监听端口 8080,这是 Web 服务的常用备用端口。在终端中,运行以下命令。请注意,你的终端似乎会“挂起”,因为它现在正在积极运行服务器。

    python3 -m http.server 8080
    

    你应该会看到指示服务器已启动的输出:

    Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
    
  2. 此终端现在被 Web 服务器进程占用。你需要一个新的终端来运行其他命令。在 LabEx 环境中,你可以通过单击终端窗口中的“加号”图标或使用菜单(File -> New Tab)来打开一个新的终端标签页。

  3. 在你的终端标签页中,再次运行 netstat 命令以查看监听端口的列表。

    sudo netstat -tulnp
    
  4. 仔细检查输出。你现在将看到端口 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 状态。你已成功启动了一个服务,并确认它正在监听网络连接。

  5. 现在,让我们停止该服务。返回你的第一个终端标签页(运行 Python 服务器的那个),然后按 Ctrl+C。这将中断并终止服务器进程。

  6. 返回第二个终端标签页,最后一次运行 netstat 命令。

    sudo netstat -tulnp
    

    端口 8080 的那一行将消失,证明当应用程序终止时,它不再监听该端口。

通过浏览网站创建新连接

在此步骤中,你将把焦点从服务器端的监听端口转移到客户端的主动连接。到目前为止,你已经观察了等待他人连接的服务。现在,你将从你的机器发起一个到远程服务器的连接,并观察连接的形成。我们将使用命令行工具 curl 来模拟访问网站。

为了观察这个短暂的事件,我们将使用 watch 命令,它会重复运行另一个命令,使我们能够近乎实时地看到 netstat 输出的变化。

  1. 首先,让我们设置监控窗口。在终端中,运行以下命令。这将每两秒执行一次 netstat -antp 并显示结果,持续刷新屏幕。

    watch netstat -antp
    
    • a:显示所有套接字。
    • n:显示数字地址。
    • t:仅显示 TCP 连接。
    • p:显示 PID/程序名称。

    你的终端现在将被 netstat 输出填充,它会自动更新。保持此终端打开并可见。

  2. 现在,你需要打开一个新终端标签页来发出创建连接的命令。单击终端标签栏上的“加号”图标。

  3. 终端标签页中,你将使用 curl 来获取 LabEx 网站的主页。> 符号将 HTML 输出重定向到 /dev/null,这样它就不会弄乱你的屏幕。

    curl https://www.labex.io > /dev/null
    
  4. 一旦你按下 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
    ...
    
    • 注意 StateESTABLISHED,表示一个活动连接。
    • Foreign Address 显示了 labex.io 服务器的 IP 地址和端口 443(HTTPS 的标准端口)。
    • PID/Program name 列清楚地标识了 curl 是发起此连接的程序。
    • Local Address 使用一个高编号的随机端口(如示例中的 45678)。这是一个临时端口(ephemeral port),我们将在下一步中讨论它。
  5. 一旦 curl 命令完成下载(速度非常快),你将看到连接状态变为 TIME_WAITFIN_WAIT,然后从列表中完全消失。

  6. 你现在可以停止 watch 命令。转到第一个终端标签页并按 Ctrl+C。你也可以关闭第二个终端标签页。

识别 ESTABLISHED 会话和临时端口

在最后这个步骤中,你将通过检查一个持久的活动连接来巩固你的理解。这将使你能够清晰地识别一个网络“会话”,并了解你的系统如何使用临时的或“临时”端口进行客户端通信。

netstat 输出中的 ESTABLISHED 连接代表一个活动会话(OSI Layer 5),其中两个应用程序已准备好交换数据。在上一步中,curl 会话非常短暂。为了更轻松地研究会话,我们将使用 SSH 创建一个保持打开状态的会话。

首先,让我们定义一个重要的概念:临时端口(ephemeral ports)。当你的计算机(客户端)连接到服务器上的一个知名端口(如 SSH 的端口 22 或 HTTPS 的端口 443)时,你的操作系统必须为其对话的一方分配一个端口。它会从一个高编号的范围(通常高于 32768)中选择一个临时的、未使用的端口。这就是所谓的临时端口。这种机制允许你的单台机器与同一服务器端口建立许多独立的连接,例如,打开多个浏览器标签页访问同一网站。

  1. 为了创建一个稳定、可观察的会话,你将从你的实验机器通过 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 继续。

    它会显示一个输入密码的提示。你不需要输入密码,只需保持在此处。

  2. 通过单击“加号”图标打开一个新终端标签页。我们需要这个新终端来运行 netstat,而不会干扰我们当前的 SSH 会话。

  3. 在新终端中,再次运行 netstat,但这次我们将使用 grep 命令过滤输出,只显示包含 ESTABLISHED 的行。这使得查找活动会话更加容易。

    netstat -antp | grep ESTABLISHED
    
  4. 输出将显示所有当前活动的 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 连接,它将使用一个不同的临时端口。
  5. 最后,关闭会话。切换回你运行 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 状态的连接,并理解临时端口的作用,临时端口是分配给网络通信客户端的临时端口。