netstat vs ss: Linuxにおけるネットワーク接続とポートリスニングの徹底解析

Network tutorial - IT technology blog
Network tutorial - IT technology blog

サーバー管理を始めた頃、誰かがnetstatを使っているのを見ては何も考えずに真似していました。古いチュートリアルで身についた習慣で、疑問を持つこともありませんでした。数千のソケットが開いている本番サーバーで遅い接続をデバッグする必要が出てくるまでは——netstatの実行に30秒以上かかってようやく結果が出てきました。その日初めて、ssについて本腰を入れて調べました。

私は50人が働くオフィスと小規模なデータセンターのネットワークを管理しています——この記事は、netstatからssへ約6ヶ月かけて段階的に移行し、状況に応じて両方を使い分けることを学んだ実体験をまとめたものです。

netstat vs ss: 2つのツール、1つの目的

どちらもネットワーク接続の状態、リスニングポート、アクティブなソケットを表示します。しかし内部の動作は全く異なります。

netstatnet-toolsパッケージに含まれており、/proc/net/から従来の方法で情報を読み取ります。Ubuntu 20.04+およびDebian 11+では、もはやデフォルトでインストールされていません——必要な場合は手動でインストールする必要があります。

ss(socket statistics)はiproute2パッケージに含まれており、netlinkソケット経由でカーネルと直接通信します。これが多数の接続が開いている場合に明らかに速い理由です——/proc内のテキストファイルを解析する代わりに、カーネルから直接データを取得します。

各ツールの長所と短所を分析

netstat: 使い慣れているが時代遅れ

長所:

  • Googleなしで構文を覚えられる;2012年のStackOverflowチュートリアルでも正常に動作する
  • 初心者でも読みやすい出力——列が明確で、ほとんど説明不要
  • ルーティングテーブルとインターフェース統計を同じツールで確認できる(ip routeの方が優れているが)

短所:

  • 接続数が多いと遅い——/proc/net/tcpをテキスト形式で解析するため、スケールしない
  • net-toolsパッケージはほぼ更新されていない;多くのディストリビューションがデフォルトインストールから除外済み
  • フィルターオプションが少なく、ssより柔軟性に乏しい

ss: 高速で現代的だが、構文に慣れが必要

長所:

  • 5,000以上のソケットがあるサーバーでもssは1秒未満で結果を返す;netstatは数分かかることも
  • フィルター式言語が非常に強力——IP、サブネット、ポート、状態、プロセスを1つのコマンドでフィルタリング可能
  • TCPタイマーや輻輳ウィンドウなど追加情報を表示——netstatにはない機能
  • 活発に開発が続けられており、あらゆる現代的なLinuxディストリビューションの標準ツール

短所:

  • フィルター構文がnetstatと全く異なり、慣れるのに数日かかる
  • 最初は出力が少し見慣れない、特にProcessカラムのusers:(("nginx",pid=5678,fd=7))形式

どの状況でどちらのツールを使うか?

両方を6ヶ月使ってみて、シンプルなルールを導き出しました:

  • 本番サーバー、多数の接続:ss一択。数千の接続が開いているサーバーでは、netstatが数分かかる場合でもssは数秒で結果を返します。
  • 開発マシンやワークステーションでの簡易デバッグ:どちらでも構いませんが、習慣を統一するため徐々にssに移行しています。
  • ルーティングテーブルやインターフェース統計が必要な場合:netstat -rの代わりにiproute2のip routeip -s linkを使いましょう——ssと同じパッケージで、一貫性があります。

実践的な使い方ガイド

リスニングポートの確認

最もよく行う作業——どのサービスがどのポートを使用しているかを確認する:

# ssを使う場合(推奨)
ss -tlnp

# フラグの説明:
# -t : TCPのみ
# -l : リスニングソケット
# -n : サービス名ではなくポート番号を表示(高速)
# -p : プロセス名とPIDを表示

# netstatの同等コマンド
netstat -tlnp

ss -tlnpの出力は次のようになります:

State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128     0.0.0.0:22          0.0.0.0:*          users:(("sshd",pid=1234,fd=3))
LISTEN  0       511     0.0.0.0:80          0.0.0.0:*          users:(("nginx",pid=5678,fd=6))
LISTEN  0       511     0.0.0.0:443         0.0.0.0:*          users:(("nginx",pid=5678,fd=7))

