SSD Nodes Learn 🎉 VPS $5.50/月〜
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-21

Linuxでポートが開いているか確認する方法

Linuxで本当に待ち受けているポートをssで確認し、外部からncやnmapで接続テストします。ブロックされたポートがハングし、閉じたポートが即座に拒否される違いも解説します。

Linux でポートが開いているか確認する: まず適切な問いを選ぶ

Linux でポートが開いているか確認する場合は、最初に何を確認したいのかを決めます。「開いている」の意味は、確認する場所によって異なるためです。サーバー上では、プロセスがそのポートにバインドされ、接続を待ち受けていることを意味します。別のマシンから確認する場合は、パケットがそのプロセスに到達し、応答が返ることを意味します。応答が返らない場合は、どのデバイスがパケットを破棄したのかが本当の問いになります。sudo ss -ltnp は最初の問いに答えます。nc -z または nmap は2番目の問いに答えます。ファイアウォールのカウンターと tcpdump は3番目の問いに答えます。

誤った確認方法を使うと、半日を費やすことになります。サーバー上で実行したテストは、プロバイダーのネットワークファイアウォールを通過しません。そのフィルターはサーバーの外側にあるためです。ポート番号にまだ慣れていない場合は、Linux でポートとソケットがどのように動作するかで、このガイドが前提とする仕組みを確認できます。

このマシンで待ち受けているものは何か: ss の出力を読む

ss は iproute2 に含まれているため、現在のすべてのディストリビューションに存在します。netstat は net-tools に含まれています。Ubuntu では何年も前から標準でインストールされていないため、netstat -tulpn では netstat: command not found が返ることがよくあります。ss を覚えて、失望しないようにしてください。

sudo ss -ltnp

-l は待ち受けソケットだけを表示します。-t は一覧を TCP に限定します。-n は名前解決を行わず、番号を表示するため、コマンドはすぐに返ります。-p は所有プロセスを表示します。このオプションには root 権限が必要です。sudo がない場合、自分が所有していないプロセスでは Process 列が空になります。UDP を確認するには -t-u に置き換えます。

State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
LISTEN 0      4096   127.0.0.53%lo:53    0.0.0.0:*   users:(("systemd-resolve",pid=612,fd=14))
LISTEN 0      128    0.0.0.0:22          0.0.0.0:*   users:(("sshd",pid=921,fd=3))
LISTEN 0      511    127.0.0.1:8080      0.0.0.0:*   users:(("node",pid=1442,fd=19))
LISTEN 0      128    [::]:22             [::]:*      users:(("sshd",pid=921,fd=4))

すべてを決めるのは Local Address 列です。この列は見落とされがちです。

  • 0.0.0.0:22 はマシン上のすべての IPv4 アドレスを意味します。そのため、ファイアウォールが許可していれば外部から到達できます。
  • [::]:22 は IPv6 について同じ意味です。
  • 127.0.0.1:8080 はループバックだけを意味します。このマシンの外部からは到達できません。
  • 10.20.0.5:5432 は、その 1 つのインターフェースアドレスだけを意味します。プライベートネットワーク構成でよく使われます。
  • Process 列が空の場合、通常はプロセスがないのではなく、sudo が不足しています。

特定のポートについて確認する場合は、一覧全体を grep するのではなく、ss の中で絞り込みます。

sudo ss -ltnp 'sport = :8080'
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser 8080/tcp

3 つすべての出力が空の場合、そのポートを使用しているものはありません。サービスが停止している、起動に失敗した、または別の場所で待ち受けている可能性があります。ファイアウォールルールを 1 つでも変更する前に、systemctl status <unit>journalctl -u <unit> -n 50 を確認してください。

Local Address の 127.0.0.1 で午後がつぶれる理由

127.0.0.1 にバインドされたソケットには、別のホストから接続できません。ファイアウォールルールを変更しても解決しません。カーネルは 127.0.0.0/8 をループバックインターフェースにだけルーティングします。そのため、その宛先アドレスを持つパケットが実際のネットワークカードに到着すると、martian パケットとして破棄されます。プロセスは動作し、ss では待ち受け中と表示され、ufw allow 8080 も成功を返します。それでも、ラップトップからの接続は失敗します。接続は即座に Connection refused で失敗します。パケットがパブリックアドレスに到達しても、そこにバインドされたソケットが見つからず、カーネルが TCP reset を返すためです。

