2026年5月29日

2026年5月29日

netstatとssでネットワーク接続を監視する|症状別に接続トラブルを切り分けるコマンド集

「ポートが使用中で起動しない」「CLOSE_WAIT が増え続ける」「アクセスが集中すると接続が拒否される」といった接続まわりのトラブルは、ss(古い環境では netstat)の出力を正しく読めれば、多くの場合その場で原因の見当が付きます。この記事では、netstat から ss への置き換え方を確認したうえで、WordPress サーバーで起きやすい症状ごとに「どのコマンドで何を見て、どう判断し、何を直すか」をまとめます。

基本的な使い方より、トラブル時の切り分けに重点を置いています。コマンドの細かなオプションは iproute2 や net-tools のバージョンで差があるため、手元の man ss も合わせて確認してください(2026年10月現在の主要な Linux ディストリビューションを前提にしています)。

netstat から ss への置き換え早見

netstat は net-tools パッケージに含まれ、多くのディストリビューションで標準ではインストールされなくなっています。ss は iproute2 に含まれ、カーネルから直接情報を取るため、接続数が多いサーバーでも速く動きます。手順書に netstat が書かれていても、次のように読み替えられます。

目的 netstat ss / iproute2
待ち受けポートとプロセス netstat -tlnp ss -tlnp
すべての TCP 接続 netstat -tan ss -tan
状態ごとの概要 netstat -s(統計) ss -s、nstat
インターフェースの統計 netstat -i ip -s link
ルーティング表 netstat -rn ip route

プロセス名(-p の出力)は、他のユーザーのプロセスについては root でないと表示されません。表示が空のときは sudo を付けて実行してください。

症状1:「Address already in use」でサービスが起動しない

Nginx や Apache、Docker のコンテナを起動しようとしてこのエラーが出る場合、同じポートをすでに別のプロセスが使っています。

sudo ss -ltnp 'sport = :80'
sudo ss -ltnp 'sport = :443'

出力の users:(("nginx",pid=1234,...)) の部分に、ポートを使っているプロセス名と PID が出ます。よくある原因は次のとおりです。

  1. 古いプロセスが残っている(再起動のつもりが二重起動になった)。systemctl status でサービスの状態を確認し、正しい手順で止めます。
  2. Apache と Nginx の両方が入っていて、両方が 80 番を待ち受けている。どちらを使うか決めて、もう一方を無効化します。
  3. Docker のコンテナがホストのポートを公開している。docker ps の PORTS 列で確認します。

何も表示されないのにエラーが出る場合は、IPv6 側([::]:80)だけが使われているか、設定ファイルで同じ listen を二重に書いていることがあります。ss -ltnp を絞り込まずに実行して、全体を見てください。

症状2:CLOSE_WAIT が増え続ける

CLOSE_WAIT は「相手が接続を閉じたのに、自分の側のアプリケーションがまだソケットを閉じていない」状態です。カーネルのチューニングでは解消せず、アプリケーションの問題であることがほとんどです。

# CLOSE_WAIT の接続とプロセス
sudo ss -tanp state close-wait

# 相手のアドレスごとに数える
ss -Htan state close-wait | awk '{print $4}' | sed -E 's/:[0-9]+$//' | sort | uniq -c | sort -rn | head

state で状態を一つ指定すると、出力から State 列が省かれます。そのため上の例では4列目が相手のアドレスになります。状態を指定しない場合は列が一つずれるので、awk の列番号に注意してください。また -H(ヘッダーなし)が使えない古い ss では、tail -n +2 でヘッダー行を除きます。

相手のアドレスが特定の外部 API やデータベースに偏っているなら、その接続を張っているプラグインや処理が、エラー時に接続を閉じていない可能性があります。PHP-FPM のプロセスに偏っている場合は、pm.max_requests を設定して子プロセスを定期的に入れ替えると、原因を直すまでの間の悪化を抑えられます。

症状3:TIME_WAIT が大量にある

TIME_WAIT は、先に接続を閉じた側に一定時間残る正常な状態です。外部 API やデータベースへ短い接続を何度も張るサーバーでは、数千件あっても珍しくありません。

ss -s
ss -Htan | awk '{print $1}' | sort | uniq -c | sort -rn

