Apa cara termudah untuk menemukan port lokal yang tidak digunakan?
Saat ini saya menggunakan sesuatu yang mirip dengan ini:
port=$RANDOM
quit=0
while [ "$quit" -ne 1 ]; do
netstat -a | grep $port >> /dev/null
if [ $? -gt 0 ]; then
quit=1
else
port=`expr $port + 1`
fi
done
Rasanya sangat bundaran, jadi saya bertanya-tanya apakah ada jalan yang lebih sederhana seperti builtin yang saya lewatkan.
shell
networking
shell-script
netstat
mybuddymichael
sumber
sumber
-n
netstat dan grep yang lebih selektif). Cara untuk melakukannya adalah dengan mencoba dan membuka port dalam mode apa pun yang Anda butuhkan, dan coba yang lain jika tidak tersedia.ssh -D
sebagai server SOCKS.Jawaban:
Jika aplikasi Anda mendukungnya, Anda dapat mencoba mengirimkan port 0 ke aplikasi tersebut. Jika aplikasi Anda meneruskan ini ke kernel, port akan dialokasikan secara dinamis pada waktu permintaan, dan dijamin tidak akan digunakan (alokasi akan gagal jika semua port sudah digunakan).
Jika tidak, Anda dapat melakukan ini secara manual. Skrip dalam jawaban Anda memiliki kondisi balapan, satu-satunya cara untuk menghindarinya adalah dengan memeriksa secara atomik apakah itu terbuka dengan mencoba membukanya. Jika port sedang digunakan, program harus berhenti dengan kegagalan untuk membuka port.
Misalnya, Anda mencoba mendengarkan dengan GNU netcat.
sumber
$port
program yang sebenarnya seperti padawhile ...; done; program --port $port
.Solusi saya adalah mengikat ke port 0, yang meminta kernel untuk mengalokasikan port dari itu ip_local_port_range. Kemudian, tutup soket dan gunakan nomor port itu dalam konfigurasi Anda.
Ini berfungsi karena kernel tampaknya tidak menggunakan kembali nomor port sampai benar-benar harus. Ikatan selanjutnya ke port 0 akan mengalokasikan nomor port yang berbeda. Kode python:
Ini hanya memberikan sejumlah port, misalnya.
60123
.Jalankan program ini 10.000 kali (Anda harus menjalankannya secara bersamaan), dan Anda akan mendapatkan 10.000 nomor port yang berbeda. Karena itu, saya pikir cukup aman untuk menggunakan porta.
sumber
python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'
{ 1: 7006, 2: 1249, 3: 151, 4: 8, 5: 1, 6: 1}
ruby -e 'puts Addrinfo.tcp("", 0).bind { |s| s.local_address.ip_port }'
Satu garis
Saya telah mengumpulkan satu-liner bagus yang dengan cepat melayani tujuan, memungkinkan untuk mengambil sejumlah port yang sewenang-wenang dalam rentang sewenang-wenang (di sini dibagi dalam 4 baris untuk dibaca):
Baris demi baris
comm
adalah utilitas yang membandingkan baris dalam dua file yang harus ditampilkan secara alfabet. Ini menghasilkan tiga kolom: baris yang hanya muncul di file pertama, baris yang hanya muncul di baris kedua dan umum. Dengan menentukan-23
kami menekan kolom terakhir dan hanya menyimpan yang pertama. Kita bisa menggunakan ini untuk mendapatkan perbedaan dua set, yang dinyatakan sebagai urutan baris teks. Saya belajar dicomm
sini .File pertama adalah kisaran port yang dapat kita pilih.
seq
menghasilkan urutan angka yang diurutkan dari$FROM
ke$TO
. Hasilnya disortir berdasarkan abjad (bukan secara numerik) dan disalurkan kecomm
sebagai file pertama yang menggunakan proses substitusi .File kedua adalah daftar port yang diurutkan, yang kami peroleh dengan memanggil
ss
perintah (dengan-t
arti port TCP,-a
artinya semua - mapan dan mendengarkan - dan-n
numerik - jangan mencoba menyelesaikan, katakanlah,22
untukssh
). Kami kemudian hanya memilih kolom keempat denganawk
, yang berisi alamat dan port lokal. Kami menggunakancut
untuk membagi alamat dan port dengan:
pembatas dan hanya menyimpan yang terakhir (-f2
).ss
juga menampilkan tajuk, yang kami singkirkan dengan melakukangrep
ping untuk urutan angka yang tidak kosong yang tidak lebih dari 5. Kami kemudian memenuhicomm
persyaratan dengansort
tanpa duplikat-u
.Sekarang kita memiliki daftar diurutkan dari port terbuka, bahwa kita dapat
shuf
PHK untuk kemudian ambil pertama"$HOWMANY"
-orang denganhead -n
.Contoh
Raih tiga porta acak yang terbuka dalam jangkauan privat (49152-65535)
bisa kembali misalnya
Catatan
-t
dengan-u
diss
untuk mendapatkan port UDP gratis sebaliknya.shuf
dengansort -n
jika Anda lebih suka mendapatkan port yang tersedia diurutkan secara numerik daripada secara acaksumber
Penghargaan untuk Chris Down
sumber
Rupanya koneksi TCP dapat digunakan sebagai deskriptor file di linux dari dengan di bash / zsh. Fungsi berikut menggunakan teknik itu dan harus lebih cepat daripada memanggil netcat / telnet.
Instruksi penggunaan: Bind output ke variabel dan gunakan dalam skrip. Diuji pada Ubuntu 16.04
sumber
ksh93
juga.$[$LPORT + ($RANDOM % ($UPORT-$LPORT))]
.\n
ke port mendengarkan :) :) Saya sarankan menambahkan-n
. Ini masih akan mencoba untuk membuka koneksi tetapi tidak mengirim apa pun tetapi segera putuskan.Inilah "oneliner" lintas-platform, efisien, yang menghirup semua port yang digunakan dan memberi Anda yang pertama dari 3000 dan seterusnya:
Anda cukup bergabung dengan semua baris untuk memilikinya di satu baris. Jika Anda ingin mendapatkan yang pertama tersedia dari nomor port yang berbeda, ubah penetapan menjadi
i
dalamfor
loop.Ia bekerja pada Mac dan Linux, itulah sebabnya
[:.]
diperlukan regex.sumber
-a
dan tidak-t
hanya melihat soket TCP (6)?ss -Htnl
mungkin lebih baik (dan lebih cepat! - bukannya saya peduli tentang itu: P).-t
, setidaknya yang dikirimkan Apple, danss
juga tidak ada di macOS.netstat -aln
bahkan bekerja pada Solaris.Di Linux, Anda dapat melakukan sesuatu seperti:
Untuk menemukan port gratis pertama di atas 1080. Catatan yang
ssh -D
akan mengikat pada antarmuka loopback, jadi secara teori Anda bisa menggunakan kembali port 1080 jika soket mengikatnya pada alamat lain. Cara lain adalah dengan benar-benar mencoba dan mengikatnya:sumber
ssh -D
, saya tidak bisa melihat opsi yang lebih baik. The-O forward
pilihan untukssh
tidak kembali kesalahan ketika maju gagal.Ini adalah versi yang saya gunakan:
Perintah
shuf -n 1 -i 49152-65535
memberi Anda port "acak" dalam rentang dinamis. Jika sudah digunakan, port lain dalam kisaran itu dicoba.Perintah ini
netstat -atun
mencantumkan semua port (-a) TCP (-t) dan UDP (-u) tanpa membuang waktu untuk menentukan nama host (-n).sumber
Ini adalah bagian dari fungsi yang saya miliki di .bashrc saya, yang secara dinamis membuat terowongan SSH dan mencoba menggunakan port apa pun dalam rentang:
YMMV
sumber
Satu lagi berlari di kuda hobi lama ini:
Kode ini membuat penggunaan murni portabel
netstat
,egrep
,awk
, & al. Perhatikan bahwa hanya panggilan yang dikeluarkan untuk perintah eksternal, untuk mendapatkan daftar port yang diambil di awal. Satu dapat meminta satu atau lebih port gratis:dan mulai dari porta arbitrer:
sumber
Kombinasi saya dari jawaban lain di atas. Mendapatkan:
Dengan shuf -n1 kita mengambil satu angka acak dari rentang (-i) di / proc / sys / net / ipv4 / ip_local_port_range. shuf memerlukan sintaks dengan tanda hubung, jadi kami menggunakan tr untuk mengubah tab dalam tanda hubung.
Selanjutnya kita akan menggunakan netstat untuk menunjukkan kepada kita semua (-a) koneksi tcp dan udp (-u -t) dalam angka (-n), jika kita menemukan port acak $ port dalam hal ini (mulai dengan:: dan diakhiri dengan w whitespace ( \ s) maka kita memerlukan Port lain dan lanjutkan. Lain (grep -q memiliki kode pengembalian> 0 kita meninggalkan loop while dan $ port diatur.
sumber
Jika Anda memiliki python, Anda akan melakukan ini:
sumber
Saya menulis skrip Python2 / 3 kecil ini yang mungkin dapat membantu Anda lain kali:
https://github.com/sdenel/find-unused-local-port
sumber
Pendapat saya ... fungsi mencoba menemukan
n
port bebas berurutan:sumber