SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

Linuxのポートとlistenをssで確認する方法

ポートが通信をサービスへ振り分ける仕組みを解説します。ssで待ち受け中のサービスを確認し、ローカルポートと公開ポートの違いも理解できます。

ポートとは何か

ポートは、1 台のサーバーで複数のサービスを同時に実行し、ネットワークトラフィックが混ざらないようにする番号です。VPS には 1 つの IP アドレスしかなくても、Web サーバー、SSH サーバー、データベースを同時に実行できます。パケットが到着すると、オペレーティングシステムは、どのサービス宛てなのかを判断する必要があります。その答えがポート番号です。HTTPS のトラフィックは通常 port 443、SSH は port 22 に送られます。IP アドレスがパケットをサーバーまで届け、ポートがそのサーバー上の適切なプログラムまで届けます。

ポートは 16-bit の番号です。16-bit では 0 から 65535 までを表せますが、0 は予約されているため、実際に使用するポートは 1 から 65535 です。1024 未満のポートは「well-known」ポートと呼ばれ、デフォルトでは Linux は root、または CAP_NET_BIND_SERVICE capability を付与されたプログラムだけが開けます。そのため、標準サービスはここで待ち受けます。SSH は 22、HTTP は 80、HTTPS は 443、DNS は 53 です。net.ipv4.ip_unprivileged_port_start sysctl でこの境界値を変更できますが、デフォルトは 1024 です。1024 以上は通常のプログラムも自由に使用できます。

ポートには TCP と UDP の 2 種類があり、一方のポート番号は、もう一方の同じ番号とは別のものです。TCP は接続指向のプロトコルで、SSH、HTTP、データベースなど、ほとんどのサービスが使用します。UDP はコネクションレスで、DNS や一部の VPN などに使用されます。ファイアウォールでポートを開くときは、通常どちらのプロトコルかを指定します。たとえば 22/tcp です。

「listen」はプログラムがポートで接続を待ち受けることを意味します

接続を受け付けるプログラムは、カーネルにポートを「listen」するよう要求します。その時点で、そのポートはマシン上で開かれ、ファイアウォールの制限範囲内で、そこに到達した接続にプログラムが応答します。待ち受けているプログラムがないポートは、接続を拒否します。そのため、セキュリティ確認で最初に確認するのは、何がどこで待ち受けているかです。

これを確認するコマンドは ss です。

sudo ss -tlnp

各フラグは、TCP(t)、待ち受けソケットのみ(l)、ポート番号の数値表示(n。そのため ssh ではなく 22 と表示されます)、および所有プロセス(p)を指定します。一般的な結果は次のとおりです。

State   Recv-Q  Local Address:Port   Process
LISTEN  0       0.0.0.0:22           sshd
LISTEN  0       127.0.0.1:5432       postgres
LISTEN  0       [::]:80              nginx

Process 列には各ポートを所有するプログラムが表示されます。これにより、意図せず起動したままにしていたプログラムを特定できます。

重要なのは Local Address 列です

各ポートの前に表示されるアドレスを注意して確認してください。どのクライアントがサービスに接続できるかは、このアドレスで決まります。頻繁に目にするケースは 3 つあります。

0.0.0.0:22 は「このマシンが持つすべての IPv4 アドレスで待ち受ける」という意味です。パブリックアドレスも含まれます。ファイアウォールが許可していれば、サービスは IPv4 経由でインターネットから到達可能です。

[::]:80 は IPv6 でも同じ意味です。パブリックアドレスを含む、すべての IPv6 アドレスで待ち受けます。多くのプログラムはデフォルトでここに bind し、Linux では :: socket が IPv4 も受け付けることがあります。