多くのプログラムは意図的にループバックへバインドします。データベースや管理インターフェースでは、それが適切なデフォルトです。選択肢は2つあります。プログラム自身の設定でバインドアドレスを変更します(postgresql.conflisten_addressesredis.confbind、またはアプリケーションが受け取る host 引数)。その後、ファイアウォールを開きます。もう1つは、ループバックでの待ち受けを維持し、nginx のリバースプロキシや、ラップトップからの SSH トンネルなど、別の手段でアクセスする方法です。

ssh -L 8080:127.0.0.1:8080 user@203.0.113.10

Docker の publish フラグにも同じ違いがあります。-p 8080:80800.0.0.0 にバインドし、コンテナをインターネットに公開します。-p 127.0.0.1:8080:8080 はループバックにバインドし、ローカルだけで利用できるようにします。

Linux で別のマシンからポートが開いているか確認する方法

別のネットワークからこのテストを実行します。サーバー上からのテストで確認できるのは、loopback 経路が機能していることだけです。サーバー自身から自分の public IP に接続しても、プロバイダーのネットワークファイアウォールは経由しません。このフィルターは VPS の外側で動作するためです。

nc -zv -w 3 203.0.113.10 443

-z はデータを送信せずに接続して終了します。-w 3 は 3 秒で諦めます。この flag は重要です。timeout を指定しない場合、パケットが破棄されると、kernel が停止するまで client は 2 分以上 SYN の再送を続けます。成功時の表示は次のようになります。

Connection to 203.0.113.10 443 port [tcp/https] succeeded!

ツールがない場合(nc: command not found)は、Debian または Ubuntu に netcat-openbsd をインストールします。または、パッケージを必要としない bash 組み込みのネットワークリダイレクトを使用します。

timeout 3 bash -c '</dev/tcp/203.0.113.10/443' && echo open || echo "no answer"

この構文は bash の機能なので、bash で実行します。Debian と Ubuntu の /bin/sh は dash です。dash には /dev/tcp がないため、パスが存在しないというエラーが表示されます。複数のポートを範囲指定する場合や、状態を名前付きで確認する場合は、自分が管理するホストに対して nmap を使用します。

sudo nmap -Pn -p 22,80,443 203.0.113.10
sudo nmap -Pn -p 1-1024 203.0.113.10

-Pn はホスト検出を無効にします。多くの VPS ホストは ICMP echo を破棄するため、-Pn がないと nmap はホストが停止していると判断し、何もスキャンしません。nmap は、応答があり接続を受け入れた場合に open、応答があり reset が返された場合に closed、まったく応答がない場合に filtered を表示します。Web サービスでは、curl -sS -o /dev/null -w '%{http_code}\n' https://example.com によりネットワーク障害とアプリケーション障害を切り分けられます。status code が返ることは、経路全体が機能したことを示すためです。

ブロックされたポートで接続がハングし、閉じたポートですぐに拒否される理由

即座に拒否される場合。 パケットはマシンに到達し、何らかの応答が返っています。

nc: connect to 203.0.113.10 port 443 (tcp) failed: Connection refused

この結果は、2 つの異なる原因で発生します。1 つは、そのアドレスとポートにバインドされたプロセスが存在しないため、カーネルが TCP reset を返した場合です。もう 1 つは、ファイアウォールルールが reset または ICMP port unreachable メッセージを返してパケットを拒否した場合です。拒否は明確な応答であり、1 回の round trip で返ります。

一時停止してからタイムアウトする場合。 何かがパケットを破棄し、応答を返していません。

nc: connect to 203.0.113.10 port 443 (tcp) timed out: Operation now in progress

これは DROP ルールの動作です。プロバイダーのファイアウォールやクラウドのセキュリティグループも同じ動作をします。送信元からは、パケットの破棄とホスト停止を区別できません。そのため、無応答は破棄の特徴になります。

