检查 Linux 中端口是否开放的所有方法

您的 Linux 服务器正在运行,现在您想要检查特定端口是否开放,以便可以远程访问。检查开放端口是系统管理员的一个常见任务,在 Linux 中有几种不同的方法可以做到这一点。

在本文中,您将学习几种检查 Linux 端口是否开放的方法,以便您可以选择适合您的最佳方法。准备好了吗?继续阅读!

先决条件

本教程将进行实际演示。如果您想要跟着操作,请确保您具备以下条件。

  • A Linux computer. This guide uses Ubuntu 20.04, but any recent Linux distribution should work.
  • 访问终端。如果您使用图形桌面环境,请在应用程序菜单中查找终端仿真器程序。或者,如果您通过 SSH 登录到远程服务器,
  • A user account with sudo privileges. For simplicity, this tutorial uses the root user.

使用 netstat 在 Linux 中检查端口是否开放

在 Linux 中检查端口是否开放的第一种方法是运行 netstat 命令。此命令显示网络连接、路由表和许多网络接口统计信息。

netstat 命令是 net-tools 软件包的一部分,该软件包可能不会默认安装在您的 Linux 发行版中。在 Ubuntu 上,通过在终端中运行以下命令安装 netstat

apt update -y && apt install net-tools -y

假设您运行着一个NGINX Web服务器,并且想要检查端口80是否开放。您可以通过运行以下命令来执行此操作。将80替换为您希望检查的端口号。

-tulpn标志指示netstat显示所有监听端口。第一个grep命令在结果中找到并过滤包含单词LISTEN的行。第二个grep命令过滤结果,仅显示与:80匹配的项。

netstat -tulpn | grep LISTEN | grep :80

要了解更多关于netstat标志的信息,请运行netstat –help命令。

如果端口开放,您将看到以下输出。如您所见,输出显示系统上端口80是开放的。tcp是协议类型,:::80表示这是一个TCPv6端口。0.0.0.0:80表示该端口对所有IPv4地址开放。80是默认的HTTP端口,用于访问网站。

Checking If a Port is Open with netstat

使用ss检查端口是否开放

ss命令是另一个用于检查开放端口的命令行实用程序。该命令显示套接字统计信息,您可以使用它来确认端口是否打开。与其他工具相比,ss命令显示有关开放端口的更多信息。

netstat命令类似,-t标志指示ss仅显示TCP套接字,-u仅显示UDP套接字,-l仅显示监听套接字。-p标志指示使用端口的进程名称或PID。

ss -tulpn | grep LISTEN | grep :80

如果端口打开,则将看到以下输出。正如您所见,输出包含每个监听端口的进程名称和PID。在这种情况下,端口80是打开的,NGINX Web服务器正在使用它。

Checking If a Port is Open Using ss

使用lsof检查端口是否打开

lsof命令是另一个用于检查开放端口的便利工具。lsof名称代表列出打开的文件,它显示有关系统上打开的文件的信息。此信息包括文件描述符、进程ID、用户ID等。

列出打开的文件如何帮助您确定端口是否打开?您可能已经听说过短语“在Linux中,一切皆为文件”,而这句话意思就是如此。

例如,假设您想要检查端口22是否打开,您的用户是否可以SSH到您的服务器。运行以下命令以列出在端口22上具有活动连接的打开文件。

使用-i标志指示lsof显示所有打开的互联网套接字。使用-P标志显示端口号而不是服务名称。而-n标志则抑制了DNS和服务名称的查询,因此您将看到IP地址而不是远程主机名。

lsof -i -P -n | grep LISTEN | grep :22

如果端口打开,您将看到以下输出。如您所见,输出包含以下信息:

  • 1027是sshd服务的进程ID。
  • root是使用该端口的用户ID。
  • 3u和4u分别是IPv4和IPv6的文件描述符。
  • 31035和31037分别是IPv4和IPv6的网络端口。
  • :22表示端口22对所有IPv4和IPv6地址都是开放的。
  • (LISTEN)表示该端口正在监听传入连接。
  • 0t0是套接字的状态,意味着套接字处于LISTEN状态。
Checking If a Port is Open Using lsof

使用nmap检查端口是否打开

到目前为止,您已经了解了如何使用命令行检查Linux上的端口是否打开。但是如果您想要检查远程机器上的端口是否打开怎么办?在这种情况下,您可以使用nmap工具。

但在运行nmap之前,请注意此工具可能不是您的Linux发行版中的默认软件包的一部分。在这种情况下,您必须首先通过运行以下命令来安装nmap

apt install nmap -y

现在,运行以下命令检查远程主机是否开放某个端口。此命令测试端口22是否对159.89.176.25开放,以便用户可以通过SSH连接到服务器。根据需要替换IP地址。

nmap -p 22 159.89.176.25

正如您所见,输出包含以下信息:

  • 端口扫描开始时间(2022-06-30 16:58 UTC)。
  • 远程主机的IP地址(159.89.176.25)。
  • 端口状态(开放)。
  • 使用该端口的服务(ssh)。
  • 主机状态(上线)。
Checking If a Port is Open Using nmap

结果确认用户可以使用IP地址和端口通过SSH连接到计算机。

ssh [email protected] -p 22

下面的截图显示成功连接到服务器的SSH连接,证明端口22是开放的。

SSHing into your server

从Shell脚本测试端口是否开放

自动化总是个好主意。通过运行Shell脚本检查开放端口是测试多个端口的绝佳方法。您可以使用任何先前的方法检查端口是否开放。但是,为了本示例,您将编写一个运行Netcat nc命令的基本Shell脚本。

1. 使用您喜欢的文本编辑器在您的主目录中创建一个名为check_port.sh的文件。此示例使用nano。

