Mac でオープンポートを確認する方法:lsof、netstat、nc

lsof -i :3000、netstat、nc を使って Mac のオープンポートを確認する方法。ローカルポートのチェックとリモートホストのテストを、実際のコマンド出力例とともに解説。

rails server を実行したのに何も読み込まれない。またはリモートサーバーに接続しようとして何も返ってこない。最初の疑問は常に同じです:ポートは本当にオープンなのか?

Mac でのポート状態の確認はコマンド一つで済みます。コツは、自分の Mac を確認するのかリモートホストを確認するのかに応じて、どのコマンドを使うかを知ることです。

自分の Mac のオープンポートを確認する

これは開発者にとって最もよくあるケースです。開発サーバーがポート 3000 で動いているはずなのに、ブラウザは接続できないと言っている。そもそもポートはリッスンしているのでしょうか?

lsof -i :ポート番号(素早い答え)

lsof -i :3000

何かがリッスンしている場合、このような出力が表示されます:

COMMAND   PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby     8421  aaron  13u  IPv4 0x3f8a2b4c      0t0  TCP *:3000 (LISTEN)

出力が空の場合、そのポートには何もバインドされていません。Rails サーバーが動いていないか、別のポートで起動したかのどちらかです。

ポート 8080 の場合:

lsof -i :8080

ポート 80 の場合(特権ポートなので sudo が必要):

sudo lsof -i :80

lsof -i | grep LISTEN(すべてを一度に確認)

Mac が現在リッスンしているすべてのポートを確認するには:

lsof -i | grep LISTEN

出力にはオープンなリッスンポートを持つすべてのプロセスが表示されます:

ruby      8421  aaron  13u  IPv4  TCP *:3000 (LISTEN)
node      9102  aaron  21u  IPv6  TCP *:8080 (LISTEN)
postgres  1234  aaron   5u  IPv4  TCP localhost:5432 (LISTEN)

localhost:5432*:3000 の違いに注目してください。Postgres は同じマシンからの接続のみを受け付けています。Rails はネットワーク上のどこからでも接続を受け付けています。同じネットワーク上の別のデバイスから接続しようとしている場合、この区別が重要になります。

ホスト名の解決なしで数値ポートを表示したい場合(より高速):

lsof -i -n -P | grep LISTEN

netstat -an | grep LISTEN

netstat は別のフォーマットで同様のビューを提供します:

netstat -an | grep LISTEN

出力はこのようになります:

tcp4       0      0  *.3000                 *.*                    LISTEN
tcp4       0      0  127.0.0.1.5432         *.*                    LISTEN
tcp6       0      0  *.8080                 *.*                    LISTEN

ポート番号の前のアドレスがインターフェイスを示します。*.3000 はすべてのインターフェイス(ネットワークからアクセス可能)を意味します。127.0.0.1.5432 はローカルホストのみを意味します。

netstat はプロセス名なしのフラットなリストが欲しい場合に便利です。lsof はどのアプリがどのポートを所有しているかを知る必要がある場合により適しています。

結果の意味

LISTEN 出力に何か表示される場合:ポートはオープンでプロセスが所有しています。それでも接続できない場合、問題は別の場所にあります(ファイアウォール、間違った IP、認証など)。

lsof から出力がない / netstat に何も表示されない場合:そのポートには何もリッスンしていません。サービスが動いていないか、別のポートで起動しています。

出力に 127.0.0.1 または localhost が表示される場合:サービスはローカル接続のみを受け付けています。同じネットワーク上の別のマシンやスマートフォンからはアクセスできません。

リモートホストのポートを確認する

自分が管理していないサーバーのポートがオープンかどうかをテストする必要がある場合、lsof は使えません。代わりに実際に接続を試みて、何が起こるかを確認します。

nc -zv(適切なツール)

nc -zv hostname 443

ポートがオープンな場合:

Connection to hostname port 443 [https] succeeded!

クローズの場合(何もリッスンしていない):

nc: connectx to hostname port 80 (tcp) failed: Connection refused

フィルタリングされている場合(ファイアウォールがパケットをドロップ):

