MENU

エフェメラルポート枯渇の本番診断と net.ipv4 パラメータ調整フロー

目次

エフェメラルポート枯渇が起きる仕組みと背景

Linux でクライアント側から TCP 接続を発信するとき、カーネルは発信元ポート番号(エフェメラルポート)を自動的に割り当てます。割り当て可能な範囲は /proc/sys/net/ipv4/ip_local_port_range で管理されており、主要ディストリビューションのデフォルト値は 32768 60999、つまり約 28,000 ポートです。

この上限を超えると新規 TCP 接続が EADDRNOTAVAIL(Cannot assign requested address) エラーで失敗します。高トラフィックのリバースプロキシ、マイクロサービス間の短命 HTTP 接続、あるいはコネクションプールを使わずに都度接続を張るアーキテクチャでは、TIME_WAIT 状態のソケットが大量に積み上がり、利用可能なポート数を圧迫します。

TIME_WAIT は TCP の正常な終了シーケンスで発生するステートです。Linux では実質的に約 60 秒間ポートを占有し続けます。28,000 ポートに対して毎秒 500 コネクション以上を発信するサーバーでは、理論上 1 分以内に枯渇に至ります。障害が散発的で再現しにくいのは、負荷のピーク時間帯のみ閾値を超えるためです。

本番環境での症状確認と診断コマンド

ポート枯渇が疑われる場合、まずアプリケーションログに EADDRNOTAVAIL または connect: Cannot assign requested address が出ていないか確認します。次にカーネルソケット統計で全体像を把握します。

# ソケット全体のサマリー
ss -s

# 状態別の件数を集計(降順)
ss -tan | awk 'NR>1{print $1}' | sort | uniq -c | sort -rn

# TIME_WAIT の件数のみ確認
ss -tan state time-wait | wc -l

ss -s は接続状態ごとの合計をコンパクトに表示します。TIME_WAIT の件数が ip_local_port_range の幅に近づいているようであれば、枯渇リスクが高いと判断できます。

# 現在のポート範囲を確認
cat /proc/sys/net/ipv4/ip_local_port_range

# TIME_WAIT のピーク傾向をリアルタイム観測(5 秒ごと)
watch -n 5 'ss -tan state time-wait | wc -l'

# カーネルログでの関連エラー確認
dmesg | grep -i 'socket\|port' | tail -20

診断ポイントをまとめると以下のとおりです。

  • TIME_WAIT 数が利用可能ポート数(デフォルト約 28,000)の 70% を超えていれば警戒水準
  • アプリケーション側のエラーログに EADDRNOTAVAIL が散見されれば枯渇がほぼ確定
  • 負荷のピーク時間帯に限定した散発的エラーは枯渇の典型的なパターン

net.ipv4 パラメータの調整フロー

原因が確認できたら、段階的にパラメータを調整します。一度に複数のパラメータを変更すると影響を切り分けにくくなるため、順序立てて適用するのが基本です。

ステップ 1:ポート範囲を拡張する

最もシンプルかつ副作用が小さい対処です。範囲を広げることで、TIME_WAIT 状態のソケットが多くても新規接続に使えるポートを確保できます。

# 即時反映(再起動で元に戻る)
sysctl -w net.ipv4.ip_local_port_range="10000 65535"

# 永続化(/etc/sysctl.d/ 配下に専用ファイルを作成)
cat <<'EOF' > /etc/sysctl.d/90-ephemeral-port.conf
net.ipv4.ip_local_port_range = 10000 65535
EOF
sysctl -p /etc/sysctl.d/90-ephemeral-port.conf

範囲を 10000 65535 にすることで約 55,500 ポートを利用可能にします。ウェルノウンポート(0~1023)との競合を避けるため、下限を 1024 以上に設定します。実運用では 10000 65535 あたりを下限とするケースが多く、既存サービスのポート割り当てと重複しないかをあらかじめ確認します。

ステップ 2:tcp_tw_reuse を有効化する

tcp_tw_reuse は、TIME_WAIT 状態のソケットを新規発信接続に再利用することを許可するオプションです。tcp_timestamps(デフォルトで有効)が有効な場合のみ安全に動作します。

cat <<'EOF' >> /etc/sysctl.d/90-ephemeral-port.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
EOF
sysctl -p /etc/sysctl.d/90-ephemeral-port.conf

tcp_tw_reuse はサーバー側のリスニングソケットには影響せず、クライアント側(発信元)のエフェメラルポート割り当てにのみ作用します。tcp_timestamps と組み合わせることで、タイムスタンプによる古いパケット識別が機能し、NAT 環境でも比較的安全に使用できます。

ステップ 3:tcp_fin_timeout を短縮する

