ss コマンド: Linux のポートとプロセスの確認、netstat との比較
Linux サーバーでどのポートが開いていて誰が接続しているかは、ss コマンドで確認します。ss は netstat に代わる iproute2 のソケット確認ツールです。Debian 12 サーバーで ss を使って待ち受け (LISTEN) 中のポートと接続を調べたところ、一般アカウントでは -p を付けても、ほかのアカウントが起動したプログラムの名前が Process 欄に表示されないことを確認しました。
以下の出力は英語の locale で実行した結果です。サーバーと相手のアドレスは例示用のアドレスで表記しています。
1️⃣ ss コマンドの基本的な使い方と出力の欄
オプションなしで ss を実行すると、待ち受け中のポートは除かれ、接続が確立したソケットだけが表示されます。テストサーバーでは、先頭の行はすべてサーバー内のプログラム同士が使う Unix ソケット (u_str、u_dgr) でした。
ss | head -n 5Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
u_str ESTAB 0 0 * 1013903 * 1013904
u_dgr ESTAB 0 0 * 1013960 * 13394
u_str ESTAB 0 0 * 1013907 * 1013908
u_str ESTAB 0 0 * 46066198 * 46066199そこで TCP の接続だけを見るには -t を付けます。Unix ソケットが除かれ、ポートの位置には番号の代わりに ssh や https のようなサービス名が表示されます。
ss -tState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 203.0.113.10:ssh 198.51.100.7:51114
ESTAB 0 0 203.0.113.10:26676 192.0.2.15:https
ESTAB 0 0 203.0.113.10:29714 192.0.2.16:https-n も一緒に付けると、サービス名に置き換えずにポート番号がそのまま表示されます。
ss -tnState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 203.0.113.10:22 198.51.100.7:51114
ESTAB 0 0 203.0.113.10:26676 192.0.2.15:443
ESTAB 0 0 203.0.113.10:29714 192.0.2.16:443Recv-Q と Send-Q は同じ欄でも、ソケットの状態によって意味する値が異なります。接続中のソケットでは、Recv-Q は受信したもののプログラムがまだ読んでいないバイト数で、Send-Q は送信したものの相手がまだ受信を確認していないバイト数です。
待ち受けソケットでは、Recv-Q はキューにたまった接続の数、Send-Q はキューの最大サイズを意味します。この二つの欄の意味は net-tools の netstat(8) man ページの説明です。
2️⃣ Linux のポート確認 (-tln、-uln、-tulpn)
オプションなしの出力には接続を待っているポートが表示されないため、開いているポートを確認するときは待ち受けソケットだけを選ぶ -l を付けます。[ss -tln] は待ち受け中の TCP ポートを番号で出力します。
ss -tlnState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 511 [::]:443 [::]:*Local Address が 0.0.0.0 ならサーバーのすべての IPv4 アドレスに来る接続を受け付け、127.0.0.1 ならサーバー内からしか接続できません。[::] は IPv6 のすべてのアドレスを意味するため、22 番、80 番、443 番ポートは IPv4 と IPv6 の両方で開いています。
-n を外すと、ポート番号がサービス名に変わります。8080 番は http-alt と表示されます。
ss -tlState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:ssh 0.0.0.0:*
LISTEN 0 511 0.0.0.0:http 0.0.0.0:*
LISTEN 0 511 0.0.0.0:https 0.0.0.0:*
LISTEN 0 511 127.0.0.1:http-alt 0.0.0.0:*
LISTEN 0 128 [::]:ssh [::]:*
LISTEN 0 511 [::]:http [::]:*
LISTEN 0 511 [::]:https [::]:*UDP は接続を確立しない方式のため、待ち受けソケットにも LISTEN 状態がありません。[ss -uln] の出力の状態欄はすべて UNCONN でした。68 番 (bootpc) は DHCP クライアント、123 番 (ntp) は時刻同期のポートです。
ss -ulnState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
UNCONN 0 0 203.0.113.10:123 0.0.0.0:*
UNCONN 0 0 127.0.0.1:123 0.0.0.0:*
UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
UNCONN 0 0 [::1]:123 [::]:*
UNCONN 0 0 [::]:123 [::]:*TCP と UDP を一度に見るには、[ss -tulpn] のようにオプションをまとめて付けます。種類が二つ以上になると、先頭に Netid 欄が付きます。
ss -tulpnNetid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
udp UNCONN 0 0 203.0.113.10:123 0.0.0.0:*
udp UNCONN 0 0 127.0.0.1:123 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
udp UNCONN 0 0 [::1]:123 [::]:*
udp UNCONN 0 0 [::]:123 [::]:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
tcp LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:*
tcp LISTEN 0 511 [::]:80 [::]:*
tcp LISTEN 0 511 [::]:443 [::]:*3️⃣ ss コマンドでプロセスを確認 (-p)
-p はソケットを使っているプログラムを Process 欄に出力するオプションです。ところが、テストサーバーの一般アカウントで [ss -tlnp] を実行すると、下のように Process 欄が空になり、オプションが効いていないように見えました。
ss -tlnpState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 511 [::]:443 [::]:*ss はプロセスごとに /proc の下の fd フォルダーを読んで、ソケットを使っているプロセスを探します。ほかのアカウントが起動したプロセスの fd フォルダーは一般アカウントでは開けないため、そのプログラムの名前は欄に入りません。root が起動した 1 番プロセスのフォルダーを一般アカウントで開くと、権限エラーになります。
ls /proc/1/fdls: cannot open directory '/proc/1/fd': Permission denied自分のアカウントで起動したプログラムは、一般アカウントでも Process 欄に表示されます。python3 の簡易 Web サーバーを 127.0.0.1 の 8000 番ポートで起動して確認しました。
python3 -m http.server 8000 --bind 127.0.0.1 &起動したら、[sport = :8000] を付けて 8000 番ポートの行だけを表示します。
ss -tlnp sport = :8000State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 5 127.0.0.1:8000 0.0.0.0:* users:(("python3",pid=343015,fd=3))users の後ろの括弧には、プログラム名、pid、ファイルディスクリプター番号 (fd) が順に入ります。
確認が終わった簡易 Web サーバーは [kill %1] で止めます。止めたあとに [ss -tln sport = :8000] をもう一度実行すると、見出し行だけが残り、8000 番の行は表示されません。
root アカウントで実行すると、すべてのプロセスの情報を読めるため Process 欄が埋まります。一つのポートで複数のプロセスが一緒に待ち受けている場合は、その数だけ users の括弧の中に項目が続きます。下の root の出力のプログラム名と pid は例示用の値です。
ss -tlnp sport = :443State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("app",pid=2101,fd=6),("app",pid=2100,fd=6))
LISTEN 0 511 [::]:443 [::]:* users:(("app",pid=2101,fd=7),("app",pid=2100,fd=7))ポート番号からプログラムを探すときは、 lsof コマンドの [lsof -i :443] の形も使えます。
アカウントによって Process 欄がどう変わるかは、下の図でアカウントを切り替えながら比べられます。
4️⃣ ss の状態とポートのフィルターオプション
開いているポートを確認したあとも、いまそのポートに誰が接続しているかは別に絞り込む必要があります。ss はオプションの後ろにフィルター条件を付けて、必要な行だけを残します。
state の後ろに状態名を書くと、その状態のソケットだけが残ります。[ss -tn state established] の出力は State 欄がなく、Recv-Q 欄から始まります。
ss -tn state establishedRecv-Q Send-Q Local Address:Port Peer Address:Port Process
0 0 203.0.113.10:22 198.51.100.7:51114
0 0 203.0.113.10:26676 192.0.2.15:443
0 0 203.0.113.10:29714 192.0.2.16:443ポートは dport (相手側のポート) と sport (自分側のポート) で絞り込みます。サーバーから外部の https サーバーへ出ていった接続は [dport = :443] で選びます。
ss -tn dport = :443State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
ESTAB 0 0 203.0.113.10:26676 192.0.2.15:443
ESTAB 0 0 203.0.113.10:29714 192.0.2.16:443sport を -l と一緒に使うと、そのポートが待ち受け中かどうかだけを確認できます。
ss -tln sport = :22State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*複数の条件は括弧と or でまとめ、シェルが括弧を先に解釈しないようにシングルクォートで囲みます。下は man ページの例にならって ssh の接続だけを選んだ結果です。
ss -tn state established '( dport = :ssh or sport = :ssh )'Recv-Q Send-Q Local Address:Port Peer Address:Port Process
0 0 203.0.113.10:22 198.51.100.7:51114TIME-WAIT は接続が切れたあとしばらく残っている状態です。既定の出力には表示されないため、[state time-wait] で別に選ばないと見えません。
ss -tn state time-waitRecv-Q Send-Q Local Address:Port Peer Address:PortProcess
0 0 127.0.0.1:28750 127.0.0.1:80
0 0 127.0.0.1:57698 127.0.0.1:8080
0 0 [::1]:31936 [::1]:80状態名を間違えると、[wrong state name] のエラーを 1 行だけ残してコマンドがすぐに終わります。下はわざと foo を入れた結果です。使える名前は [ss -h] の出力の TCP-STATES の行で確認できます。
ss -tn state fooss: wrong state name: foo📌 主なオプション: この記事で実行した結果
| オプション | 作業 | この記事で確認した結果 | |
|---|---|---|---|
| -t | TCP ソケットだけを出力 | Unix ソケットが除かれ、ポートの位置に ssh や https のようなサービス名が表示される | |
| -n | サービス名に置き換えずポート番号で出力 | ss -tn では ssh が 22、https が 443 と表示される | |
| -l | 待ち受け (LISTEN) ソケットだけを出力 | ss -tln に 22 番、80 番、443 番などの待ち受けポートが表示される | |
| -u | UDP ソケットだけを出力 | ss -uln の状態欄がすべて UNCONN | |
| -p | ソケットを使っているプログラムを Process 欄に出力 | 一般アカウントでは自分のアカウントが起動した python3 だけ名前と pid が表示され、ほかのアカウントのプログラムは空欄 | |
| -s | ソケットの一覧の代わりに種類ごとの数を集計 | TCP の行の estab 9 が、state established の出力から見出し行を除いた 9 行と一致 | |
| -4 | IPv4 ソケットだけを出力 | ss -t4ln では [::] で始まる行が除かれる | |
| -6 | IPv6 ソケットだけを出力 | ss -t6ln では 0.0.0.0 と 127.0.0.1 で始まる行が除かれる | |
| -H | 見出し行なしでソケットの行だけを出力 | ss -H -tln | wc -l の行数に見出し行が数えられない | |
| state 状態 | その状態のソケットだけを残す | state established の出力は State 欄なしで Recv-Q から始まり、存在しない名前は [wrong state name: foo] | |
| dport = :ポート | 相手側のポートで絞り込む | dport = :443 で外部の https サーバーへ出ていった接続が 2 行 | |
| sport = :ポート | 自分側のポートで絞り込む | -l と一緒に使った sport = :22 で IPv4 と IPv6 の 22 番の待ち受けが 2 行 | |
| src アドレス | そのアドレスのソケットだけを残す | ss -tln src 127.0.0.1 で、サーバー内からの接続だけを受け付ける 127.0.0.1 側のポートだけが表示される |
📎 その他のオプション: 公式マニュアルより
| オプション | 作業 | |
|---|---|---|
| -a, --all | 待ち受けソケットと接続中のソケットを一緒に出力 | |
| -r, --resolve | アドレスとポート番号を名前に解決して出力 | |
| -e, --extended | ソケットごとに uid や inode などの詳しい情報を出力 | |
| -o, --options | TCP の再送や keepalive などのタイマー情報を出力 | |
| -m, --memory | ソケットが使っているメモリを出力 | |
| -i, --info | TCP の内部情報 (rtt、cwnd など) を出力 | |
| -x, --unix | Unix ドメインソケットだけを出力 | |
| -w, --raw | RAW ソケットだけを出力 | |
| -f 種類 | unix、inet、inet6、link、netlink などのソケットの種類で選ぶ | |
| -Q, --no-queues | Recv-Q と Send-Q の欄を除いて出力 | |
| -K, --kill | フィルターに合うソケットを強制的に閉じる。カーネルが対応していないソケットは飛ばす | |
| -E, --events | 閉じられるソケットを出力し続ける | |
| -V, --version | バージョン情報を出力 |
🔲 ss コマンドシミュレーター
下のシミュレーターでは、ここまで出てきたオプションとフィルターを実際に入力し、[netstat -tln] と出力を比べられます。
5️⃣ ss のソケット集計 (-s)
-s はソケットの一覧の代わりに、種類ごとの数を集計して出力します。man ページによると、一覧を一つずつ数えるのではなく、さまざまな統計情報から数を集めます。
ss -sTotal: 340
TCP: 48 (estab 9, closed 15, orphaned 0, timewait 13)
Transport Total IP IPv6
RAW 0 0 0
UDP 8 4 4
TCP 33 25 8
INET 41 29 12
FRAG 0 0 0TCP の行の estab は、いま確立している接続の数です。そのため、同じ時点に [state established] で出力した行数と照らし合わせられます。
ss -tn state established | wc -l10出力 10 行から見出し行 1 行を除くと 9 行で、-s の estab 9 と同じでした。timewait 13 は、[state time-wait] で選んだときにだけ見えていた TIME-WAIT ソケットの数です。
6️⃣ ss コマンドと netstat の比較
netstatが入っている net-tools パッケージの man ページは、netstat をほとんど使われなくなったプログラム (mostly obsolete) と書き、代わりに ss を使うよう案内しています。ただし、netstat の出力形式に合わせて作ったスクリプトは、ss に替えると欄の順序とアドレスの表記が違うため、そのままでは読めません。
同じサーバーで待ち受け中の TCP ポートを二つのコマンドで出力すると、netstat は状態がいちばん後ろに来て、IPv6 アドレスを :::22 のように書きました。
netstat -tlnActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::80 :::* LISTEN
tcp6 0 0 :::443 :::* LISTENss では状態がいちばん前に来て、IPv6 アドレスを [::]:22 のように角括弧で囲みます。
ss -tlnState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 511 [::]:443 [::]:*よく使う netstat のオプションを ss と ip コマンドに置き換えると、次のとおりです。
| netstat | 代わりのコマンド / 確認できるもの |
|---|---|
| netstat -tln | ss -tln待ち受け中の TCP ポートを番号で |
| netstat -tulpn | ss -tulpn待ち受け中の TCP・UDP ポートとプログラム |
| netstat -tan | ss -tanすべての TCP ソケットを番号で |
| netstat -r | ip routeルーティングテーブル |
| netstat -i | ip -s linkネットワークインターフェースの統計 |
🔢 FAQ & おすすめコンテンツ









ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。
