TCP có thể cung cấp nhiều hơn 65535 cổng không?


50

Có thể thiết lập một hệ thống Linux để nó cung cấp hơn 65.535 cổng không? Mục đích sẽ là có hơn 65 nghìn daemon nghe trên một hệ thống nhất định.

Rõ ràng có những cổng đang được sử dụng vì vậy những điều này là không thể, vì vậy, hãy nghĩ đây là một bài tập lý thuyết trong việc cố gắng hiểu nơi TCP sẽ bị hạn chế khi làm điều gì đó như thế này.


11
Động lực cho câu hỏi này là gì? Tại sao bạn muốn có nhiều daemon nghe?
Warren Young

1
Ngoài ra, bạn sẽ có một thời gian khó khăn để bắt đầu nhiều quá trình. (Tôi giả sử bạn có nghĩa là một quy trình cho mỗi daemon.)
Warren Young

13
Mặc dù không có gì chính thức hạn chế bạn mặc 65 chiếc quần cùng một lúc, nhưng sẽ thật ngu ngốc khi thử. Nếu bạn có thể chỉ cho tôi một cỗ máy có thể xử lý đồng thời 10.000 cổng TCP, thì đây có thể là một câu hỏi trừu tượng thú vị.
msw

13
Bản chất của Q này là hoàn toàn trên lý thuyết, không có mục đích nào ngoài mục đích tìm hiểu các hạn chế của TCP & # của các cổng.
slm

1
Mặc dù vậy, vấn đề là bạn đã thực hiện nó theo cách liên kết nó với các vấn đề thực tế khác nhau liên quan đến không gian RAM được yêu cầu bởi các quy trình 64k + daemon. Bất kỳ máy nào bạn có khả năng sẽ có ngay bây giờ hoặc trong thập kỷ tới hoặc lâu hơn sẽ hết RAM trước khi bạn đạt đến giới hạn người nghe. Nếu bạn viết lại câu hỏi chỉ nói về người nghe TCP , bỏ hoàn toàn cuộc nói chuyện về daemon, vấn đề đó sẽ biến mất. Ví dụ, bạn có thể khấu hao không gian ngăn xếp bằng cách gán một nghìn ổ cắm cho mỗi trình nền hướng sự kiện đơn luồng.
Warren Young

Câu trả lời:


84

Nhìn vào RFC cho TCP: RFC 793 - Giao thức điều khiển truyền dẫn , câu trả lời dường như là không vì thực tế là tiêu đề TCP bị giới hạn ở 16 bit cho trường cổng nguồn / đích.

    ss # 1

IPv6 có cải thiện mọi thứ không?

Không. Mặc dù IPv6 sẽ cung cấp cho chúng tôi không gian địa chỉ IP lớn hơn nhiều, 32 bit so với 128 bit, nhưng nó không cố gắng cải thiện giới hạn gói TCP là 16 bit cho số cổng. Điều thú vị là RFC cho IPv6: Đặc tả giao thức Internet, Phiên bản 6 (IPv6) , trường IP cần được mở rộng.

Khi TCP chạy trên IPv6, phương thức được sử dụng để tính toán tổng kiểm tra được thay đổi, theo RFC 2460 :

Bất kỳ giao thức hoặc giao thức lớp trên nào khác bao gồm các địa chỉ từ tiêu đề IP trong tính toán tổng kiểm tra của nó phải được sửa đổi để sử dụng qua IPv6, để bao gồm các địa chỉ IPv6 128 bit thay vì địa chỉ IPv4 32 bit.

                 ss # 2

Vì vậy, làm thế nào bạn có thể nhận được nhiều cổng hơn?

Một cách tiếp cận sẽ là xếp chồng các địa chỉ IP bổ sung bằng cách sử dụng nhiều giao diện hơn. Nếu hệ thống của bạn có nhiều NIC thì điều này dễ dàng hơn, nhưng ngay cả chỉ với một NIC, người ta có thể sử dụng các giao diện ảo (còn gọi là bí danh ) để phân bổ nhiều IP hơn nếu cần.

LƯU Ý: Sử dụng bí danh đã được thay thế bằng cách iproute2bạn có thể sử dụng để xếp chồng địa chỉ IP trên một giao diện duy nhất (ví dụ eth0).

Thí dụ

$ sudo ip link set eth0 up
$ sudo ip addr add 192.0.2.1/24 dev eth0
$ sudo ip addr add 192.0.2.2/24 dev eth0
$ ip addr show dev eth0
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc
      pfifo_fast state DOWN qlen 1000
    link/ether 00:d0:b7:2d:ce:cf brd ff:ff:ff:ff:ff:ff
    inet 192.0.2.1/24 brd 192.0.2.255 scope global eth1
    inet 192.0.2.2/24 scope global secondary eth1

Nguồn: iproute2: Cuộc sống sau ifconfig

Người giới thiệu


3
Không thể chọn trong số 65.536+ trình nền chỉ sử dụng cổng đích, nhưng nếu một người có bộ nhớ và băng thông không giới hạn, có thể có hơn 32.000 kết nối với mỗi địa chỉ TCP riêng biệt trên mỗi cổng đến.
supercat

7

Có thể thiết lập một hệ thống Linux để nó cung cấp hơn 65.535 cổng không?

Không.

Mục đích sẽ là có hơn 65 nghìn daemon nghe trên một hệ thống nhất định.

