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