mirror of
https://github.com/kuhyx/praca_magisterska.git
synced 2026-07-04 13:43:05 +02:00
434 lines
14 KiB
Markdown
434 lines
14 KiB
Markdown
|
|
# 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"
|