FIN_WAIT2 タイムアウトはデフォルト 60 秒です。これを短縮すると半開き接続が早期に解放されます。

cat <<'EOF' >> /etc/sysctl.d/90-ephemeral-port.conf
net.ipv4.tcp_fin_timeout = 15
EOF
sysctl -p /etc/sysctl.d/90-ephemeral-port.conf

値を短くしすぎると不安定なネットワーク経路での切断検知に影響することがあります。一般的には 15~30 秒の範囲が実運用のバランスとされています。

設定変更の検証と動作確認

変更後は以下のコマンドで設定が反映されているかを確認します。

# 設定値の確認
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_tw_reuse
sysctl net.ipv4.tcp_fin_timeout
sysctl net.ipv4.tcp_timestamps

設定反映後は数分間 TIME_WAIT 数を監視し、増加傾向が緩やかになっていることを確認します。アプリケーション側でも接続エラーが消えているかをログで検証します。

# 状態の継続観測
watch -n 5 'ss -s | grep -E "TIME-WAIT|estab"'

負荷試験ツール(wrk、vegeta など)が利用できる環境であれば、想定トラフィックを再現して改善を数値で確認するとより確実です。想定例として、秒間 1,000 リクエストを継続したときに TIME_WAIT がポート範囲の上限に達しないことを確認するといった検証が考えられます。

切り戻しと注意点

想定外の影響が出た場合は、即時 sysctl -w で元の値に戻し、/etc/sysctl.d/ のファイルを削除またはコメントアウトして sysctl --system を再適用します。

# 緊急時の即時切り戻し例
sysctl -w net.ipv4.ip_local_port_range="32768 60999"
sysctl -w net.ipv4.tcp_tw_reuse=0
sysctl -w net.ipv4.tcp_fin_timeout=60

運用上で押さえておきたい注意点は以下のとおりです。

  • ポート範囲を広げても根本的な接続過多は解消されない。コネクションプールの導入や HTTP Keep-Alive の活用など、アプリケーションアーキテクチャ側の見直しも並行して検討する
  • tcp_tw_reuse は発信側(クライアント)のカーネルにのみ効果がある。サーバーとして TIME_WAIT を大量に抱えている場合は、接続元のクライアント側設定を見直す必要がある
  • コンテナ環境(Docker/Kubernetes)では Pod の hostNetwork 設定やノードの sysctl 設定との兼ね合いを確認する。Kubernetes 1.28 以降は sysctls フィールドで Pod ごとの設定が可能
  • クラウド VM の場合は OS レイヤーで変更可能だが、マネージドロードバランサーやサービスメッシュ側のコネクション管理と競合しないか確認が必要

2026 年現行環境での差分:tcp_tw_recycle は使わない

古い技術記事やチューニングガイドには net.ipv4.tcp_tw_recycle = 1 を推奨するものが今も残っています。しかしこのパラメータは Linux カーネル 4.12(2017 年 7 月)で完全に削除されています。現行の Ubuntu 22.04/24.04、RHEL 9/10、Debian 12 などはすべて 4.12 以降のカーネルを採用しているため、このパラメータは存在しません。誤って設定しても無視されるだけですが、混乱を避けるため古い設定ファイルからは削除しておくべきです。

tcp_tw_recycle が削除された背景には、NAT 環境での致命的な問題がありました。同一 NAT ゲートウェイ配下の複数クライアントがタイムスタンプの整合性チェックで弾かれ、接続が断続的に失敗するという挙動が報告されていました。クラウドやコンテナが当然の環境となった現在では、過去に使っていたとしても早急に設定を外すべきです。

tcp_tw_reuse についても近年のカーネルで挙動が変化しています。比較的新しいカーネルでは、ループバックインターフェース向けの動作が調整されており、設定値の意味が以前と異なる場合があります。チューニングを適用する前に sysctl net.ipv4.tcp_tw_reuse で現在値を確認し、変更後の挙動を必ずテスト環境で検証することを推奨します。

また、RHEL 9 / CentOS Stream 9 以降など新しいディストリビューションでは ip_local_port_range のデフォルト値がディストリビューション側で調整されているケースがあります。チューニング前に必ず cat /proc/sys/net/ipv4/ip_local_port_range で現在値を確認するのが確実です。よくあるつまずきとして、デフォルト値を確認せずに設定を追記し、実際には変化していなかったというケースがあります。sysctl -a | grep ip_local_port_range で適用済みの値を検証する習慣をつけておくと安心です。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

PR・広告

Linuxサーバーセキュリティ徹底入門(Amazon)

ポート・ファイアウォール・権限などサーバ防御の基本をオープンソースで学べる実務書。

Amazonで見る

※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次