Di Linux, bagaimana saya bisa tahu berapa banyak porta yang tersisa tersedia?

17

Apakah ada metode di Linux untuk memeriksa berapa banyak porta yang tersisa tersedia? Saya kadang-kadang melihat kesalahan "Alamat sudah digunakan" sebagai akibat dari kehabisan porta sesaat. Reboot mesin akan menyelesaikan ini, tetapi akan lebih baik untuk menangkapnya sebelum terjadi.

JMc
sumber
Jika Anda memukul kesalahan seperti itu, saya sarankan Anda menyalahgunakan sistem dengan tidak menggunakan perangkat lunak atau arsitektur yang tepat untuk suatu pekerjaan, atau perangkat lunak Anda mengalami kesalahan konfigurasi atau kesalahan konfigurasi. Mungkin waktu tunggu Anda terlalu lama untuk aplikasi Anda atau ada sesuatu yang membiarkan koneksi terbuka tanpa menggunakannya?
Caleb
1
Ada banyak aplikasi yang valid yang membutuhkan port fana tambahan di luar standar OS.
GregB

Jawaban:

26

Rentang port ephermal ditentukan dalam /proc/sys/net/ipv4/ip_local_port_range. Anda mungkin dapat memperpanjang untuk menjalankan dari 16k ke 64k.

Anda dapat melihat jumlah koneksi terbuka menggunakan netstat -an. Soket mungkin macet dalam keadaan TIME_WAIT jika Anda membuka dan menutup banyak koneksi. Di beberapa tempat hal ini tidak dapat dihindari, tetapi Anda mungkin perlu mempertimbangkan apakah Anda memerlukan kumpulan koneksi jika ini masalahnya.

Jika TIME_WAIT adalah masalahnya, Anda dapat mengatur net.ipv4.tcp_tw_reuse/ net.ipv4.tcp_tw_recycleuntuk mempercepat pergantian koneksi.

Sean
sumber
+1, terima kasih telah meluangkan waktu untuk memberikan detail yang tepat kepada orang ini.
Caleb
Kami memiliki kisaran 32800 hingga 61000. Kami hanya menemukan bahwa setelah ini digunakan OS tidak akan menggunakannya lagi. Ini adalah perilaku yang diharapkan, tetapi saya akan mengharapkan OS untuk memulai lagi di awal setelah mencapai port terakhir yang tersedia. Ini sepertinya tidak terjadi. Juga, hanya untuk dicatat, ini bukan kejadian biasa. Itu intermiten tetapi kami memiliki sejumlah besar server.
JMc
1
Untuk mematuhi RFC 6335, /proc/sys/net/ipv4/ip_local_port_range perlu subset dari 49152-65535. Jadi mengurangi ujung bawah kisaran menjadi kurang dari 49152 memang berisiko.
kasperd
tidak pernah pengguna net.ipv4.tcp_tw_recycle atau net.ipv4.tcp_tw_reuse kecuali jika Anda putus asa dan tahu persis apa yang Anda lakukan. Anda memaparkan layanan Anda terhadap potensi masalah ekstrem.
Kiwy
3

Ingatlah bahwa batas ini berlaku per tupel unik (IP sumber, IP rekan, port peer). Oleh karena itu Anda perlu mengelompokkan output dari netstat/ ssdengan masing-masing tupel ini, dan memeriksa seberapa dekat masing-masing grup dengan batas koneksi.

Posting ini menjelaskan bagaimana Anda dapat melakukan pengelompokan ini secara lebih rinci. Untuk memeriksa seberapa dekat masing-masing grup dengan batas di Ruby, Anda dapat memproses ssoutput seperti:

#!/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
Will Sewell
sumber