127.0.0.1:5432 は「loopback のみで待ち受ける」という意味です。127.0.0.1 はマシンが自分自身と通信するために使用するアドレスで、kernel のデフォルト設定では他の場所から routing できません。ここに bind したサービスは、ファイアウォールがそのポートを許可していても、同じサーバーからしか到達できません。前述の Postgres の行は、デフォルトでは安全です。例外は route_localnet という kernel 設定です。これはデフォルトでは無効ですが、一部のツールが有効にします(Kubernetes の kube-proxy がその一例です)。この設定が有効で、適切な routing または NAT ルールがあると、loopback のトラフィックが外部から到達する可能性があります。すべての行で sysctl -a | grep route_localnet は = 0 になっている必要があります。

ここから実用上のルールが導けます。自分のアプリケーションだけが使用するデータベース、キャッシュ、管理パネルは、127.0.0.1 に bind し、0.0.0.0 には bind しないでください。パブリックアドレスで待ち受けなければ、攻撃者が到達できる対象はありません。

待ち受けていることと到達可能であることは別です

混乱を避けるために、もう 1 つ区別しておきます。マシン上でポートが開いている、つまりプログラムが待ち受けていることと、外部からそのポートに到達できる、つまりファイアウォールが許可していることは別です。リモートクライアントが接続するには、両方が成立している必要があります。2 つの失敗はクライアント側で異なる形で現れます。接続が拒否される場合は、通常、待ち受けているプログラムがありません。一方、接続が停止してから timeout する場合は、通常、ファイアウォールがパケットを破棄しています。これは、2 つの SSH エラーが示している内容そのものです。

つまり、制御する層は 2 つあります。各サービスの bind address を設定して、何が待ち受けるかを決めます。そして、ファイアウォールで外部から何に到達できるかを決めます。適切に運用されたサーバーは、両方を使用します。サービスは必要な場所でのみ待ち受け、ファイアウォールは明示的に許可していない通信をすべて拒否します。ss で待ち受けている内容を確認することが最初の手順です。次に、ファイアウォールが許可する内容を決めます。詳しくは UFW を使ったファイアウォールの基本で説明します。

ここには見落としやすい点があります。IPv4 と IPv6 は別のものです。IPv4 だけを対象にしたファイアウォールでは、[::] サービスが IPv6 上で公開されたままになります。この問題については、IPv6 ファイアウォールの落とし穴で詳しく説明しています。

FAQ

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

TCP には sudo ss -tlnp、UDP には sudo ss -ulnp を実行します。これにより、すべての listening socket、ポート、bind されている local address、所有しているプロセスが一覧表示されます。Local Address 列を確認してください。0.0.0.0 または [::] はサービスがネットワークに公開されていることを示し、127.0.0.1 はマシン自身でのみ待ち受けていることを示します。

0.0.0.0 と 127.0.0.1 の違いは何ですか?

0.0.0.0 は「パブリックアドレスを含む、すべての IPv4 アドレスで待ち受ける」という意味です。そのため、サービスはネットワークから到達可能です。127.0.0.1 は loopback です。マシンが自分自身と通信するために使用するアドレスで、kernel のデフォルト設定では他の場所から routing できません。そのため、ここに bind したサービスはローカルからのみ到達できます。内部サービスは 127.0.0.1 に bind して、ネットワークに公開されないようにしてください。

サービスを動作させるには、ファイアウォールでポートを開く必要がありますか?

他のマシンから到達する必要があるサービスに限り、必要です。127.0.0.1 に bind したサービスには allow rule は不要です。kernel のデフォルト設定では、外部から到達できないためです。0.0.0.0 または [::] で動作するサービスには、ファイアウォールが incoming traffic をデフォルトで拒否する設定になっていれば、allow rule が必要です。ファイアウォールが有効でない場合、または policy がすべての通信を許可している場合、そのサービスは rule がなくてもすでに到達可能です。

TCP ポートと UDP ポートの違いは何ですか?

TCP は接続指向で、SSH、Web サーバー、データベースなど、ほとんどのサービスが使用します。UDP はコネクションレスで、DNS や一部の VPN に使用されます。TCP と UDP で同じ番号を使用していても、それぞれ別のポートです。そのため、53/tcp と 53/udp は異なります。ファイアウォールルールを記述するときは、プロトコルを指定します。たとえば 22/tcp です。