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 が出ます。よくある原因は次のとおりです。
- 古いプロセスが残っている(再起動のつもりが二重起動になった)。
systemctl statusでサービスの状態を確認し、正しい手順で止めます。 - Apache と Nginx の両方が入っていて、両方が 80 番を待ち受けている。どちらを使うか決めて、もう一方を無効化します。
- 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 が増え続けているなら、アプリケーションが接続を受け取る速度が追いついていません。対処の順序は次のとおりです。
- 受け取る側の処理能力を確認する。PHP-FPM の子プロセスがすべて使用中になっていないか(ステータスページやログの「max_children に達した」旨の警告)を見ます。
- 処理を軽くする。ページキャッシュ、オブジェクトキャッシュで PHP まで届くリクエストを減らします。
- 必要に応じてバックログを広げる。
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 の背後では使えない。遮断の前にログで裏付けを取る