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を含む行を検索してフィルタリングします。2番目のgrepコマンドは、結果を:80に一致する項目のみ表示するようにフィルタリングします。

netstat -tulpn | grep LISTEN | grep :80

netstatフラグについて詳しく知るには、netstat –helpコマンドを実行します。

ポートが開いている場合、次の出力が表示されます。表示されるように、出力にはポート80がシステム上で開いていることが示されています。tcpはプロトコルタイプであり、:::80TCPv6ポートを示します。0.0.0.0:80は、IPv4アドレスすべてに対してポートが開いていることを意味します。80はウェブサイトへのアクセスを提供するデフォルトのHTTPポートです。

Checking If a Port is Open with netstat

ssを使用してポートが開いているかどうかを確認する

ssコマンドは、オープンポートをチェックするための別のコマンドラインユーティリティです。このコマンドはソケットの統計情報を表示し、ポートが開いているかどうかを確認するために使用できます。他のツールよりもオープンポートに関する詳細な情報を表示します。

netstatコマンドと同様に、-tフラグはssにTCPソケットのみを表示するよう指示し、-uはUDPソケットのみを表示し、-lはリスニングソケットのみを表示します。-pフラグはポートを使用しているプロセスの名前またはPIDを示します。

ss -tulpn | grep LISTEN | grep :80

ポートが開いている場合、以下の出力が表示されます。出力には、各リスニングポートのプロセス名とPIDが含まれています。この場合、ポート80が開いており、NGINXウェブサーバーが使用しています。

Checking If a Port is Open Using ss

lsofを使用してポートが開いているかどうかを確認する

lsofコマンドは、オープンポートをチェックするための便利なツールです。 lsoflist open filesの略であり、システム上でオープンされているファイルに関する情報を表示します。この情報には、ファイルディスクリプタ、プロセス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

次のコマンドを実行して、リモートマシンのポートが開いているかどうかを確認します。このコマンドはポート 22159.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

以下のスクリーンショットは、ポート22が開いていることを証明するサーバーへのSSH接続の成功を示しています。

SSHing into your server

シェルスクリプトからポートが開いているかどうかをテストする

自動化は常に良いアイデアです。シェルスクリプトを実行してポートが開いているかどうかをテストすることは、複数のポートをテストする優れた方法です。ポートが開いているかどうかを確認するために以前の方法を使用することもできますが、この例では基本的なシェルスクリプトを作成し、Netcatncコマンドを実行します。

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. シェルスクリプトを実行して、スクリプト内で指定した開いているポートをチェックします。

bash check_port.sh

ポートが開いているかどうかに応じて、以下のいずれかの出力が表示されます。この場合、ポートは開いているため、「Online」というメッセージが確認されます。

Check if the 80 port is open

このシェルスクリプトを使用すると、間隔またはスケジュールされたジョブでポートが開いているかどうかをチェックすることができます。スクリプトは特に複数のサーバーをチェックする必要がある場合に役立ちます。チェックしたいすべてのサーバーにこのcheck_port.shスクリプトをコピーし、JenkinsやAnsibleなどのCI/CDツールを使用して実行するだけです。

PowerShellを使用してポートが開いているかどうかをテストする

PowerShellには、ネットワーク接続をテストするための組み込みのコマンドレットであるTest-NetConnectionがありますが、このコマンドレットはWindowsシステムでのみ利用可能です。心配しないでください。Linuxでも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
		この関数は、オープンまたはクローズしているかをテストします。
	.NOTES

	.PARAMETER Computername
		1つまたは複数のリモートの、カンマ区切りのコンピュータ名
	.PARAMETER Port
		テストしたい1つまたは複数のカンマ区切りのポート番号
	.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パラメータには、テストする1つ以上のポート番号の配列を指定します。

./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でポートが開いているかどうかをチェックする方法について学びました。また、シェルスクリプトやPowerShellからポートが開いているかどうかをチェックする方法も学びました。これらの方法のいずれかを使用して、自分のマシンやリモートマシン上のポートが開いているかどうかを確認できます。

しかし、ここで終わらずに、他のトラブルシューティング記事をチェックして、システム管理者スキルをさらに磨いてください!

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