1. 概要

このチュートリアルでは、Linuxで接続用にネットワークポートが開いているかどうかを確認する方法を見ていきます。 この目的に使用できるBashユーティリティのいくつかを詳しく見ていきます。時間効率の良いソリューションを実現するために提供されたメソッドのパフォーマンスのベンチマークも行います。

2. netstatコマンドの使用

Linuxのnetstatコマンドラインユーティリティは、多くのネットワークプロトコルおよびインターフェイスの net work statisticsを出力します。 これを使用して、ネットワークソケットを調査し、Linuxのネットワークポートのステータスをテストできます。 まず、netstatコマンドのデフォルト出力を確認しましょう。

$ netstat | head
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 localhost:34702         localhost:8684          ESTABLISHED
tcp        0      0 localhost:5747          localhost:55488         ESTABLISHED
tcp        0      0 localhost:5161          localhost:44858         ESTABLISHED
tcp        0      0 localhost:8580          localhost:42432         ESTABLISHED
tcp        0      0 localhost:54090         localhost:3852          ESTABLISHED
tcp        0      0 localhost:8186          localhost:52896         ESTABLISHED
tcp        0      0 localhost:7367          localhost:43282         ESTABLISHED
tcp        0      0 localhost:4441          localhost:35762         ESTABLISHED
$

この出力では、「ローカルアドレス」および「外部アドレス」列の下に、ポート番号がコロン「:」の後に表示されます。 ネットワークアドレスの状態(IPとポートの組み合わせ)は、「状態」列に一覧表示されます。

特定のポートのステータスを確認するようにコマンドを変更してみましょう。