nano check_port.sh

2. 将以下示例代码复制到您的编辑器中。用您要检查的端口号替换80。

条件if使用nc命令检查80端口是否打开。2>&1 和 >/dev/null 将错误和输出消息分别重定向到/dev/null。/dev/null是一个特殊文件,它会丢弃接收到的所有内容。

如果端口打开,check_port.sh脚本将在控制台上打印”Online”。否则,脚本将打印”Offline”。

if ( nc -zv localhost 80 2>&1 >/dev/null ); then
    echo 'Online'
else
    echo 'Offline'
fi

脚本文件应该类似于下面的截图。保存脚本并退出编辑器。

Creating the Shell script

3. 运行shell脚本以开始检查您在脚本中指定的开放端口。

bash check_port.sh

根据端口是否打开,您将看到以下输出之一。在这种情况下,端口是开放的,消息Online证实了这一点。

Check if the 80 port is open

您可以使用此Shell脚本检查端口是否在间隔或计划任务中打开。当您需要检查多个服务器时,脚本编写尤其有帮助。您只需要将check_port.sh脚本复制到您想要检查的所有服务器上,并使用CI/CD工具(如Jenkins或Ansible)运行它。

使用PowerShell测试端口是否打开

PowerShell具有用于测试网络连接的内置cmdlet,称为Test-NetConnection,但该cmdlet仅适用于Windows系统。不用担心;您仍然可以在Linux中使用PowerShell来检查打开的端口和连接,使用TcpClient类。

如果您的Linux计算机尚未安装PowerShell,请按照Microsoft文档中的说明进行安装:在Linux上安装PowerShell

1. 运行以下命令启动PowerShell。

pwsh
Launching PowerShell

2. 接下来,使用您的文本编辑器创建一个名为Test-Port.ps1的文件。此示例使用nano。

nano Test-Port.ps1

3. 接下来,将下面的代码复制到您的编辑器中。保存文件,然后退出编辑器。

注意:此代码是一款全能的PowerShell测试端口工具的摘录。

<#
	.SYNOPSIS
		此函数用于测试开放的TCP/UDP端口。
	.DESCRIPTION
		此函数测试任何TCP/UDP端口,以确定其是开放还是关闭。
	.NOTES

	.PARAMETER Computername
		一个或多个远程计算机名称,以逗号分隔
	.PARAMETER Port
		要测试的一个或多个以逗号分隔的端口号。
	.PARAMETER TcpTimeout
		函数等待声明TCP端口关闭的毫秒数。默认为1000。
	.EXAMPLE
		PS> Test-Port -Computername 'LABDC','LABDC2' -Protocol TCP 80,443
		
		此示例在LABDC和LABDC2服务器上测试TCP网络端口80和443。
	#>
[CmdletBinding()]
[OutputType([System.Management.Automation.PSCustomObject])]
param (
    [Parameter(Mandatory)]
    [string[]]$ComputerName,
    [Parameter(Mandatory)]
    [int[]]$Port,
    [Parameter()]
    [int]$TcpTimeout = 1000
)
begin {
    $Protocol = 'TCP'
}
process {
    foreach ($Computer in $ComputerName) {
        foreach ($Portx in $Port) {            
            $Output = @{ 'Computername' = $Computer; 'Port' = $Portx; 'Protocol' = $Protocol; 'Result' = '' }
            Write-Verbose "$($MyInvocation.MyCommand.Name) - Beginning port test on '$Computer' on port '$Protocol<code>:$Portx'"

            $TcpClient = New-Object System.Net.Sockets.TcpClient
            $Connect = $TcpClient.BeginConnect($Computer, $Portx, $null, $null)
            $Wait = $Connect.AsyncWaitHandle.WaitOne($TcpTimeout, $false)
            if (!$Wait -or !($TcpClient.Connected)) {
                $TcpClient.Close()
                Write-Verbose "$($MyInvocation.MyCommand.Name) - '$Computer' failed port test on port '$Protocol</code>:$Portx'"
                $Output.Result = $false
            }
            else {
                $TcpClient.EndConnect($Connect)
                $TcpClient.Close()
                Write-Verbose "$($MyInvocation.MyCommand.Name) - '$Computer' passed port test on port '$Protocol<code>:$Portx'"
                $Output.Result = $true
                $TcpClient.Close()
                $TcpClient.Dispose()
            }
            [pscustomobject]$Output
        }
    }
}

4. 保存Test-Port.ps1脚本后,运行以下命令测试端口22、80、443和53。

-ComputerName参数接受目标机器的主机名、FQDN或IP地址的列表。

-Port参数接受一个包含一个或多个要测试的端口号的数组。

./Test-Port.ps1 -ComputerName localhost -Port 22,80,443

如下所示,结果显示端口22和80是开放的(True),而端口443不是(False)。

Checking for open ports using PowerShell scripting

要对多个目标端点和端口运行相同的脚本,请编辑下面的代码,将所有目标计算机添加到ComputerName参数中,并将端口号添加到Port参数中。

./Test-Port.ps1 `
    -ComputerName adamtheautomator.com,localhost,8.8.8.8 `
    -Port 22,80,443,53
Checking for open ports on multiple targets using PowerShell scripting

结论

在这篇文章中,您已经学会了如何在Linux中检查端口是否打开。您还学会了如何从Shell脚本和PowerShell中检查端口是否打开。现在,您可以使用这些方法中的任何一种来检查您的计算机或任何远程计算机上的端口是否打开。

但别就此止步。继续查看其他故障排除文章,以继续磨练您的系统管理员技能!

Source:
https://adamtheautomator.com/check-if-a-port-is-open-in-linux/