web-dev-qa-db-ja.com

Linuxでは、使用可能なままになっているエフェメラルポートの数を確認するにはどうすればよいですか?

Linuxに使用可能なエフェメラルポートの数を確認する方法はありますか?エフェメラルポートが不足した結果、「アドレスはすでに使用されています」というエラーが表示されることがあります。マシンを再起動するとこれが解決しますが、発生する前にキャッチすることをお勧めします。

17
JMc

境界ポート範囲は/proc/sys/net/ipv4/ip_local_port_rangeで指定されます。おそらく、16kから64kに実行するように拡張できます。

netstat -anを使用して、開いている接続の数を確認できます。多数の接続を開いたり閉じたりしていると、ソケットがTIME_WAIT状態のままになる場合があります。これは避けられない場合もありますが、その場合は接続のプールが必要かどうかを検討する必要があります。

TIME_WAITが問題である場合は、net.ipv4.tcp_tw_reuse/net.ipv4.tcp_tw_recycleを設定して、接続のターンオーバーを高速化できます。

26
Sean

この制限は一意の(ソースIP、ピアIP、ピアポート)タプルごとに適用されることに注意してください。したがって、これらのタプルごとにnetstat/ssの出力をグループ化し、各グループが接続制限にどれだけ近いかを確認する必要があります。

この投稿 は、このグループ化をどのように行うことができるかをさらに詳しく説明しています。 Rubyで各グループが制限にどれだけ近いかを確認するには、ss出力を次のように処理します。

#!/usr/bin/Ruby

first_port, last_port = IO.read('/proc/sys/net/ipv4/ip_local_port_range').split.map(&:to_i)
ephemeral_port_max = last_port - first_port + 1
ephemeral_port_warning = ephemeral_port_max / 3 * 2

conns = `ss --numeric --tcp state connected "( sport >= :#{first_port} and sport <= :#{last_port} )"`

groups = Hash.new(0)
conns.lines.each do |conn|
  state, recvq, sendq, local, peer = conn.split
  local_ip, local_port = local.split(':')
  group = [local_ip, peer]
  groups[group] += 1
end

groups_requiring_warning =
  groups.select { |k, v| v > ephemeral_port_warning }
  .to_a
  .sort_by { |v1, v2| v1[1] <=> v2[1] } # Sort groups in descending order of number of connections

groups_requiring_warning.each do |group, used_port_count|
  puts "Connections from #{group[0]} to #{group[1]} "\
    "have used #{used_port_count} ephemeral ports out of #{ephemeral_port_max} max"\
    "(#{((used_port_count.to_f / ephemeral_port_max) * 100).round(2)}% used)"
end
3
Will Sewell