praca_magisterska/pytania/odpowiedzi/08-tcp-three-way-handshake.md

434 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Pytanie 8: TCP Three-Way Handshake
## Pytanie
**"Jaki jest cel uzgadniania trójetapowego (three way handshake) w protokole TCP? Jaka jest interpretacja numerów sekwencyjnych i potwierdzenia? Jaka jest wartość początkowa numeru sekwencyjnego?"**
Przedmiot: SKM (Sieci Komputerowe)
---
## 📚 Odpowiedź główna
### Wprowadzenie do TCP
**TCP (Transmission Control Protocol)** to protokół warstwy transportowej zapewniający:
- Niezawodne dostarczanie danych
- Kontrolę przepływu
- Kontrolę przeciążenia
- Połączeniowość (connection-oriented)
---
## 1. Three-Way Handshake - cel i przebieg
### Cele uzgadniania trójetapowego
1. **Nawiązanie połączenia** - obie strony zgadzają się na komunikację
2. **Synchronizacja numerów sekwencyjnych** - ISN (Initial Sequence Number)
3. **Uzgodnienie parametrów** - MSS, Window Scale, SACK, Timestamps
4. **Weryfikacja dostępności** - obie strony są aktywne i gotowe
### Przebieg (diagram)
```
Klient Serwer
│ │
│ (1) SYN, seq=x │
│──────────────────────────────────────────→│
│ │
│ (2) SYN+ACK, seq=y, ack=x+1 │
│←──────────────────────────────────────────│
│ │
│ (3) ACK, seq=x+1, ack=y+1 │
│──────────────────────────────────────────→│
│ │
│ [POŁĄCZENIE NAWIĄZANE] │
│ │
```
### Szczegółowy opis kroków
#### Krok 1: SYN (Synchronize)
```
Klient → Serwer:
┌────────────────────────────────────────┐
│ Flaga: SYN = 1 │
│ Sequence Number: x (ISN klienta) │
│ Acknowledgment Number: 0 (nieistotny) │
│ Opcje: MSS, Window Scale, SACK, etc. │
└────────────────────────────────────────┘
```
- Klient inicjuje połączenie
- Wysyła swój ISN (Initial Sequence Number)
- Stan klienta: SYN_SENT
#### Krok 2: SYN-ACK (Synchronize-Acknowledge)
```
Serwer → Klient:
┌────────────────────────────────────────┐
│ Flagi: SYN = 1, ACK = 1 │
│ Sequence Number: y (ISN serwera) │
│ Acknowledgment Number: x + 1 │
│ Opcje: MSS, Window Scale, etc. │
└────────────────────────────────────────┘
```
- Serwer potwierdza otrzymanie SYN (ACK = x+1)
- Serwer wysyła swój ISN
- Stan serwera: SYN_RECEIVED
#### Krok 3: ACK (Acknowledge)
```
Klient → Serwer:
┌────────────────────────────────────────┐
│ Flaga: ACK = 1 │
│ Sequence Number: x + 1 │
│ Acknowledgment Number: y + 1 │
└────────────────────────────────────────┘
```
- Klient potwierdza otrzymanie SYN serwera
- Połączenie nawiązane (ESTABLISHED)
- Może zawierać już dane (TCP Fast Open)
---
## 2. Numery sekwencyjne (Sequence Numbers)
### Interpretacja
**Sequence Number (SEQ)** = numer pierwszego bajtu danych w segmencie
```
Strumień danych:
Bajty: [0][1][2][3][4][5][6][7][8][9][10][11][12]...
Segment 1: SEQ=0, dane = bajty 0-4 (5 bajtów)
Segment 2: SEQ=5, dane = bajty 5-9 (5 bajtów)
Segment 3: SEQ=10, dane = bajty 10-12 (3 bajty)
```
### Funkcje numerów sekwencyjnych
| Funkcja | Opis |
|---------|------|
| **Kolejność** | Odbiorca składa segmenty we właściwej kolejności |
| **Wykrywanie duplikatów** | Ten sam SEQ = duplikat |
| **Wykrywanie braków** | Luka w SEQ = brakujący segment |
| **Potwierdzanie** | ACK wskazuje oczekiwany następny SEQ |
### Przykład transmisji
```
Klient (ISN=1000) Serwer (ISN=5000)
│ │
│ SEQ=1000, "Hello" (5 bytes) │
│────────────────────────────────────→│
│ │
│ SEQ=5000, ACK=1005, "Hi" (2 bytes) │
│←────────────────────────────────────│
│ │
│ SEQ=1005, ACK=5002, "World" (5 b) │
│────────────────────────────────────→│
│ │
```
---
## 3. Numery potwierdzenia (Acknowledgment Numbers)
### Interpretacja
**Acknowledgment Number (ACK)** = numer **następnego oczekiwanego** bajtu
```
ACK = ostatni_otrzymany_SEQ + liczba_otrzymanych_bajtów
```
### Kumulatywne potwierdzenia
TCP używa **cumulative ACK** - potwierdza wszystkie bajty do danego numeru:
```
Otrzymano: SEQ=100 (10 bajtów), SEQ=110 (10 bajtów)
ACK = 120 (potwierdza bajty 100-119)
Otrzymano: SEQ=100 (10 bajtów), BRAK SEQ=110, SEQ=120 (10 bajtów)
ACK = 110 (nie można potwierdzić 120, bo brakuje 110-119!)
```
### Selective ACK (SACK)
Opcja TCP pozwalająca potwierdzać niesąsiednie bloki:
```
Otrzymano: SEQ=100, BRAK SEQ=110, SEQ=120
ACK = 110
SACK: [120-130] ← "mam też te bajty"
```
---
## 4. Wartość początkowa numeru sekwencyjnego (ISN)
### Dlaczego ISN nie zaczyna od 0?
1. **Bezpieczeństwo** - przewidywalny ISN umożliwia ataki (TCP hijacking)
2. **Unikanie kolizji** - stare segmenty z poprzednich połączeń nie będą mylone z nowymi
### Generowanie ISN
#### Historycznie (RFC 793):
```
ISN = (4 mikrosekundy timer) mod 2^32
```
Zwiększany o 1 co 4μs → pełny cykl co ~4.55 godziny
#### Współcześnie (RFC 6528):
```
ISN = M + F(localhost, localport, remotehost, remoteport, secretkey)
```
Gdzie:
- **M** = timer (jak wyżej)
- **F** = funkcja kryptograficzna (MD5/SHA)
- **secretkey** = tajny klucz serwera
### Właściwości dobrego ISN
| Właściwość | Powód |
|------------|-------|
| **Losowy** | Utrudnia ataki typu sequence prediction |
| **Unikalny** | Różny dla każdego połączenia |
| **Monotonicznie rosnący** | Unikanie kolizji z poprzednimi połączeniami |
### Zakres numerów sekwencyjnych
```
SEQ: 32 bity → zakres 0 do 4,294,967,295 (2^32 - 1)
Przy szybkości 1 Gbps:
- 125 MB/s danych
- Przepełnienie (wrap-around) co ~34 sekundy!
Rozwiązanie: PAWS (Protection Against Wrapped Sequences)
- Używa opcji Timestamp do rozróżniania "starych" i "nowych" numerów
```
---
## 5. Stany połączenia TCP
```
┌─────────────┐
┌────────→│ CLOSED │←────────┐
│ └─────────────┘ │
│ │ │
(timeout) (passive open) (active open)
│ ↓ │
│ ┌─────────────┐ │
│ │ LISTEN │ │
│ └─────────────┘ │
│ │ │
│ (recv SYN) (send SYN)
│ ↓ ↓
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ TIME_WAIT │ │ SYN_RECEIVED│ │ SYN_SENT │
└─────────────┘ └─────────────┘ └─────────────┘
↑ │ │
(recv FIN+ACK) (send SYN+ACK) (recv SYN+ACK)
│ ↓ ↓
┌─────────────┐ ┌─────────────────────────────┐
│ FIN_WAIT_2 │ │ ESTABLISHED │
└─────────────┘ └─────────────────────────────┘
```
---
## 6. Zamykanie połączenia (Four-Way Handshake)
```
Klient Serwer
│ │
│ (1) FIN, seq=u │
│──────────────────────────────────────────→│
│ │
│ (2) ACK, ack=u+1 │
│←──────────────────────────────────────────│
│ │
│ (serwer może jeszcze wysyłać dane) │
│ │
│ (3) FIN, seq=v │
│←──────────────────────────────────────────│
│ │
│ (4) ACK, ack=v+1 │
│──────────────────────────────────────────→│
│ │
│ [TIME_WAIT: 2×MSL] │
│ │
```
**MSL (Maximum Segment Lifetime)** = maksymalny czas życia segmentu (~2 minuty)
**TIME_WAIT = 2×MSL** = ~4 minuty (oczekiwanie na zagubione segmenty)
---
## 📊 Podsumowanie Three-Way Handshake
| Krok | Kierunek | Flagi | SEQ | ACK | Cel |
|------|----------|-------|-----|-----|-----|
| 1 | C→S | SYN | x | - | Inicjacja, ISN klienta |
| 2 | S→C | SYN+ACK | y | x+1 | Akceptacja, ISN serwera |
| 3 | C→S | ACK | x+1 | y+1 | Potwierdzenie, połączenie gotowe |
---
## 🧠 Mnemoniki
### "SYN-SYN/ACK-ACK" - trzy kroki:
- **SYN** - "Chcę rozmawiać" (klient)
- **SYN/ACK** - "OK, ja też" (serwer)
- **ACK** - "Super, zaczynamy" (klient)
### "SEQ = Sent, ACK = Expected":
- **SEQ**uence = numer wysyłanego bajtu
- **ACK**nowledgment = numer oczekiwanego bajtu
### "ISN = Initial Secret Number":
- **I**nitial - początkowy
- **S**ecret - losowy dla bezpieczeństwa
- **N**umber - 32-bitowa liczba
### "ESTABLISHED po trzech krokach":
- 1: SYN_SENT
- 2: SYN_RECEIVED
- 3: **ESTABLISHED** (obie strony)
---
## ❓ Możliwe pytania dodatkowe (follow-up)
### Q1: "Dlaczego trzy kroki, nie dwa?"
**Odpowiedź:**
Dwa kroki nie wystarczą do synchronizacji **obu** ISN:
```
Dwa kroki (hipotetycznie):
Klient: SYN, seq=x → Serwer zna ISN klienta
Serwer: SYN+ACK, seq=y → Klient zna ISN serwera
→ Ale serwer NIE WIE, czy klient otrzymał y!
Trzy kroki:
Klient: SYN, seq=x → Serwer zna ISN klienta
Serwer: SYN+ACK, seq=y → Klient zna ISN serwera
Klient: ACK, ack=y+1 → Serwer WIE, że klient otrzymał y ✓
```
---
### Q2: "Co to jest SYN flood attack?"
**Odpowiedź:**
**SYN flood** = atak DoS wysyłający masę SYN bez dokończenia handshake'a.
```
Atakujący: SYN, SYN, SYN, SYN... (tysiące)
Serwer: SYN+ACK, SYN+ACK... (czeka na ACK)
→ Kolejka half-open connections pełna
→ Serwer nie może przyjąć nowych połączeń
```
**Obrona:**
- **SYN cookies** - serwer nie przechowuje stanu, koduje go w ISN
- **Zwiększenie kolejki SYN**
- **Zmniejszenie timeout SYN_RECEIVED**
- **Firewall/IDS**
---
### Q3: "Co to jest TCP Fast Open (TFO)?"
**Odpowiedź:**
**TFO** pozwala wysyłać dane już w pierwszym SYN (0-RTT):
```
Standardowo: TFO:
SYN → SYN + dane →
← SYN+ACK ← SYN+ACK + dane
ACK + dane → ACK →
3 RTT do danych 1 RTT do danych!
```
**Wymaga:** Cookie TFO z poprzedniego połączenia (uzyskany przy pierwszym handshake).
---
### Q4: "Jak działa retransmisja w TCP?"
**Odpowiedź:**
1. **Timeout (RTO):** Brak ACK w określonym czasie → retransmisja
2. **Fast Retransmit:** 3 duplikaty ACK → retransmisja bez czekania na timeout
```
Wysłano: SEQ=100, SEQ=200, SEQ=300
Zgubiono: SEQ=200
Odbiorca: ACK=200, ACK=200, ACK=200 (3× duplikat)
Nadawca: "Ah, brakuje 200!" → retransmisja SEQ=200
```
---
### Q5: "Co oznacza flaga RST?"
**Odpowiedź:**
**RST (Reset)** = natychmiastowe przerwanie połączenia.
**Kiedy wysyłane:**
- Segment do zamkniętego portu
- Segment do nieistniejącego połączenia
- Połączenie w nieprawidłowym stanie
- Aplikacja chce natychmiast zamknąć (bez FIN handshake)
```
RST nie wymaga potwierdzenia - połączenie natychmiast zamknięte.
```
---
### Q6: "Wyjaśnij opcje negocjowane podczas handshake"
**Odpowiedź:**
| Opcja | Opis | Wartość typowa |
|-------|------|----------------|
| **MSS** | Maximum Segment Size | 1460 (Ethernet) |
| **Window Scale** | Mnożnik okna (>65535) | 0-14 (×2^n) |
| **SACK Permitted** | Selective ACK dozwolone | tak/nie |
| **Timestamp** | Pomiar RTT, PAWS | 32-bit timer |
| **NOP** | Padding | - |
---
## 🎯 Kluczowe punkty do zapamiętania
1. **3 kroki:** SYN → SYN+ACK → ACK
2. **SEQ** = numer pierwszego bajtu w segmencie
3. **ACK** = numer **następnego oczekiwanego** bajtu
4. **ISN** = losowy, dla bezpieczeństwa i unikania kolizji
5. **Zamknięcie:** 4 kroki (FIN → ACK → FIN → ACK) + TIME_WAIT
6. **SYN flood** - atak DoS, obrona: SYN cookies
---
## 📖 Źródła do pogłębienia
1. RFC 793 - TCP Specification
2. RFC 6528 - Defending Against Sequence Number Attacks
3. RFC 7413 - TCP Fast Open
4. Stevens - "TCP/IP Illustrated, Volume 1"