この症状から、次に確認すべき場所が分かります。拒否された場合はパケットがネットワークを正常に通過しているため、ss -ltnp に戻り、バインドアドレスとポート番号を確認します。タイムアウトする場合はパケットが破棄されているため、外側から内側へ順にファイアウォールを確認します。SSH で拒否とタイムアウトを区別する方法では、port 22 を例にこの違いを詳しく説明しています。多くの人がこの問題に遭遇するのは port 22 です。

ufw は意図的に両方の動作を提供します。ufw deny 8080 は破棄し、ufw reject 8080 は拒否応答を送信します。nftables では 2 つの target が dropreject であり、iptables では -j DROP-j REJECT です。デフォルトポリシーはほぼ常に破棄に設定されます。そのため、ルールが ない 場合はエラーメッセージではなく接続のハングが発生します。

ポートをブロックしているのは誰か。外側から内側へ確認する

sudo ufw status verbose
sudo iptables -L INPUT -n -v --line-numbers
sudo nft list ruleset

-v のカウンターが重要です。外部から nc テストを実行し、iptables コマンドをもう一度実行して、増加したカウンターを探します。パケット数が増えたルールが、対象のトラフィックを処理しているルールです。これにより、推測ではなく証拠に基づいて判断できます。

決定的なテストは、外部から接続しながらサーバー上でネットワーク上のパケットを監視して実行します。

sudo tcpdump -ni any tcp port 8080

SYN が到着しているのに SYN-ACK が返っていない場合、パケットは VPS に到達し、ホストで破棄されています。つまり、プロバイダーのファイアウォールは正常で、ローカルのルールに問題があります。出力がまったくない場合、パケットは到着していません。原因は、プロバイダーのファイアウォール、セキュリティグループ、または誤った IP アドレスです。この区別だけで、調査の大部分を省けます。

結果が不可能に見える原因になる層が2つあります。1つ目は IPv6 です。ホスト名に AAAA レコードがある場合、クライアントは IPv6 で接続する可能性があります。一方、ルールが IPv4 だけを対象にしていることがあります。そのため、どちらかの結果を信頼する前に、nc -4nc -6 で各アドレスファミリーをテストしてください。ufw のルールと VPS の IPv6 ポート では、この不一致を説明しています。2つ目は Docker です。ufw status でポートが拒否されていると表示されても、公開されたコンテナポートはインターネットからの接続に応答します。これらのパケットは、ufw のチェーンが処理する前に処理されるためです。Docker が ufw を通過してポートを直接公開する理由 では、その仕組みと修正方法を説明しています。新しい VPS に設定すべき ufw のルール は、最初に用意しておくべき基本セットです。

UDP の応答が設計上あいまいになる理由

UDP にはハンドシェイクがないため、プローブには成功を判定できる対象がありません。nc -zu 203.0.113.10 53 はパケットが送信元を離れるとすぐに 0 で終了します。これは自ホストがパケットを送信したことしか示さず、相手側については何も示しません。UDP ポートが閉じている場合、通常はホストが ICMP port unreachable メッセージを返します。カーネルは、このエラーを接続済みソケットに対して次回の書き込み時に報告するため、1 回だけパケットを送るプローブでは検出できません。ファイアウォールは慣例的に ICMP を破棄するため、その手掛かりすら失われます。このため、nmap はほとんどの UDP ポートに対して open|filtered と表示します。応答がない状態は、応答を返さない open サービスと filtered ポートの両方で発生するためです。

確認したいプロトコルを実際に使用して、UDP をテストします。DNS サーバーは dig +short @203.0.113.10 example.com に対してアドレスを返すか、何も返しません。WireGuard peer では、sudo wg show に最近の latest handshake 行が表示されます。次に、サーバー側で到着を確認します。

sudo tcpdump -ni any udp port 51820

クライアントの送信中にパケットが表示される場合、パケットは到着しています。その場合は、サービスまたは input chain に問題があります。パケットがまったく表示されない場合、パケットはサーバーまで到達していません。

