Nasłuchiwanie TCP / HTTP na portach: jak wielu użytkowników może współużytkować ten sam port
Więc co się dzieje, gdy serwer nasłuchuje połączeń przychodzących na porcie TCP? Na przykład, powiedzmy, że masz serwer WWW na porcie 80. Załóżmy, że Twój komputer ma publiczny adres IP 24.14.181.229, a osoba, która próbuje się z tobą połączyć, ma adres IP 10.1.2.3. Ta osoba może się z Tobą połączyć, otwierając gniazdo TCP pod numer 24.14.181.229:80. Wystarczająco proste.
Intuicyjnie (i niesłusznie) większość ludzi zakłada, że wygląda to mniej więcej tak:
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.
Jest to intuicyjne, ponieważ z punktu widzenia klienta ma on adres IP i łączy się z serwerem pod adresem IP: PORT. Skoro klient łączy się z portem 80, to jego port też musi mieć 80? To rozsądna rzecz, aby pomyśleć, ale tak naprawdę nie to, co się dzieje. Gdyby to było poprawne, moglibyśmy obsługiwać tylko jednego użytkownika na obcy adres IP. Gdy komputer zdalny się połączy, wtedy połączy port 80 z portem 80 i nikt inny nie będzie mógł się połączyć.
Należy zrozumieć trzy rzeczy:
1.) Na serwerze proces nasłuchuje na porcie. Gdy uzyska połączenie, przekazuje je innemu wątkowi. Komunikacja nigdy nie blokuje portu nasłuchującego.
2.) Połączenia są jednoznacznie identyfikowane przez system operacyjny za pomocą następujących 5 krotek: (lokalny-IP, lokalny-port, zdalny-IP, zdalny-port, protokół). Jeśli jakikolwiek element w krotce jest inny, jest to całkowicie niezależne połączenie.
3.) Kiedy klient łączy się z serwerem, wybiera losowy, nieużywany port źródłowy wysokiego rzędu . W ten sposób pojedynczy klient może mieć do ~ 64 tys. Połączeń z serwerem dla tego samego portu docelowego.
Tak więc tak naprawdę powstaje, gdy klient łączy się z serwerem:
Local Computer | Remote Computer | Role
-----------------------------------------------------------
0.0.0.0:80 | <none> | LISTENING
127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED
Patrząc na to, co się właściwie dzieje
Najpierw użyjmy netstat, aby zobaczyć, co się dzieje na tym komputerze. Będziemy używać portu 500 zamiast 80 (ponieważ na porcie 80 dzieje się cała masa rzeczy, ponieważ jest to port wspólny, ale funkcjonalnie nie robi to różnicy).
netstat -atnp | grep -i ":500 "
Zgodnie z oczekiwaniami dane wyjściowe są puste. Teraz uruchommy serwer WWW:
sudo python3 -m http.server 500
Oto wynik ponownego uruchomienia netstata:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
Więc teraz istnieje jeden proces, który aktywnie nasłuchuje (stan: LISTEN) na porcie 500. Lokalny adres to 0.0.0.0, co oznacza kod „nasłuchiwania wszystkich adresów IP”. Łatwym błędem jest nasłuchiwanie tylko na porcie 127.0.0.1, który akceptuje tylko połączenia z bieżącego komputera. Więc to nie jest połączenie, to po prostu oznacza, że proces zażądał powiązania () z adresem IP portu, a ten proces jest odpowiedzialny za obsługę wszystkich połączeń do tego portu. Wskazuje to na ograniczenie polegające na tym, że na jeden komputer może nasłuchiwać tylko jeden proces na porcie (istnieją sposoby obejścia tego problemu za pomocą multipleksowania, ale jest to znacznie bardziej skomplikowany temat). Jeśli serwer WWW nasłuchuje na porcie 80, nie może współdzielić tego portu z innymi serwerami WWW.
Więc teraz połączmy użytkownika z naszą maszyną:
quicknet -m tcp -t localhost:500 -p Test payload.
Jest to prosty skrypt ( https://github.com/grokit/quickweb ), który otwiera gniazdo TCP, wysyła ładunek (w tym przypadku „Ładunek testowy”), czeka kilka sekund i rozłącza się. Ponowne wykonanie netstat w tym czasie powoduje wyświetlenie następujących informacji:
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 -
Jeśli połączysz się z innym klientem i ponownie wykonasz netstat, zobaczysz następujące informacje:
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 -
... to znaczy klient użył innego losowego portu do połączenia. Dlatego nigdy nie ma pomyłki między adresami IP.