Nghe TCP / HTTP trên các cổng: Làm thế nào nhiều người dùng có thể chia sẻ cùng một cổng
Vì vậy, điều gì sẽ xảy ra khi máy chủ lắng nghe các kết nối đến trên cổng TCP? Ví dụ: giả sử bạn có máy chủ web trên cổng 80. Giả sử rằng máy tính của bạn có địa chỉ IP công cộng là 24.14.181.229 và người cố gắng kết nối với bạn có địa chỉ IP 10.1.2.3. Người này có thể kết nối với bạn bằng cách mở ổ cắm TCP tới 24.14.181.229:80. Đủ đơn giản.
Theo trực giác (và sai), hầu hết mọi người đều cho rằng nó trông giống như sau:
Local Computer | Remote Computer
--------------------------------
<local_ip>:80 | <foreign_ip>:80
^^ not actually what happens, but this is the conceptual model a lot of people have in mind.
Điều này là trực quan, vì từ quan điểm của khách hàng, anh ta có địa chỉ IP và kết nối với máy chủ tại IP: PORT. Vì máy khách kết nối với cổng 80, thì cổng của anh ta cũng phải là 80? Đây là một điều hợp lý để nghĩ, nhưng thực tế không phải là những gì xảy ra. Nếu điều đó là chính xác, chúng tôi chỉ có thể phục vụ một người dùng cho mỗi địa chỉ IP nước ngoài. Khi một máy tính từ xa kết nối, anh ta sẽ chuyển kết nối cổng 80 sang cổng 80 và không ai khác có thể kết nối.
Ba điều phải được hiểu:
1.) Trên máy chủ, một tiến trình đang lắng nghe trên một cổng. Khi nó có kết nối, nó sẽ chuyển nó sang một chuỗi khác. Giao tiếp không bao giờ bị kẹt cổng nghe.
2.) Các kết nối được HĐH xác định duy nhất bởi 5 bộ sau: (local-IP, local-port, remote-IP, remote-port, protocol). Nếu bất kỳ phần tử nào trong tuple khác nhau, thì đây là một kết nối hoàn toàn độc lập.
3.) Khi một máy khách kết nối với một máy chủ, nó sẽ chọn một cổng nguồn bậc cao ngẫu nhiên, không được sử dụng . Bằng cách này, một máy khách có thể có tối đa ~ 64k kết nối đến máy chủ cho cùng một cổng đích.
Vì vậy, đây thực sự là những gì được tạo ra khi máy khách kết nối với máy chủ:
Local Computer | Remote Computer | Role
-----------------------------------------------------------
0.0.0.0:80 | <none> | LISTENING
127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED
Nhìn vào những gì thực sự xảy ra
Đầu tiên, hãy sử dụng netstat để xem những gì đang xảy ra trên máy tính này. Chúng tôi sẽ sử dụng cổng 500 thay vì 80 (vì có rất nhiều thứ đang xảy ra trên cổng 80 vì nó là một cổng thông thường, nhưng về mặt chức năng thì nó không tạo ra sự khác biệt).
netstat -atnp | grep -i ":500 "
Như mong đợi, đầu ra là trống. Bây giờ hãy bắt đầu một máy chủ web:
sudo python3 -m http.server 500
Bây giờ, đây là kết quả của việc chạy lại netstat:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
Vì vậy, bây giờ có một quá trình đang tích cực lắng nghe (Trạng thái: LISTEN) trên cổng 500. Địa chỉ cục bộ là 0.0.0.0, là mã để "lắng nghe tất cả các địa chỉ ip". Một sai lầm dễ mắc phải là chỉ nghe trên cổng 127.0.0.1, cổng này sẽ chỉ chấp nhận các kết nối từ máy tính hiện tại. Vì vậy, đây không phải là một kết nối, điều này chỉ có nghĩa là một quá trình được yêu cầu để ràng buộc () với IP của cổng và quá trình đó chịu trách nhiệm xử lý tất cả các kết nối đến cổng đó. Điều này cho thấy hạn chế rằng chỉ có thể có một quá trình cho mỗi máy tính lắng nghe trên một cổng (có nhiều cách để giải quyết vấn đề đó bằng cách sử dụng ghép kênh, nhưng đây là một chủ đề phức tạp hơn nhiều). Nếu một máy chủ web đang nghe trên cổng 80, nó không thể chia sẻ cổng đó với các máy chủ web khác.
Vì vậy, bây giờ, hãy kết nối người dùng với máy của chúng tôi:
quicknet -m tcp -t localhost:500 -p Test payload.
Đây là một tập lệnh đơn giản ( https://github.com/grokit/quickweb ) mở một ổ cắm TCP, gửi tải trọng ("Kiểm tra tải trọng." Trong trường hợp này), đợi một vài giây và ngắt kết nối. Thực hiện lại netstat trong khi điều này đang xảy ra sẽ hiển thị như sau:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED -
Nếu bạn kết nối với một ứng dụng khách khác và thực hiện lại netstat, bạn sẽ thấy như sau:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED -
... tức là máy khách đã sử dụng một cổng ngẫu nhiên khác cho kết nối. Vì vậy, không bao giờ có sự nhầm lẫn giữa các địa chỉ IP.