最短で障害箇所を特定できる順序のチェックリスト

  1. サーバー上で sudo ss -ltnp 'sport = :8080' を実行します。出力がない場合、待ち受けているプロセスはありません。まずサービスを修正します。
  2. 出力がある場合は、Local Address 列を確認します。127.0.0.1 では、再バインドするか前段にプロキシを配置するまで外部から接続できません。
  3. 別のネットワークから nc -zv -w 3 <public ip> 8080 を実行します。
  4. 接続拒否の場合は、手順 1 に戻ります。アドレス、ポート、または対象のマシンが想定と異なります。
  5. タイムアウトの場合は、パケットが破棄されています。サーバー上で sudo tcpdump -ni any tcp port 8080 を開始し、テストを再実行します。
  6. SYN は到着するものの応答がない場合は、ホストのファイアウォールが原因です。sudo iptables -L INPUT -n -v でカウンターが増加するルールを特定します。
  7. SYN が到着しない場合は、プロバイダーのファイアウォール、セキュリティグループ、または誤った IP アドレスが原因です。

FAQ

自分の Linux サーバーで、開いているポートを確認するにはどうすればよいですか?

TCP には sudo ss -ltnp、UDP には sudo ss -lunp を実行します。各行は 1 つの待ち受けソケットを示します。Local Address 列では、接続元の範囲を確認できます。0.0.0.0[::] はファイアウォールで許可されているすべての接続元を受け入れ、127.0.0.1 は同じマシンからの接続だけを受け入れます。Process 列の表示には root 権限が必要です。そのため sudo を付けて実行しないと、列が空になります。ss は iproute2 の一部で、常にインストールされています。netstat は net-tools の一部で、通常はインストールされていません。

ss ではサービスが待ち受け中なのに、接続できないのはなぜですか?

主な原因は 2 つあります。1 つのコマンドで切り分けられます。Local Address が 127.0.0.1 の場合、サービスは loopback にバインドされています。そのため、他のホストからは接続できません。カーネルがその範囲を loopback インターフェースにだけルーティングするためです。0.0.0.0 なのに接続できない場合は、サーバーで sudo tcpdump -ni any tcp port <port> を実行し、外部から接続します。SYN が到着しても応答がない場合は、ローカルのファイアウォールルールがパケットを破棄しています。何も到着しない場合は、VPS に到達する前にパケットが停止しています。通常はプロバイダーのファイアウォールまたはセキュリティグループが原因です。

接続が拒否される場合とタイムアウトする場合の違いは何ですか?

拒否は応答です。パケットはホストに到達し、TCP reset または ICMP port unreachable が返されています。これは、そのアドレスとポートで待ち受けているものがないか、ルールによって拒否されたことを示します。タイムアウトは無応答です。ルールがパケットを破棄して何も返さないため、クライアントは諦めるまで再試行します。拒否された場合は、サービスとバインドアドレスを確認します。タイムアウトした場合は、ファイアウォールを確認します。最初に、外部に最も近いファイアウォールを調べてください。

UDP ポートが開いているかどうかを確認するにはどうすればよいですか?

一般的なプローブで確実に判定することはできません。UDP にはハンドシェイクがなく、無応答のサービスと破棄されたパケットを区別できないためです。nc -zu は送信するとすぐに成功を返します。nmap が同じ理由で open|filtered と報告する場合もあります。代わりに、プロトコルを実際に使用してテストします。DNS には dig +short @<host> example.com、WireGuard peer には、最近のハンドシェイクを確認できる sudo wg show を使います。パケットの到着を証明するには、クライアントが送信している間にサーバーで sudo tcpdump -ni any udp port <port> を実行します。

telnet host port でポートをテストできますか?

TCP では使用できます。Escape character is '^]' は接続が受け入れられたことを示します。Ctrl+] で終了し、その後 quit を実行します。ただし、nc -z のほうが適しています。現在のサーバーイメージの多くには telnet がインストールされていません。また、nc-w でタイムアウトを指定でき、スクリプトで確認できる終了ステータスも設定します。どちらも利用できない場合は、パッケージの追加なしで timeout 3 bash -c '</dev/tcp/<host>/<port>' を使えます。