No Linux, como posso saber quantas portas efêmeras ainda estão disponíveis?


17

Existe um método no Linux para verificar quantas portas efêmeras ainda estão disponíveis? Ocasionalmente, vejo erros de "Endereço já em uso" como resultado da falta de portas efêmeras. Uma reinicialização da máquina resolverá isso, mas seria melhor capturá-la antes que isso aconteça.


Se você estiver enfrentando erros como esse, sugiro que você esteja abusando do sistema por não usar o software ou a arquitetura corretos para um trabalho ou o seu software esteja se comportando mal ou configurado incorretamente. Talvez seus tempos limite sejam muito longos para o seu aplicativo ou algo esteja deixando as conexões abertas sem usá-los?
Caleb

1
Existem muitos aplicativos válidos que requerem portas efêmeras adicionais além dos padrões do SO.
GregB

Respostas:


26

O intervalo de portas epérmicas é especificado em /proc/sys/net/ipv4/ip_local_port_range. Você provavelmente pode estendê-lo para executar de 16k a 64k.

Você pode ver o número de conexões abertas usando netstat -an. Os soquetes podem estar presos no estado TIME_WAIT se você estiver abrindo e fechando muitas conexões. Em alguns lugares, isso é inevitável, mas talvez seja necessário considerar se você precisa de um conjunto de conexões, se for o caso.

Se o problema for TIME_WAIT, você pode definir net.ipv4.tcp_tw_reuse/ net.ipv4.tcp_tw_recyclepara acelerar a rotatividade da conexão.


+1, obrigado por reservar um tempo para fornecer detalhes exatos a esse cara.
Caleb

Temos um intervalo de 32800 a 61000. Acabamos de descobrir que, uma vez utilizados, o SO não os utilizará novamente. Esse é um comportamento esperado, mas eu esperaria que o sistema operacional iniciasse novamente no início assim que atingir a última porta disponível. Isso parece não acontecer embora. Além disso, apenas para observar, essa não é uma ocorrência extremamente regular. É intermitente, mas temos um grande número de servidores.
JMC


1
Para estar em conformidade com a RFC 6335, /proc/sys/net/ipv4/ip_local_port_range precisa ser um subconjunto de 49152-65535. Portanto, reduzir o limite inferior do intervalo para algo menor que 49152 tem um certo risco.
kasperd 03/02

nunca use net.ipv4.tcp_tw_recycle nem net.ipv4.tcp_tw_reuse, exceto se estiver desesperado e souber exatamente o que está fazendo. Você está expondo seu serviço a possíveis problemas extremos.
Kiwy

3

Lembre-se de que esse limite se aplica por tupla exclusiva (IP de origem, IP de ponto, porta de ponto). Portanto, você precisará agrupar a saída de netstat/ sspor cada uma dessas tuplas e verificar a proximidade de cada grupo com o limite de conexão.

Esta postagem explica como você pode fazer esse agrupamento com mais detalhes. Para verificar o quão perto cada grupo está do limite em Ruby, você pode processar a sssaída como:

#!/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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.