【実務・中級編】 netstatの主要オプション(-an, -p, -r, -i)によるルーティングとインターフェース診断 – トラブルシューティング&ネットワーク運用監視実践ガイド

現場の「最終兵器」:netstatを使いこなしてネットワークの迷宮を脱出する

深夜3時、アラートの通知音と共に叩き起こされる。画面に並ぶのは「API接続タイムアウト」のログ。ロードバランサーは正常、アプリケーションのログも出ているが、特定の通信だけがなぜかブラックホールに吸い込まれている。

そんな時、君はまず何を叩く? curl で疎通確認? それともログを追いかける?
もちろんそれも大事だが、現場で泥をすすり、数々の障害を鎮火してきたエンジニアが最後に頼るのは、OSの足元を覗き込む netstat だ。今日は、単なるマニュアルの羅列ではない、実戦で「生き残る」ための netstat 活用術を伝授しよう。

—

1. なぜ今さら netstat なのか

最近では ss コマンドへの移行が進んでいるが、依然として多くのレガシーシステムや、緊急時のレスキュー現場では netstat が標準だ。何より、OSのカーネルが今、ネットワークスタックで何を考えているのかを直接覗けるこのツールは、ネットワークエンジニアにとっての「聴診器」に他ならない。

まずは、現場で最もよく使うオプションを整理しよう。

netstat -an:名前解決の罠を回避する

# -a: すべてのソケットを表示
# -n: 数値形式(IPアドレスとポート番号)で表示
netstat -an | grep 8080

なぜ -n が重要か。それは、DNSの解決待ちでコマンドのレスポンスが数秒間フリーズするのを防ぐためだ。障害発生時の「1分」は非常に長い。DNSが死んでいる最中に名前解決を試みるような愚は避けるべきだ。

netstat -p:犯人(プロセス)を特定する

# root権限で実行してPIDを表示
sudo netstat -anp | grep :443

通信が詰まっている時、どのプロセスがそのポートを掴んでいるのか? LISTEN しているのは nginx か、あるいはゾンビ化した古い python プロセスか。-p を付けることで、ポートとプロセスID(PID)が一発で紐付く。これは障害調査における「容疑者特定」の第一歩だ。

—

2. インターフェースの「健康診断」:-i オプション

パケットロスが疑われる時、OS側で何が起きているかを確認するのが -i オプションだ。

netstat -i

ここで注目すべきは RX-ERR(受信エラー)や TX-ERR(送信エラー)、そして DROP(破棄)の列だ。もしここで数字が急激に増えているなら、それはアプリケーションの問題ではなく、NICのバッファ溢れや、MTUサイズ不一致によるパケットドロップの可能性が高い。

curl で叩いても「Connection reset by peer」になる場合、ルーティング以前に、インターフェースの層でパケットが門前払いされているケースを疑おう。

—

3. 迷子になったパケットを追う:-r ルーティングテーブル

「なぜか特定セグメントへの通信だけが飛ばない」という現象に遭遇したら、まずはルーティングを確認する。

netstat -r -n

これは ip route コマンドと似ているが、netstat -rn はOSがパケットをどのゲートウェイに投げようとしているのかを即座に教えてくれる。

  • デフォルトゲートウェイは正しいか?
  • 特定のセグメントに対して、意図しないインターフェースが割り当てられていないか?

特に、DockerコンテナやVPNインターフェースが乱立する環境では、ルーティングテーブルの汚染は日常茶飯事だ。ここで Gateway の値と Iface を見比べることで、パケットが「どこへ向かおうとしているか」の現在地を把握できる。

—

4. 実践:PythonでAPI呼び出しを監視する

例えば、Pythonの requests や aiohttp で外部APIを叩いている際、接続が詰まる状況を再現・調査する場合を考えよう。

import requests

# 接続時のタイムアウト設定を明示的に記述する
try:
    response = requests.get('https://api.example.com/v1/data', timeout=(3.05, 10))
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    # ここでエラーをキャッチしつつ、netstatで現状を確認する準備をする
    print(f"通信エラー発生: {e}")

このコードを実行している最中に、別のターミナルで netstat -anp | grep ESTABLISHED を打ってみれば、自分のプログラムがどのリモートIPに対して接続を張り、どの程度の Recv-Q(受信キュー)や Send-Q(送信キュー)が溜まっているかが可視化できる。

  • Send-Q が溜まっているなら:相手側の受信処理が追いついていない、あるいはネットワーク帯域が飽和している。
  • Recv-Q が溜まっているなら:自分のアプリケーションがソケットからデータを読み出すのが遅い。

—

最後に:エンジニアとしての心構え

ツールはあくまで補助輪だ。一番大切なのは、「何が起きているか」を論理的に仮説立てる力である。netstat で見えるのはあくまで結果としての「状態」だ。その状態が、なぜその数値を示しているのか。

「なぜパケットがそこに留まっているのか?」という問いを常に持ち続けてほしい。
教科書通りのコマンドを打つだけの作業員ではなく、パケットの呼吸を感じ取れるエンジニアになれば、どんな難解な障害も必ず突破できる。

さあ、次のアラートが鳴る前に、自分のサーバーの今の状態を netstat で眺めておこう。それが、いざという時の「武器」になるはずだ。

コメント

タイトルとURLをコピーしました