====== Warstwa transportowa ====== Warstwa **sieci** zapewnia komunikację między dowolnymi **urządzeniami**. \\ Odpowiednie pole pakietu IP wskazuje jaki protokół warstwy transportowej jest używany. Warstwa **transportowa** zapewnia komunikację między **procesami** działającymi na wskazanych urządzeniach. Protokoły warstwy transportowej mogą: * tworzyć połączenia albo przesyłać datagramy (porównaj z połączeniami telefonicznymi i wiadomościami SMS) * przesyłać dane jako strumień bajtów albo jako wiadomości * gwarantować (lub nie) odebranie danych w tej samej kolejności w jakiej były nadane * zapewniać że dane dotrą, a w razie gdyby jakiś pakiet nie dotarł, automatycznie wysłać go ponownie * dostosowywać prędkość wysyłania do możliwości łącza W internecie używa się głównie protokołów TCP i UDP. \\ Poza TCP i UDP jest w użyciu jeszcze kilka protokołów warstwy transportu, np. SCTP, DCCP, MPTCP === Adresacja na warstwie transportowej === Protokoły warstwy transportowej spójnie używają 16-bitowej liczby jako adres. \\ Adres warstwy transportowej nazywa się **numerem portu**. System operacyjny po otrzymaniu wiadomości biorąc pod uwagę: * adresu warstwy sieci (np. IP) źródłowy (zdalny), * adresu warstwy sieci (np. IP) docelowy (lokalny), * użyty protokół warstwy transportowej, * adresu warstwy transportowej (np. port) źródłowy (zdalny), * adresu warstwy transportowej (np. port) docelowy (lokalny),
sprawdza czy wiadomość należy do już istniejącego połączenia (i wtedy dostarcza dane do tego połączenia), a jeśli nie, to czy jakiś program czeka na nowe połączenie / wiadomości pod docelowym adresem IP i docelowym portem użytego protokołu warstwy transportowej. === Klient-serwer === Programy sieciowe zwykle pełnią rolę serwera lub klienta. \\ Serwer to program który czeka (nasłuchuje) na nowe połączenia (lub żądania/wiadomości) od klientów. \\ Klient to program który łączy się do serwera (lub wysyła do niego żądania). \\ Program może jednocześnie pełnić rolę serwera i klienta. Programy pełniące rolę serwera muszą wskazać użyty protokół warstwy transportu i poinformować system operacyjny na jakich adresach IP i numerach portów oczekują połączeń/wiadomości. Program który chce połączyć lub wysłać wiadomość musi podać jaki protokół warstwy transportu ma zostać użyty i podać docelowy adres IP i docelowy numer portu dla połączenia/wiadomości. === Znane numery portów === Konkretne numery portów są zwyczajowo używane do adresowania konkretnych programów. \\ Np. port 80 i 443 jest używany przez serwery stron internetowych, a porty 25, 465 lub 587 przez serwery poczty internetowej (e-mail). \\ Lista takich numery portów, wraz z przypisanymi do nich słownymi nazwami i informacją do czego są (albo były w przeszłości) używane [[http://www.iana.org/assignments/service-names-port-numbers|jest utrzymywana]] przez organizację IANA. \\ W Linuksie dodatkowo taka lista jest tradycyjnie dostępna w pliku ''/etc/services''. === Zakresy numerów portów === Zakres numerów portów jest podzielony na porty [[https://tools.ietf.org/html/rfc6335#section-8.1.2|[RFC6335]]]: * uprzywilejowane (system / well-known / privileged) – 1÷1023 \\ jako lokalne porty mogą być używane tylko przez uprzywilejowanego użytkownika (root / administrator), * //zarejestrowane// ((czy ktoś zna jakieś lepsze tłumaczenie na polski nazwy "user ports" lub "registered ports"?)) (user / registered) – 1024÷49151 \\ mogą zostać zarejestrowane (tzn. przypisane do konkretnego zastosowania w rejestrze utrzymywanym przez IANA), * efemeryczne (dynamic / private / ephemeral) – 49152÷65535 \\ używane kiedy program nie potrzebuje stałego numeru portu (czyli zwykle kiedy program nawiązuje połączenie).
W implementacjach systemów operacyjnych zwykle granica między user ports a ephemeral jest niższa, np. w Linuksie zakres portów efemerycznych można odczytać wykonując jedną z komend:   ''sysctl net.ipv4.ip_local_port_range''   /   ''cat /proc/sys/net/ipv4/ip_local_port_range''. ====== Monitorowanie bieżących połączeń ====== Polecenia ''netstat'' i ''ss'' wyświetlają listę połączeń (nie tylko sieciowych) których stroną jest ten komputer oraz (po podaniu odpowiedniej opcji) informacje na jakich adresach IP i portach programy na tym komputerze czekają na połączenia bądź wiadomości. * ''netstat {|-a|-l} [-t] [-u] [-p] [-n]'' (np. ''netstat -atupn'') * ''ss {|-a|-l} [-t] [-u] [-p] [-n]'' (np. ''ss -atupn'')
Przełączniki dla netstat / ss:
┌      (domyślnie) tylko już nawiązane połączenia
│ -l   nasłuchujące porty (programy czekające aż ktoś do nich się połączy)     
└ -a   nasłuchujące porty + nawiązane połączenia
┌      (domyślnie) wszystkie wspierane protokoły sieciowe
│ -t   połączenia protokołu TCP
└ -u   połączenia protokołu UDP
┌ -4   wybiera IPv4
└ -6   wybiera IPv6
  -p   nazwa i pid programu do którego należy połączenie
  -n   pokazywanie wszystkich wartości numerycznie, np. '22' zamiast 'ssh'
  -W   [tylko netstat] wyłącza przycinanie adresów IP / nazw domenowych do szerokości kolumny
Więcej: netstat -h / ss -h
* ''/proc/net/(tcp|udp|…)'' (np. ''cat /proc/net/tcp'')
# netstat -atunp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      13830/sshd
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      28693/exim4
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      26745/cupsd
tcp        0    780 10.0.1.1:22             150.254.33.66:38126     ESTABLISHED 19424/sshd: usernam
tcp        0      0 10.0.1.1:38596          150.254.30.199:443      ESTABLISHED 19481/weechat
tcp6       0      0 :::22                   :::*                    LISTEN      13830/sshd
udp        0      0 0.0.0.0:68              0.0.0.0:*                           14541/dhclient
udp        0      0 10.0.1.1:53             0.0.0.0:*                           22173/named
udp      768      0 0.0.0.0:35722           0.0.0.0:*                           21533/snmpwalk
====== Testowanie łączności na warstwie aplikacji ====== ===== netcat ===== ''[[https://en.wikipedia.org/wiki/Netcat|netcat]]'' (czasami dostępny jako ''nc'') to szeroko rozpowszechnione narzędzie potrafiące nawiązać proste połączenia sieciowe bądź stworzyć prosty serwer (używając protokołu TCP bądź UDP). \\ Uwaga: netcat ma wiele wersji różniących się możliwościami, przełącznikami i zachowaniem! ^ ^ Serwer ^ Klient ^ | TCP|''nc -l -p //12345//'' |''nc //10.0.0.1// //12345//'' | | UDP|''nc -u -l -p //12345//'' |''nc -u //10.0.0.1// //12345//'' | ===== socat ===== ''[[http://www.dest-unreach.org/socat/|socat]]'' to rozbudowany i wciąż rozwijany program pozwalający testować rozmaite "połączenia" sieciowe. **''socat'' zawsze przyjmuje dwie opcje** – dwa "strumienie" które ze sobą połączy, np. standardowe wejście/wyjście z połączeniem sieciowym. \\ Można też łączyć np. jedno połączenie sieciowe z drugim, czy połączenie sieciowe z programem. ^ ^ Serwer ^ Klient ^ | TCP|''socat TCP-LISTEN:12345 STDIO'' |''socat STDIO TCP:10.0.0.1:12345'' | | UDP (pseudo-połączeniowe)|''socat UDP-LISTEN:12345 STDIO'' |''socat STDIO UDP:10.0.0.1:12345'' | | UDP (zorientowane na wiadomość)|''socat UDP-RECV:12345 STDIO'' |''socat STDIO UDP-SENDTO:10.0.0.1:12345'' | Zamiast ''STDIO'' można podać ''-'' (dodatkowo w większości dystrybucji można też skorzystać z ''readline'') \\ Socat nie rozróżnia wielkości liter, pozwala na skróty – np. ''udp-l'' jako ''udp-listen'' czy ''tcp'' jako ''tcp-connect'' \\ Adresy IPv6 podaje się w nawiasach kwadratowych, np. [::1] ====== Powyżej warstwy transportowej ====== Rola systemu operacyjnego kończy się na zapewnieniu łączności między procesami na wskazanych urządzeniach – na warstwie transportowej. Cała reszta jest w rękach twórcy programu. ===== Połączenia szyfrowane ===== Powszechnie do zapewnienia poufności i integralności komunikacji używa się [[https://en.wikipedia.org/wiki/Transport_Layer_Security|protokołów (D)TLS]]. ==== Testowanie szyfrowanych połączeń z opessl ==== Narzędzie ''openssl'' dostarczane z biblioteką [[https://openssl.org/|OpenSSL]] pozwala testować połączenia szyfrowane. W najprostszej wersji nawiązanie połączenia TLS odbywa się komendą: \\ ''openssl s_client :'' Do uruchomienia serwera potrzeby jest klucz prywatny i certyfikat (klucz publiczny z podpisem zaufanego urzędu certyfikacji). \\ Na podstawie certyfikatu otrzymanego od serwera klient sprawdza czy ufa serwerowi; jeżeli klient nie zna podpisującego certyfikat, serwer uzna za niezaufany. \\ Do wygenerowania dla ćwiczeń klucza prywatnego i certyfikatu możesz użyć komendy: \\ ''openssl req -x509 -newkey rsa:1024 -days 1 -nodes -keyout key.pem -out cert.pem'' \\ W najprostszej wersji stworzenie serwera odbywa się komendą: \\ ''openssl s_server -key key.pem -cert cert.pem -accept '' ==== Testowanie szyfrowanych połączeń z socat ==== Program ''socat'' również pozwala na nawiązanie połączeń z użyciem TLS. W najprostszej wersji nawiązanie połączenia TLS odbywa się komendą: \\ ''socat openssl:: STDIO'' \\ lub, bez sprawdzania poprawności certyfikatu: ''socat openssl::,verify=0 STDIO'' W najprostszej wersji stworzenie serwera odbywa się komendą: \\ ''socat openssl-listen:,key=key.pem,cert=cert.pem,verify=0 -'' \\ (W serwerze ''verify=0'' wyłącza wymaganie i sprawdzanie certyfikatu klienta.) ====== Przykładowe aplikacje ====== ===== Zapytania do serwerów stron internetowych ===== Protokół HTTP definiuje różne metody, z których przeglądarki używają głównie GET i POST. Wersje HTTP do 2.0 włącznie używają protokołu tekstowego. W protokole HTTP każde żądanie (i odpowiedź) składa się z linii żądania (statusu) i nagłówków (każdy w osobnej linii), po których następuje pusta linia (''"\r\n\r\n"'') i, jeżeli jest, treść żądania (bądź odpowiedzi). \\ Długość treści żądania/odpowiedzi (jeśli jest obecna) zwykle wskazuje nagłówek ''Content-Length''. === Ręcznie === Treść minimalnego zapytania HTTP w wersji 1.1:
GET / HTTP/1.1 Host: Np. żeby pobrać zasób ''%%https://bip.put.poznan.pl/artykuly/status-politechniki-poznanskiej-2020-2024%%'',\\ można połączyć się z szyfrowaniem TLS pod adres ''bip.put.poznan.pl'' i port ''443'' (domyślny dla ''%%https://%%'') i wysłać zapytanie:
GET /artykuly/status-politechniki-poznanskiej-2020-2024 HTTP/1.0 Host: bip.put.poznan.pl
=== wget / curl === Narzędzia ''wget'' i ''curl'' pozwalają automatycznie wysłać żądanie HTTP. \\ ''wget'' domyślnie podąża za przekierowaniami i zapisuje odpowiedź do pliku. \\ ''curl'' domyślnie nie podąża za przekierowaniami i wypisuje odpowiedź na standardowe wyjście. \\ Odpowiednimi przełącznikami można zmieniać zachowanie programów, np. ''curl -v '' wyświetli pełną treść wysłanego żądania z nagłówkami pełną odpowiedź (a nie tylko jej treść). ++++ Przykład żądania POST | Do testów, umieść poniższy plik w pustym katalogu i wykonaj z tego katalogu (z roota) komendę ''php -S 0:80''
Przykład minimalnego żądania (bez wskazania przez nagłówek ''Content-Type'' jakiego typu dane są wysyłane): POST / HTTP/1.1 Host: localhost Content-length: 12 Hello world! Przykładowa komenda ''curl'' do wysłania żądania POST: \\ ''curl --verbose --data "Hello curl!" %%http://localhost%%'' Przykładowe komendy ''wget'' do wysłania żądania POST: \\ ''wget -SqO - --post-data "Hello wget!" %%http://localhost%%'' \\ ''wget -dqO - --post-data "Hello wget!" %%http://localhost%%'' ++++ ===== [ekstra] Rozmowa z serwerem pocztowym ===== Poglądowe minimalistyczne komendy i komunikaty potrzebne do wysłania i odebrania wiadomości e-mail. === SMTP – wysyłanie maili === Komendy do połączenia z serwerem SMTP (do wyboru):
socat tcp::25,crlf stdio openssl s_client -crlf -starttls smtp :25 openssl s_client -crlf :465 Kolejne linie potrzebne do wysłania maila:
helo mail from: rcpt to: data Date: From: To: Subject: . quit
Dodanie poniższych linii po ''helo'' (bądź ''ehlo'') uwierzytelni użytkownika:
auth plain \0" | base64'> === IMAP – odbieranie maili === Komendy do szyfrowanego połączenia z serwerem IMAP (do wyboru):
openssl s_client -crlf -starttls imap :143 openssl s_client -crlf :993 Kolejne linie do pobrania (kawałka) maila:
A login B select inbox C search unseen D fetch BODY.PEEK[HEADER.FIELDS (SUBJECT DATE FROM)] QUIT