Sau đó, bạn cần:

  • một iptablescấu hình chuyển hướng trên nội dung lưu lượng hoặc

  • một "dịch vụ môi giới dịch vụ" hoặc "dịch vụ đa kênh" sẽ chấp nhận các kết nối đến trên một cổng duy nhất và định tuyến nó đến daemon thích hợp "đằng sau nó". Nếu bạn muốn các giao thức chuẩn vượt qua không được sửa đổi, bạn có thể phải thực hiện đánh hơi / nhận dạng giao thức trong dịch vụ ghép kênh này, theo cách thức mà tường lửa IDS hoặc lớp 7 sẽ phá hủy; hoàn toàn có thể với phần lớn các giao thức.

Mỗi mục thứ hai, bạn có thể thiết kế dịch vụ này để xử lý hơn 2 ^ 16 "cổng" nếu bạn thực sự muốn. Tôi chắc chắn rằng tác động hiệu suất sẽ là tối thiểu so với tải của 2 ^ 16 + người nghe đang chạy.

Daemon trong Linux có thể lắng nghe các socket unix tồn tại trong hệ thống tập tin, vì vậy "dịch vụ ghép kênh" của bạn có thể duy trì ánh xạ bên trong của cổng ngoài <-> socket unix bên trong. Bạn có thể sẽ chạy vào giới hạn quy trình kernel (quy trình 32Kbyte?) Trước khi hết inodes trên bất kỳ hệ thống tập tin hiện đại nào.


Tôi đã đánh giá thấp điều này bởi vì bạn nói rằng điều đó là không thể, sau đó tiếp tục giải thích cách thực hiện bằng nhiều IP và cân bằng tải, mặc dù theo cách bùng binh rất khó hiểu.
suprjami

2
Hơn 64K cổng trên một hệ thống là không thể. Có thể có hơn 64K người nghe , nhưng bạn phải có proxy hoặc người nghe frontend sẽ "phân tách" các kết nối đến với người nghe "phụ trợ" thực sự. Bạn có thể làm một cái gì đó điên rồ như một NAT nội bộ cho nhiều địa chỉ IP nội bộ, ví dụ.
LawrenceC

2
Sai lầm. Mọi người đã quản lý để có được nửa triệu kết nối đồng thời trên một hệ thống. Có, cần có nhiều IP và bộ cân bằng tải (không nhất thiết phải trên cùng một hệ thống), nhưng một hệ thống duy nhất có thể mở hơn 64k cổng và thậm chí hơn 64k người nghe nếu được thực hiện đúng.
suprjami

2

Chỉ vì không có câu trả lời hay mà tôi muốn hô vang.

Một cách để làm điều này là thêm một tùy chọn IP chỉ định phần mở rộng cổng. Tùy chọn phải được thiết kế để phù hợp với phần tùy chọn của tiêu đề IP và sẽ bị bỏ qua bởi các bước không xác định.

Bạn sẽ sử dụng tùy chọn này và đó là thông tin thông tin để mở rộng nguồn, đích hoặc cả hai số cổng.

Các giới hạn sẽ không tự động hoạt động trong phần mềm hiện có chỉ bằng cách thêm tùy chọn, chúng sẽ phải được viết lại để tận dụng tùy chọn cho dù nó được triển khai như thế nào, phần mềm và tường lửa hiện tại sẽ bỏ qua gói hoặc xử lý như bình thường sử dụng giá trị trong các trường cổng nguồn và đích.

Nói tóm lại, không dễ thực hiện và sẽ được thực hiện tốt hơn bằng cách sử dụng một trình nghe và dữ liệu có thể tái sử dụng duy nhất có trong tải trọng của gói.

Bạn cũng có thể dễ dàng cho phép tái sử dụng cổng trong phần mềm, điều này có thể giúp khắc phục hạn chế này bằng cách sử dụng lại các cổng của máy chủ cho nhiều kết nối máy khách.

Ví dụ, Rtsp có thể sử dụng tiêu đề SessionId kết hợp với nhiều tiêu đề khác trong tải trọng của gói IP để xác định kết nối mà yêu cầu được đưa ra và hành động tương ứng, ví dụ như nếu ổ cắm mà tin nhắn được gửi không giống với ổ cắm địa chỉ từ xa mà phiên tương ứng sau đó người ta có thể cho phép phiên được cập nhật với ổ cắm mới để xử lý, từ chối tin nhắn hoặc một loạt các hành động khác tùy thuộc vào ứng dụng.

Một máy chủ http cũng có thể làm điều này hoặc bất kỳ loại máy chủ nào khác.

Điều quan trọng cần nhớ khi cho phép tái sử dụng các cổng là bạn cũng phải tính đến địa chỉ IP nguồn.


-2

Có bạn có thể!

Nó đã được thực hiện trước đây, ví dụ như máy chủ mã hóa Edgehill, có> 25.000.000 deamons chạy trực tuyến.


9
Cân nhắc mở rộng câu trả lời của bạn để bao gồm một số hướng dẫn về cách OP có thể thực hiện điều này, tài liệu hỗ trợ câu trả lời hoặc giải thích liên quan của bạn.
HalosGhost

Bạn có thể cung cấp tài liệu tham khảo cho tuyên bố này? Một tìm kiếm nhanh khiến tôi tin rằng bất cứ thứ gì nó được phân phối trên nhiều máy.
Thomas Guyot-Sionnest
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.