在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
ss和netstat的选项和语法 非常相似。因此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 进程正在使用root和apache用户运行。现在让我们使用非 root 用户(比如centos用户)运行相同的lsof命令:
$ su centos
$ lsof -i:80
这次,它没有显示任何输出。这是因为lsof命令无法读取使用root用户创建的 HTTP 进程的 proc 目录。
3.3. 使用nmap命令
nmap (Network Mapper) 是一种开源网络扫描工具,被网络安全专家和系统管理员广泛使用。该工具可用于多种用途,包括操作系统检测、端口扫描、网络审计等。
与其他命令(ss和lsof)不同,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 等。