Uh, moje współczucia – temat portów jest historycznie bardzo bardzo źle opisywany na stronach dla początkujących, i do tego zazwyczaj od złej strony.
W zasadzie pytania są dwa:
1. Czym jest "port"?
2. Dlaczego pewne rzeczy często są na pewnych portach?
Zaczynając od tego pierwszego, ale trochę na około: żeby wyjaśnić czym jest port trzeba wyjaśnić czym jest socket (gniazdko).
Otóż jak masz program/aplikację uruchomioną na komputerze, i ta aplikacja chce porozmawiać z czymś po sieci (a czasem nawet w obrębie tego samego komputera), to musi utworzyć socket. Tych socketów jest kilka rodzajów, ale zazwyczaj interesują nas albo sockety TCP albo sockety UDP. Te drugie pominę i wrócę do nich później.
Socketów TCP są de facto dwa rodzaje: nasłuchujące, tudzież odbierające (listen, wyobraź sobie gniazdko w ścianie), oraz łączące się gdzieś (connect, wyobraź sobie kabel z wtyczką).
Jak mówimy o "otwartych portach" w kontekście TCP, to mówimy o tym pierwszym rodzaju, tj. socketach nasłuchujących (gniazdkach w ścianie).
I teraz na potrzeby dyskusji wyobraźmy sobie taki przykład: mamy komputer, który ma dwie aplikacje, i każda stworzyła sobie nasłuchujące "gniazdko" (listening socket). Chcemy się połączyć do konkretnej z nich, więc przychodzimy z kablem z wtyczką, i... e... nie wiemy które gniazdko jest od której aplikacji.
I tutaj właśnie z pomocą pojawiają się porty :)
Otóż port to po prostu numer od 0 do 65535, który identyfikuje gniazdko z zewnątrz.
Wracając do poprzedniego przykładu, jeśli mamy te dwie aplikacje, to obie podczas tworzenia swoich socketów nasłuchujących muszą przypisać im (bind) konkretne porty (formalnie: porty źródłowe) zanim zaczną na nich nasłuchiwać (odbierać połączenia). Jedna z nich może np. powiedzieć "ja chcę, żeby moje gniazdko nasłuchiwało na porcie 80 (tj. było identyfikowane numerem 80)", a druga "a ja chcę, żeby moje było na porcie 1234 (tj. było identyfikowane numerem 1234)".
I teraz jak podchodzimy z "wtyczką", na której zresztą też napisaliśmy port (formalnie: port docelowy), to system operacyjny weźmie od nas tą "wtyczkę" i połączy ją z gniazdkiem (a więc i z aplikacją) o odpowiednim numerze.
Bardziej formalnie (ale nadal w uproszczeniu!): każdy sieciowy pakiet typu TCP ma zapisane w sobie dwa numery: port docelowy, oraz port źródłowy. Jak stos sieciowy w systemie operacyjnym dostanie taki pakiet, to (w uproszczeniu) patrzy na to która aplikacja zrobiła gniazdko (socket) o porcie źródłowym równym portowi docelowemu pakietu, i przekazuje dane z tego pakietu do tej aplikacji.
Czyli jeszcze raz: port to po prostu numer gniazdka, do którego dopasowywane są numery portu docelowego w przychodzących pakietach sieciowych typu TCP.
W UDP to działa bardzo podobnie – port to też numer od 0 do 65535 (przy czym porty UDP i TCP to są oddzielne numeracje, stąd zawsze podaje się oba, np. "tcp 22" albo" udp 53"), tylko nie ma rozróżnienia na "gniazdka" (sockety nasłuchujące) i "wtyczki" (sockety łączące) – wszystkie gniazdka są typu "i gniazdko i wtyczka" ;)
I teraz tak. Wszystko to co napisałem to pewne uproszczenia. W szczególności muszę zwrócić uwagę na:
- w TCP najpierw musi być nawiązane połączenie, co de facto powoduje utworzenie dodatkowego "połączonego gniazdka", do którego pakiety dopasowywane są nie po porcie docelowym, a po parze "port docelowy, port źródłowy nadawcy"; w UDP jest podobnie ale nie są tworzone osobne gniazdka
- porty są de facto nie per komputer, a per interfejs sieciowy; tj. możemy mieć dwie różne aplikacje w systemie na porcie "tcp 22", pod warunkiem, że są na różnych interfejsach sieciowych (np. nasłuchują na różnych kartach sieciowych).
I tak oto przechodzimy do drugiego pytania - tj. czemu na tcp 80 mamy HTTP, i tak dalej.
W skrócie: bo tak się umówiliśmy ;)
Ponieważ porty to tylko liczby, to aplikacja może sobie wybrać dowolny port na którym chce nasłuchiwać (drobna uwaga: pod linuxem tylko appki z uprawnieniami roota mogą nasłuchiwać na portach poniżej 1024, ale to systemowe ograniczenie).
To powiedziawszy, jest sobie organizacja, która się nazywa IANA (Internet Assigned Numbers Authority), do której można się zgłosić, i powiedzieć "ten konkretny protokół/aplikacja powinna mieć nadany jakiś stały port, żeby nie było zamieszania". No i przez ostatnie kilka dekad trochę różnych ludzi się do nich zgłosiło i powpisywali różne rzeczy na listę.
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
Stąd na przykład HTTP (www) jest kojarzony z portem tcp 80, chociaż w praktyce serwer HTTP może stać (nasłuchiwać) na dowolnym porcie. Często porty HTTP znajduje się też np. na 8080, albo 8888 – głównie na serwerach testowych / deweloperskich.
Oczywiście jakieś 99% aplikacji/protokołów nigdy nie jest wpisywana na tę listę. Tylko te bardziej otwarte są. Stąd też nie znajdzie się tam praktycznie żadnych portów od serwerów gier, itp.
Co za tym idzie:
- Jeśli wiemy, że coś nasłuchuje na porcie 80, to to prawdopodobnie (ale NIE "na pewno") będzie serwer HTTP, bo te w 99.9% przypadków stoją własnie na porcie 80.
- Ale, jest też szansa, że na tym porcie sobie stoi coś innego. Do póki się nie połączony i nie wejdziemy z tym czymś w interakcje (tj. nie wyślemy zapytania HTTP i nie dostaniemy poprawnej odpowiedzi), to się tego nie dowiemy.
- Co więcej, serwer HTTP (ba, ten sam serwer HTTP) może też stać na porcie 44444, bo czemu nie.
- Przykładowo, często admini zmieniają domyślny port SSH (tcp 22) na cokolwiek innego, bo jest strasznie dużo botów skanujących ten port, i śmiecą w logach. Co za tym idzie, SSH można znaleźć na bardzo losowych portach.
Zdarza się, że niektóre rodziny malware też sobie jakiś tam port upodobają, i czekają na połączenia właśnie na tym a nie innym porcie (chociaż większość malware się po prostu łączy do C2, tj. serwerów sterowania, zamiast nasłuchiwać na jakichś portach).
No i teraz dochodzimy do tego mitycznego "każdy otwarty port to wektor ataku" i "należy zamykać wszystkie porty".
Po pierwsze, jeśli żadna aplikacja nie stworzyła "gniazdka" (socketu nasłuchującego) na interfejsie połączonym do internetu na danym porcie, to ten port po prostu będzie nieresponsywny. Tj. nic nie będzie na nim "nasłuchiwać", więc nie jest to zupełnie groźne. To powiedziawszy, w szczelnych sieciach nieużywane porty się blokuje, żeby np. jakiś malware nie mógł na nich skutecznie nasłuchiwać ;)
Po drugie, nawet jeśli jakaś aplikacja będzie nasłuchiwać na jakimś otwartym dla świata porcie, to nie znaczy jeszcze, że można ją skutecznie zaatakować. Może można, może nie, jest to zupełnie inny i dużo głębszy temat. Jedyne co można powiedzieć, to że pewnie da się z nią wejść w jakąś interakcję. Czy to coś atakującemu da, to bardzo bardzo zależy od samej aplikacji, jej implementacji, etc. W praktyce oczywiście czym mniej aplikacji wystawionych "na zewnątrz", tym mniejsza szansa znalezienia jakiejś, w której są jakieś błędy, które można wykorzystać.
Anyway, to co bym zalecał, to praktykę + jeszcze trochę teorii. Tj.:
- ustal na Twoim komputerze jakie aplikacje mają potworzone sockety nasłuchujące (polecenie konsolowe netstat z odpowiednimi parametrami; bodajże -anp i sockety typu "LISTEN" pod Windowsem, i -tuln pod Linuxem, ale sprawdź)
- uruchom wireshark, wybierz protokół TCP, i zobacz jakie pakiety latają; popatrz na ich warstwę TCP i zobacz jakie mają porty źródłowe i docelowe
- rzuć okiem np na wiki jak wygląda nagłówek protokołów TCP oraz UDP, w szczególności znajdź tam pola na porty
- napisz jakiś krótki programik w dowolnym języku, który utworzy socket nasłuchujący na danym porcie i coś tam porobi z nim (np. wypisze wszystko co będzie odbierać); możesz użyć netcat do przetestowania tego, albo napisać programik, który się połączy do tego nasłuchującego socketu :)
Good luck