特定のポートを占有しているプロセスを見つける

最もよく遭遇する状況:サービスが起動できず、ポートが既に使用中と報告される場合:

# ポート8080を占有しているプロセスを確認
ss -tlnp | grep :8080

# ssのフィルター式を使う方法
ss -tlnp 'sport = :8080'

# 出力例: users:(("node",pid=12345,fd=10))
# そのプロセスをkillするには:
kill -9 12345

アクティブな接続をすべて表示

# ESTABLISHEDのTCPコネクション一覧
ss -tn state established

# 状態別の接続数をカウント
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

# ss -sでサマリーを素早く確認
ss -s

ss -sの出力はサーバーの状態を素早く把握するのに非常に役立ちます:

Total: 234 (kernel 312)
TCP:   45 (estab 23, closed 5, orphaned 0, timewait 17)
UDP:   8

IPアドレスまたはサブネットで接続をフィルタリング

オフィス管理でよく使う機能——どのマシンが内部サーバーに接続しているかを確認したり、特定のIPからのトラフィックがどのポートに流れているかを調べたりする際に:

# サブネット192.168.1.0/24からの全接続を確認
ss -tn 'dst 192.168.1.0/24'

# 特定IPへの接続
ss -tn 'dst 192.168.1.100'

# 特定IPからの接続
ss -tn 'src 10.0.0.5'

# 組み合わせ: サブネットからポート443への接続
ss -tn 'src 192.168.1.0/24 and dport = :443'

TCPタイマーを確認——ssだけの機能

# TCPタイマーを確認(keepalive、再送タイムアウトなど)
ss -tn -o

# 出力にtimerカラムが追加されます:
# timer:(keepalive,1min3sec,0)
# 意味: keepaliveタイマーの残り1分3秒、再送回数0回

リアルタイムモニタリング

# 2秒ごとに更新
watch -n 2 'ss -s'

# または状態別の接続数をリアルタイムで監視
watch -n 2 'ss -tan | awk "NR>1 {print \$1}" | sort | uniq -c | sort -rn'

異常な接続を発見した際のデバッグワークフロー

データセンター内のサーバーが見知らぬIPからポートスキャンされているのを発見した際のデバッグ手順は次の通りです:

# ステップ1: SYNフラッドの有無を確認
ss -tn state syn-recv

# ステップ2: 送信元IPごとの接続数をカウント — フラッド中のIPを特定
ss -tn | awk 'NR>1 {print $5}' | grep -oP '^[\d.]+' | sort | uniq -c | sort -rn | head -20

# ステップ3: 不審なIPからの全接続を確認
ss -tn 'src 203.0.113.50'

# ステップ4: TIME_WAITが異常でないか確認
ss -tan state time-wait | wc -l

netstatでは、接続数が多いサーバーでのステップ2に数分かかることもありました。これが実際にssに乗り換えた理由です——ブログで評判だからではなく、インシデント対応中に出力を待ち続けるのが本当にストレスだったからです。

日常的にすぐ使えるエイリアス設定

このエイリアス3つをすべてのサーバーの~/.bashrcに追加しており、タイピングをかなり節約できています:

# ~/.bashrcに追加
alias ports='ss -tlnp'                        # リスニングポートを確認
alias conns='ss -tn state established'         # アクティブな接続
alias socksum='ss -s'                          # ソケット統計のサマリー

# リロード
source ~/.bashrc

インストールされていない場合

# Debian/Ubuntu
sudo apt install iproute2     # ss(通常はプリインストール済み)
sudo apt install net-tools    # netstat(必要な場合)

# CentOS/RHEL/Rocky Linux
sudo dnf install iproute      # ss
sudo dnf install net-tools    # netstat

# バージョン確認
ss -V
netstat --version

Ubuntu 22.04とDebian 12では、ssはプリインストール済みです。netstatはそうではありません——必要な場合は別途インストールが必要です。

まとめ

これから始める方は?ssを直接学んでnetstatはスキップしましょう。構文は少し異なりますが、慣れるために時間をかける価値はあります。netstatに慣れていて移行を検討している方は?ssのコアコマンドをいくつか覚えるだけで、日常業務の90%には対応できます。

私の場合、本番環境でssを半年間使った後、netstatには戻りませんでした。誰かに言われたからではなく、本当に必要な時に速くてフィルタリングが強力だからです。

Share: