Як в Linux можна сказати, скільки доступних ефемерних портів залишилося?


17

Чи є в Linux спосіб перевірити, скільки ефемерних портів залишилось доступними? Іноді я бачу помилки "Адреса вже використовується" внаслідок закінчення ефемерних портів. Машинна перезавантаження дозволить вирішити це, але було б краще зловити його до того, як це станеться.


Якщо у вас виникають подібні помилки, я б сказав, що ви або зловживаєте системою, не використовуючи потрібне програмне забезпечення або архітектуру для роботи, або ваше програмне забезпечення не поводиться або неправильно налаштовується. Можливо, ваші очікування занадто довгі для вашої програми або щось залишає з'єднання відкритими без їх використання?
Калеб

1
Існує багато дійсних додатків, які потребують додаткових ефемерних портів за межами стандартних параметрів ОС.
GregB

Відповіді:


26

Діапазон ефермального порту вказаний у /proc/sys/net/ipv4/ip_local_port_range. Ви, ймовірно, можете продовжити його, щоб він працював від 16 к 64 к.

Ви можете бачити кількість відкритих з'єднань за допомогою netstat -an. Розетки можуть застрягти в TIME_WAIT стані, якщо ви відкриваєте та закриваєте багато з'єднань. У деяких місцях це неминуче, але вам може знадобитися врахувати, чи потрібен пул зв’язків, якщо це так.

Якщо проблема TIME_WAIT, ви можете встановити net.ipv4.tcp_tw_reuse/ net.ipv4.tcp_tw_recycleприскорити обіг з'єднання.


+1, дякую, що знайшли час, щоб дати хлопцеві точні деталі.
Калеб

Ми маємо діапазон від 32800 до 61000. Ми просто виявляємо, що після їх використання ОС не буде використовувати їх знову. Це очікувана поведінка, але я би сподівався, що ОС запуститься знову на початку, як тільки вона досягне останнього доступного порту. Схоже, це не відбувається. Крім того, лише зауважте, це не дуже регулярний випадок. Це періодично, але у нас є велика кількість серверів.
JMc


1
Для відповідності RFC 6335 /proc/sys/net/ipv4/ip_local_port_range повинно бути підмножина 49152-65535. Таким чином, зменшення нижнього кінця діапазону до чого-небудь менше, ніж 49152, дійсно є певним ризиком.
kasperd

ніколи не користувач net.ipv4.tcp_tw_recycle ні net.ipv4.tcp_tw_reuse, за винятком випадків, коли ви відчайдушно і точно знаєте, що робите. Ви піддаєте свою послугу можливим проблемам з крайніми ситуаціями.
Kiwy

3

Майте на увазі, що ця межа застосовується для унікального кордону (вихідний 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.