Bagaimana cara memesan porta untuk aplikasi saya?

29

Bagaimana cara memesan daftar port untuk aplikasi khusus saya?

Untuk lebih spesifik, produk yang saya buat memiliki banyak proses dan banyak komunikasi antara mereka.

Masalah yang saya alami adalah - sesekali - OS mencuri port saya. Jarang, tetapi itu terjadi.

Ini bisa jadi karena aplikasi yang berbeda telah menggunakan ":: bind" tanpa port yang ditentukan.

Atau kadang-kadang aplikasi saya sendiri mencuri port ketika saya memanggil ":: connect" dengan soket yang tidak terikat. Seperti yang terlihat dari halaman manual:

Jika soket belum terikat ke alamat lokal, sambungkan () akan mengikatnya ke alamat yang, kecuali keluarga alamat soket adalah AF_UNIX, adalah alamat lokal yang tidak digunakan.

Jadi pertanyaan saya adalah, bisakah saya memesan port yang saya butuhkan sehingga OS tidak menggunakannya? Apakah ini dapat dilakukan dengan / etc / services? Atau ada cara lain?

Michael Baker
sumber
1
Bisakah Anda menggunakan soket AF_UNIX saja?
alex
2
Lebih khawatir mengapa aplikasi Anda sendiri 'mencuri port'?
EightBitTony
Saya berdebat jika saya perlu melalui perangkat lunak saya dan mengikat sisi klien dari setiap koneksi ke port tertentu. Cukup pekerjaan bagi saya untuk memperbarui ini karena ada banyak jalur koneksi di aplikasi saya. Pemesanan port di OS akan menjadi solusi celah berhenti yang baik sampai saya menemukan waktu untuk melakukan ini.
Michael Baker
Saya tidak yakin apakah SELinuxdalam mode Penegakan dapat memenuhi kebutuhan Anda, saya masih belajar tentang itu. Jadi hanya menebak, mungkin Anda dapat menentukan kebijakan Anda sendiri untuk SELinuxuntuk cadangan Anda port, seperti my_server_port_t tcp 1111, 2222, 3333, 4444-4600. Jika aplikasi Anda akan berjalan di mana-mana (bukan aplikasi server), saya khawatir Anda tidak dapat mengontrol apakah SELinuxON atau OFF.
LiuYan 刘 研
Dengan "mencuri", saya anggap Anda maksud bahwa aplikasi pihak ketiga mengikat ke nomor port yang Anda pilih sebelum aplikasi Anda mendapat kesempatan, karena aplikasi pihak ke-3 telah meminta untuk mengikat ke 0 dan OS telah secara acak menetapkan nomor port yang Anda pilih ke Aplikasi pihak ke-3. Jika demikian, lihat unix.stackexchange.com/a/38724/27865
Mark Lakata

Jawaban:

14

Secara teknis, tidak ada yang namanya "port yang dipesan".

Dalam TCP / UDP, satu-satunya cara untuk "mencadangkan" port adalah dengan benar bind()- benar soket. Port terikat tidak akan digunakan oleh aplikasi lain; port yang tidak digunakan, yah, tidak digunakan sehingga aplikasi lain bebas untuk menggunakannya.

Jika Anda menulis perangkat lunak server, maka Anda dapat mengikat soket ke port tertentu sedini yang Anda inginkan dalam kode aplikasi. Buat nomor port dapat dikonfigurasi, atau setidaknya nyatakan dengan jelas dalam dokumentasi, sehingga administrator sistem dapat dengan cepat mengidentifikasi bentrokan dan memindahkan aplikasi yang bertentangan ke server yang terpisah.

Riccardo Murri
sumber
1
Juga, hindari menggunakan port yang terkenal / dicadangkan jika memungkinkan.
EightBitTony
Terkadang ada port yang dipesan. Ini adalah saran umum yang baik tetapi bukan jawaban yang benar di Linux.
Jason Newton
18

Untuk memastikan kernel tidak akan memberikan 49000 dan 49001 kepada klien karena Anda ingin menggunakannya untuk server Anda di linux.

sysctl -w net.ipv4.ip_local_reserved_ports = 49000, 49001

jatuhkan /etc/sysctl.conf, lalu jalankan sysctl -p.

Perhatikan bahwa ini belum diuji.

Referensi

Hal Ashburner
sumber
Saya mencoba ini, tetapi juga mencegah aplikasi saya sendiri menggunakan port! Bagaimana dengan mendefinisikan nomor port dengan nama /etc/services?
@ user134197 Ini seharusnya tidak mencegah aplikasi Anda menggunakan port tersebut jika Anda secara eksplisit menggunakan nomor port bukan nol dalam permintaan bind Anda. Ini bekerja untuk saya.
Mark Lakata
15

Sebenarnya, jawaban di atas tidak sepenuhnya akurat. Sysctls net.inet.ip.portrange.first dan net.inet.ip.portrange.last menentukan kisaran port yang dapat dialokasikan OS untuk port acak. Anda ingin memastikan bahwa kisaran port yang dipesan untuk aplikasi Anda tidak termasuk dalam variabel-variabel ini.

Lihatlah di FreeBSD Handbook, bagian: 12.14. Batas Tuning Kernel . Tetapi premis dasar yang sama harus berlaku untuk Linux juga.

MattK
sumber
Juga, tautan ini dapat membantu: stackoverflow.com/questions/913501/…
MattK
3
Saya pikir di Linux namanyanet.ipv4.ip_local_port_range
Brian Gordon