問題になるのは、送信元ポートが足りなくなって新しい接続が作れないときです。その場合はまず接続の使い回し(HTTP のキープアライブ、データベースの持続接続やコネクションプールの見直し)を検討します。カーネル設定 net.ipv4.tcp_tw_reuse で改善することもありますが、影響を理解したうえで変更してください。古い記事にある tcp_tw_recycle は Linux 4.12 で削除されており、現在のカーネルでは使えません。

症状4:アクセス集中時に接続が拒否される・つながりにくい

待ち受け中のソケット(LISTEN)では、ss の Recv-Q は「受け付け待ちの接続数」、Send-Q は「受け付け待ちの上限(バックログ)」を意味します。通常の接続とは意味が違う点がつまずきやすいところです。

ss -ltn
# 受け付けキューが溢れた回数(累積値)
nstat -az TcpExtListenOverflows TcpExtListenDrops

Recv-Q が Send-Q に近づいている、または TcpExtListenOverflows が増え続けているなら、アプリケーションが接続を受け取る速度が追いついていません。対処の順序は次のとおりです。

  1. 受け取る側の処理能力を確認する。PHP-FPM の子プロセスがすべて使用中になっていないか(ステータスページやログの「max_children に達した」旨の警告)を見ます。
  2. 処理を軽くする。ページキャッシュ、オブジェクトキャッシュで PHP まで届くリクエストを減らします。
  3. 必要に応じてバックログを広げる。net.core.somaxconn と、Nginx の listen の backlog=、PHP-FPM の listen.backlog を合わせて調整します。片方だけ増やしても効果は限られます。

症状5:特定の IP から大量の接続がある

ss -Htn state established '( sport = :443 or sport = :80 )' \
  | awk '{print $4}' | sed -E 's/:[0-9]+$//' | sort | uniq -c | sort -rn | head -20

一つのアドレスから数百の接続がある場合、クローラーや攻撃の可能性があります。ただし、Cloudflare などの CDN やロードバランサーの背後にあるサーバーでは、相手のアドレスはすべて中継側のものになるため、この方法では本当の送信元は分かりません。その場合はアクセスログに記録された実際のクライアント IP(X-Forwarded-For などを正しく設定したもの)で判断します。

不正なアクセスと判断したら、fail2ban や Web サーバーの接続数制限、CDN 側のルールで対処します。ss の結果だけで機械的に遮断すると、検索エンジンのクローラーや社内の正当な利用を止めてしまうことがあるため、ログで裏付けを取ってからにしてください。

症状6:データベースへの接続が詰まる

WordPress とデータベースの間の接続は、TCP(3306番)か Unix ソケットのどちらかです。

# TCP で接続している場合
sudo ss -tnp '( dport = :3306 or sport = :3306 )'
# Unix ソケットの場合
sudo ss -xp | grep -i mysql

接続数がデータベースの max_connections に近いなら、「Too many connections」エラーの前兆です。PHP-FPM の子プロセス数とデータベースの上限の関係を見直します。接続の再送が多い(ss -ti で retrans が増えている)場合は、別ホストのデータベースとの間のネットワーク品質を疑います。

定点観測にする

トラブルは再現しないことが多いため、普段の値を記録しておくと比較できます。

# 1分ごとに状態別の件数を記録する例(/etc/cron.d/ss-states に置く。ユーザー名の列がある書式)
* * * * * root echo "$(date +\%FT\%T) $(ss -Htan | awk '{print $1}' | sort | uniq -c | tr '\n' ' ')" >> /var/log/ss-states.log

ログが増え続けないよう logrotate の設定も合わせて行ってください。長期の監視や通知まで必要なら、node_exporter と Prometheus など専用の監視の仕組みに移すほうが扱いやすくなります。

まとめ

  • netstat は ss と ip コマンドに読み替えられる。プロセス名を見るには sudo が必要
  • 「Address already in use」は ss -ltnp 'sport = :ポート' で使用中のプロセスを特定する
  • CLOSE_WAIT の増加はアプリケーション側の問題。相手先とプロセスで偏りを探す
  • TIME_WAIT は多くても正常なことが多い。困るのはポート不足のときで、まず接続の使い回しを検討する
  • LISTEN の Recv-Q/Send-Q と ListenOverflows でバックログ溢れを見つけ、処理能力の改善から手を付ける
  • 送信元 IP の集計は CDN の背後では使えない。遮断の前にログで裏付けを取る

お気軽にご相談ください

お見積りへ お問い合わせへ
▲