Contents

在Linux中查找开放端口

1. 概述

Linux中的端口 是一个虚拟概念,有助于访问网络中的不同服务。它是一个 16 位整数,范围从 0 到 65535,物理上不存在。当一个端口与一个 IP 地址 组合时,会产生一个套接字地址,用于在客户端和服务器 之间建立连接。

在本教程中,我们将了解开放端口以及它们在实现安全环境中的重要性。然后,我们将查看不同的 Linux 命令以查找所有打开的端口。

2. 什么是开放端口?

主动接受连接的端口称为开放端口。这样建立的连接用于访问与该端口关联的服务。

一个端口一次可以被一个服务/进程占用。我们可以终止与端口关联的现有进程 ,并将新进程/服务重新分配给同一端口。

开放端口充当入口点。因此,它增加了我们安全环境的易受攻击端点。它是在端口后面运行的服务/进程,可能导致一些严重的安全漏洞。例如,假设 Apache 服务器在端口 80 上托管一个基本的 HTML 页面。攻击者永远无法通过访问 HTML 页面来造成安全威胁。但另一方面,假设现在我们托管了一个带有一些易受攻击代码的 PHP 应用程序。这一次,攻击者可以通过访问我们的应用程序轻松利用系统。

请注意,端口(即 80)在两种情况下都是相同的。因此,真正对系统造成威胁的是在 Apache 服务器上运行的代码。

因此,作为最佳实践,我们必须始终关闭所有不打算公开的开放端口。

3. 在 Linux 中查找开放端口

现在让我们深入研究各种 Linux 命令来识别我们机器上的开放端口。

3.1. 使用ss命令

ss (套接字统计)是一个用于显示套接字信息的 CLI 实用程序。它属于 iproute2 包,比老式的 net-tools 包更快、更优化并提供更多信息。

我们可以使用带有一系列选项的ss命令来列出所有打开的 TCP 端口:

$ ss -tnlp
State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:111         0.0.0.0:*          users:(("rpcbind",pid=795,fd=4),("systemd",pid=1,fd=48)) 
LISTEN  0       128     0.0.0.0:22          0.0.0.0:*          users:(("sshd",pid=1230,fd=5))
LISTEN  0       128     *:443               *:*                users:(("httpd",pid=21905,fd=9),... 
LISTEN  0       128     [::]:111            [::]:*             users:(("rpcbind",pid=795,fd=6),("systemd",pid=1,fd=52))
LISTEN  0       128     *:80                *:*                users:(("httpd",pid=21905,fd=4),...
LISTEN  0       128     [::]:22             [::]:*             users:(("sshd",pid=1230,fd=7))

在这里,我们使用了四个选项来获得所需的输出:

  • t : 显示 TCP 套接字
  • n : 显示数字端口号
  • l : 显示监听套接字
  • p : 显示使用套接字的进程

在上面生成的命令输出中,第四列表示本地套接字地址。它是 IP 地址和端口的组合。这些端口都是开放的。此外,我们可以在第六列中找到与该特定端口关联的进程。此列包括进程详细信息,如进程名称、进程 ID 和文件描述符。

由于我们在命令中使用了标志*l ,因此每一行的“状态”(第一列)将为 LISTEN。*这表示特定套接字处于侦听状态。

ss是一个非常强大的命令,具有多种选项。我们可以使用帮助命令ss -help找到所有可用的选项,然后即插即用它们以获得所需的输出。

3.2. 使用netstat命令

netstat 是另一个显示网络连接详细信息的 Linux 命令。但是,由于缺乏对 Linux 内核的许多现代特性的支持以及一些优化问题,它被正式 标记为已过时。

要找到打开的端口,我们将使用我们在上面的ss命令中使用的相同选项:

$ netstat -tnlp
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:111             0.0.0.0:*               LISTEN      1/systemd           
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1230/sshd           
tcp6       0      0 :::443                  :::*                    LISTEN      925/httpd           
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd           
tcp6       0      0 :::80                   :::*                    LISTEN      925/httpd           
tcp6       0      0 :::22                   :::*                    LISTEN      1230/sshd          

ssnetstat的选项和语法 非常相似。因此ss命令可以替代 netstat命令。

3.2. 使用lsof命令

在 Linux 中一切都是文件。lsof(打开文件列表)是一个列出 Linux 中所有打开文件的实用程序。lsof命令从内核的 proc 文件系统中读取数据。因此,它具有基于进程、用户、应用程序或端口来跟踪网络连接的能力。

lsof命令支持各种选项来根据我们的需要过滤输出。现在让我们看看将列出打开的 TCP 连接使用的端口的选项组合:

$ lsof -i -P -sTCP:LISTEN
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd     1   root   48u  IPv4   1822      0t0  TCP *:111 (LISTEN)
systemd     1   root   52u  IPv6   1824      0t0  TCP *:111 (LISTEN)
rpcbind   795    rpc    4u  IPv4   1822      0t0  TCP *:111 (LISTEN)
rpcbind   795    rpc    6u  IPv6   1824      0t0  TCP *:111 (LISTEN)
httpd     925   root    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd     925   root    9u  IPv6  25594      0t0  TCP *:443 (LISTEN)
sshd     1230   root    5u  IPv4  28121      0t0  TCP *:22 (LISTEN)
sshd     1230   root    7u  IPv6  28123      0t0  TCP *:22 (LISTEN)
httpd   21196 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21196 apache    9u  IPv6  25594      0t0  TCP *:443 (LISTEN)
httpd   21197 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21197 apache    9u  IPv6  25594      0t0  TCP *:443 (LISTEN)
httpd   21223 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21223 apache    9u  IPv6  25594      0t0  TCP *:443 (LISTEN)
httpd   21905 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21905 apache    9u  IPv6  25594      0t0  TCP *:443 (LISTEN)

在上面的命令中,我们使用 -i选项仅列出网络文件,并使用 -P 显示端口的数值而不是它们的名称。 -sTCP:LISTEN用于过滤处于LISTEN状态的TCP协议文件。

输出类似于 ss 命令的输出。唯一的区别是 ss命令根据进程对输出进行分组。

我们可以使用lsof命令检查任何端口是否打开:

$ lsof -P -i:80
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd     925   root    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21196 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21197 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21223 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)
httpd   21905 apache    4u  IPv6  25918      0t0  TCP *:80 (LISTEN)

lsof命令的主要缺点 是它**需要 sudo 权限才能显示正确的输出。**到目前为止,我们已经使用 root 用户执行了所有命令。

从上面生成的输出中可以清楚地看到,HTTP 进程正在使用rootapache用户运行。现在让我们使用非 root 用户(比如centos用户)运行相同的lsof命令:

$ su centos
$ lsof -i:80

这次,它没有显示任何输出。这是因为lsof命令无法读取使用root用户创建的 HTTP 进程的 proc 目录。

3.3. 使用nmap命令

nmap (Network Mapper) 是一种开源网络扫描工具,被网络安全专家和系统管理员广泛使用。该工具可用于多种用途,包括操作系统检测、端口扫描、网络审计等。

与其他命令(sslsof)不同,nmap实用程序可以在任何远程计算机上找到打开的端口。我们不需要访问该机器。此外,无需 root 权限即可运行此命令。

让我们使用nmap命令执行端口扫描:

$ nmap google.com
Starting Nmap 7.70 ( https://nmap.org ) at 2022-01-26 19:23 UTC
Nmap scan report for google.com (142.250.190.110)
Host is up (0.018s latency).
Other addresses for google.com (not scanned): 2607:f8b0:4009:809::200e
rDNS record for 142.250.190.110: ord37s35-in-f14.1e100.net
Not shown: 998 filtered ports
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https
Nmap done: 1 IP address (1 host up) scanned in 12.29 seconds

在上面的命令中,我们使用主机名 google.com 扫描端口。nmap命令会自动从 DNS 记录中获取 IP。如果已知,我们也可以在nmap命令中使用 IP 。

输出包括一些与主机相关的基本元数据,以及开放端口列表。我们可以使用*-v*选项以详细模式显示输出。

注意谷歌服务器上没有不必要的开放端口。这样做是为了最大限度地降低安全风险。我们会注意到大多数流行主机名的这种行为,例如 youtube.com、stackoverflow.com、amazon.com、netflix.com 等。