nc: connectx to hostname port 25 (tcp) failed: Operation timed out

「Connection refused」はサーバーには到達できるがそのポートには何もないことを意味します。「Timed out」はファイアウォールがパケットを到達前にドロップしている可能性が高いことを意味します。

実際の使用例:

# サーバーで HTTPS は動いているか?
nc -zv myserver.com 443

# このマシンで SSH はオープンか?
nc -zv 192.168.1.100 22

# このマシンからデータベースポートに到達できるか?
nc -zv db.internal 5432

複数のポートを一度に確認することもできます:

nc -zv hostname 80 443 8080

結果の解釈

結果 意味
Connection succeeded ポートはオープン、何かがリッスンしている
Connection refused ポートはクローズ、何もリッスンしていない
Operation timed out ファイアウォールが接続をブロックしている
Name or service not known ホスト名が解決できない(DNS の問題)

ポートは成功するのにサービスが動かない場合、問題はアプリケーション層にあります:間違った認証情報、プロトコルの不一致、アプリが接続を拒否しているなど。

よく確認するポート

デバッグ時によく登場するポートは以下のとおりです:

  • 22(SSH):SSH 接続できない?まずここを確認。
  • 80(HTTP)と 443(HTTPS):Web サーバーが応答しない。
  • 3000、3001、8000、8080:一般的な開発サーバーポート。Rails はデフォルトで 3000、多くの Node アプリは 8080 を使用。
  • 5432(PostgreSQL)、3306(MySQL)、27017(MongoDB):データベース接続の問題。
  • 25(SMTP):アプリがメールを送れない?ISP やクラウドプロバイダーによってよくブロックされます。

セキュリティ:Mac はどのポートを公開しているか?

セキュリティの観点から、lsof -i | grep LISTEN を時々実行することをお勧めします。リッスンしているポートはすべて潜在的な入口となります。ノートパソコンでは通常、オープンポートはできるだけ少ない方が望ましいです。

予期しないオープンポートの一般的な原因:

  • 起動したまま放置した開発サーバー(Rails、Node、Webpack)
  • ホストにポートをマッピングしている Docker
  • 有効になっているリモートデスクトップや画面共有
  • AirPlay レシーバー
  • バックグラウンドサービスを実行しているサードパーティアプリ

認識できないものがあれば、lsof 出力から PID を取得して確認します:

ps aux | grep <PID>

macOS ファイアウォールの使用

macOS ファイアウォールは外部からの Mac への接続を制御します。システム設定 > ネットワーク > ファイアウォール(またはバージョンによってはシステム設定 > プライバシーとセキュリティ > ファイアウォール)で確認できます。

ファイアウォールがオンの場合、明示的に許可していない限り、他のマシンは Mac 上のリッスンサービスに到達できません。Mac からの送信接続は引き続き可能です。

ローカルの開発サーバーがブラウザでは正常に表示されるのに、同じネットワーク上のスマートフォンからアクセスできない場合、ファイアウォールが原因である可能性が高いです。

GUI オプション:NetUtil のポートスキャナー

コマンドを入力したくない場合、NetUtil にはポートスキャナーが含まれています。ホスト名とポート範囲を入力すると、オープンなポートがテーブルに表示されます。macOS Monterey で削除される前の Apple の Network Utility のポートスキャナーの直接の後継です。

定期的なデバッグには、Terminal のコマンドを数回使えば習得できるので速いです。lsof -i :3000 は慣れれば数キーストロークで済みます。たまに確認する場合やリモートサーバーのポート範囲をスキャンしたい場合は、GUI ツールが時間を節約します。

クイックリファレンス

Mac が特定のポートでリッスンしているか確認:

lsof -i :3000

Mac がリッスンしているすべてのポートを表示:

lsof -i | grep LISTEN

netstat で同じことを確認:

netstat -an | grep LISTEN

リモートポートがオープンか確認:

nc -zv hostname 443

Mac でのポート状態はサービスが動いているかを示します。リモートホストでのポート状態はそのサービスに到達可能かを示します。二つの異なる問い、二つの異なるツールです。