$ netstat -nap | grep ":8001"
(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 0.0.0.0:8001            0.0.0.0:*               LISTEN      19135/nc
tcp        0      0 127.0.0.1:8001          127.0.0.1:55368         ESTABLISHED 19135/nc
tcp        0      0 127.0.0.1:55368         127.0.0.1:8001          ESTABLISHED 19138/nc

ここでは、 grep コマンドを使用して、ポート「8001」のステータスを確認しています。

-n オプションを使用して、ホスト名を判別しようとするのではなく、数値アドレスを強制的に出力していることに注意してください。 – a オプションを使用すると、すべてのリスニングソケットと非リスニングソケットを印刷できます。 -p オプションは、このソケットが属するプロセスのPIDを出力するために使用されます。

ポートがLISTENモードの場合、接続のために開いています。 したがって、LISTENに対してgrepを使用しましょう。 また、timeコマンドを使用してコマンドの実行時間を確認します。

$ time (netstat -nap | grep ":8001" | grep LISTEN)
(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 0.0.0.0:8001            0.0.0.0:*               LISTEN      19135/nc

real    0m0.471s
user    0m0.199s
sys     0m0.302s

上記のコマンドを使用してポートのステータスを確認するには、約0.5秒(0.471秒)かかりました。 コマンドオプションを少し調整して、実行時間を再評価してみましょう。

$ time (netstat -nl | grep ":8001")
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN

real    0m0.072s
user    0m0.039s
sys     0m0.041s
$

すごい! 実行時間を0.471秒から0.072秒に短縮することができます。 ここでは、-lオプションを使用して、LISTENモードのソケットのみを一覧表示しています。 以前のアプローチでは、netstatはすべてのソケットを一覧表示し、grepコマンドを使用してLISTENモードでソケットをフィルタリングしていました。これにより、追加のオーバーヘッドが発生しました。

また、対応するプロセスの PID を取得することはここではあまり価値がないため、コマンドから-pオプションを削除しました。

ネガティブなテストケースも検証しましょう。

$ time (netstat -ne | grep ":10001" ; echo $?)
1

real    0m0.088s
user    0m0.079s
sys     0m0.022s
$

ここで、予想どおり、 netstat は出力を提供せず、ポート 10001 は接続用に開いていないため、 $?もゼロ以外の値を保持します。 。

3. ss Commandの使用

ss は、ソケット統計をダンプするためのLinuxユーティリティです。 デフォルトの出力を見てみましょう。

$ ss | head -10
Netid  State  Recv-Q  Send-Q    Local Address:Port                 Peer Address:Port                                        Process
tcp    ESTAB  0       0             127.0.0.1:34702                   127.0.0.1:8684
tcp    ESTAB  0       0             127.0.0.1:5747                    127.0.0.1:55488
tcp    ESTAB  0       0             127.0.0.1:5161                    127.0.0.1:44858
tcp    ESTAB  0       0             127.0.0.1:8580                    127.0.0.1:42432
tcp    ESTAB  0       0             127.0.0.1:54090                   127.0.0.1:3852
tcp    ESTAB  0       0             127.0.0.1:8186                    127.0.0.1:52896
tcp    ESTAB  0       0             127.0.0.1:7367                    127.0.0.1:43282
tcp    ESTAB  0       0             127.0.0.1:4441                    127.0.0.1:35762
tcp    ESTAB  0       0             127.0.0.1:7024                    127.0.0.1:57206

ユーティリティの出力は、netstatの出力と同様であることに注意してください。 興味深いことに、このユーティリティの引数オプションもnetstatコマンドに似ています。 -lオプションを使用して出力を確認し、LISTENモードのソケットのみを一覧表示してみましょう。

$ time (ss -nl | grep ":8001")
tcp   LISTEN 0      1                     0.0.0.0:8001             0.0.0.0:*

real    0m0.029s
user    0m0.039s
sys     0m0.000s

このユーティリティは、 netstat。 このユーティリティを使用すると、 実行時間0.072秒と比較して、タイミングをさらに0.029秒に短縮することができました。

4. lsofコマンドの使用

lsofユーティリティを-iオプションとともに使用して、ポートが接続用に開いているかどうかを確認することもできます。

$ lsof -i:8001
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      19135 shubh    3u  IPv4 326527      0t0  TCP *:8001 (LISTEN)
nc      19135 shubh    4u  IPv4 326528      0t0  TCP localhost:8001->localhost:55368 (ESTABLISHED)
nc      19138 shubh    3u  IPv4 326555      0t0  TCP localhost:55368->localhost:8001 (ESTABLISHED)
$

LISTEN モードのみに関心があるので、コマンドにgrepフィルターを追加しましょう。

$ time (lsof -i:8001 | grep "LISTEN")
nc      19135 shubh    3u  IPv4 326527      0t0  TCP *:8001 (LISTEN)

real    0m0.625s
user    0m0.133s
sys     0m0.492s
$

特に、netstatまたはssユーティリティよりも関連情報の表示に時間がかかります。 ここでは、grepコマンドを使用して出力を明示的にフィルタリングしました。 また、組み込みのフラグ -iTCP -sTCP:LISTENを使用して、ネットワークファイルをLISTENモードで一覧表示してみましょう。

$ time (lsof -iTCP:8001 -sTCP:LISTEN)
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      19135 shubh    3u  IPv4 326527      0t0  TCP *:8001 (LISTEN)

real    0m0.496s
user    0m0.090s
sys     0m0.407s

実行時間を短縮することはできましたが、netstatおよびssユーティリティと比較するとかなり長い時間です。

5. 結論

この記事では、Linuxで接続用にポートが開いているかどうかをテストする方法について説明しました。

netstatツールを使用してソリューションについて説明することから始めました。 さらに、時間効率の高いソリューションを実現するために、さまざまなnetstatオプションについても検討しました。 次に、ssコマンドを使用してソリューションを確認しました。

最後に、lsofコマンドを使用してポートの状態をテストする手法を紹介しました。 ベンチマークから、ssユーティリティを最適なオプションとともに使用することがLinuxのポート状態をテストする効率的な方法であると結論付けることができます。