KR_Net_Packet_Analysis - somaz94/DevOps-Engineer GitHub Wiki
Q19. Ethernet Frame, IP Packet, TCP Segmentì í€ë 구조륌 ì€ëª íê³ ì€ì íší· ë¶ì ë°©ë²ì?
ê³ìžµë³ 캡ìí 구조:
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Ethernet Frame (Layer 2) â
â âââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â IP Packet (Layer 3) â â
â â âââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â â â TCP Segment (Layer 4) â â â
â â â âââââââââââââââââââââââââââââââââââââââââââââââ â â â
â â â â Application Data (Layer 7) â â â â
â â â âââââââââââââââââââââââââââââââââââââââââââââââ â â â
â â âââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â âââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Ethernet Frame 구조 (ìŽ ìµì 64 bytes ~ ìµë 1518 bytes):
ââââââââââââ¬ââââââ¬âââââââââââ¬âââââââââââ¬âââââââ¬ââââââââââ¬ââââââ
â Preamble â SFD â Dst MAC â Src MAC â Type â Payload â FCS â
â 7 bytes â1 byteâ 6 bytes â 6 bytes â2 bytesâ46-1500 â4 bytesâ
ââââââââââââŽââââââŽâââââââââââŽâââââââââââŽâââââââŽââââââââââŽââââââ
Preamble: 10101010... (ëêž°í ì íž)
SFD: 10101011 (Start Frame Delimiter)
Dst MAC: 목ì ì§ MAC 죌ì (ì: aa:bb:cc:dd:ee:ff)
Src MAC: ì¶ë°ì§ MAC 죌ì
Type: 0x0800 (IPv4), 0x0806 (ARP), 0x86DD (IPv6)
Payload: ìì ê³ìžµ ë°ìŽí° (ìµì 46 bytes - íšë© í¬íš)
FCS: CRC-32 ì€ë¥ ê²ì¶ (Frame Check Sequence)
IP Packet 구조 (IPv4, ìµì 20 bytes):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
âââââââââ¬ââââââââ¬ââââââââââââââââ¬ââââââââââââââââââââââââââââââââ
âVersionâ IHL â TOS/DSCP â Total Length â
â (4) â (4) â (8 bits) â (16 bits) â
âââââââââââââââââââââââââââââââââŒââââ¬ââââââââââââââââââââââââââââ€
â Identification âFlgâ Fragment Offset â
â (16 bits) â(3)â (13 bits) â
âââââââââââââââââ¬ââââââââââââââââŒââââââââââââââââââââââââââââââââ€
â TTL â Protocol â Header Checksum â
â (8 bits) â (8 bits) â (16 bits) â
âââââââââââââââââŽââââââââââââââââŽââââââââââââââââââââââââââââââââ€
â Source IP Address â
â (32 bits) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â Destination IP Address â
â (32 bits) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â Options (if IHL > 5) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Version: 4 (IPv4)
IHL: Header Length (5 = 20 bytes, ìµë 15 = 60 bytes)
TOS/DSCP: Quality of Service (ì°ì ìì)
Total Len: í€ë + ë°ìŽí° ì 첎 êžžìŽ
ID: ëšíží ì íší· ìë³
Flags: bit 0: Reserved (0)
bit 1: DF (Don't Fragment)
bit 2: MF (More Fragments)
TTL: íší· ìëª
(íë§ë€ 1 ê°ì, 0ìŽ ë멎 íêž°)
Protocol: 6 (TCP), 17 (UDP), 1 (ICMP)
Checksum: IP í€ë ì€ë¥ ê²ì¶
TCP Segment 구조 (ìµì 20 bytes):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
âââââââââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââ
â Source Port â Destination Port â
â (16 bits) â (16 bits) â
âââââââââââââââââââââââââââââââââŽââââââââââââââââââââââââââââââââ€
â Sequence Number â
â (32 bits) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â Acknowledgment Number â
â (32 bits) â
âââââââââ¬ââââââââ¬ââ¬ââ¬ââ¬ââ¬ââ¬ââ¬ââ¬ââ¬ââââââââââââââââââââââââââââââââ€
â Offsetâ Res. âCâEâUâAâPâRâSâFâ Window Size â
â (4) â (3) âWâCâRâCâSâSâYâIâ (16 bits) â
â â âRâEâGâKâHâTâNâNâ â
âââââââââŽââââââââŽââŽââŽââŽââŽââŽââŽââŽââŽââââââââââââââââââââââââââââââââ€
â Checksum â Urgent Pointer â
â (16 bits) â (16 bits) â
âââââââââââââââââââââââââââââââââŽââââââââââââââââââââââââââââââââ€
â Options (if Offset > 5) â
â (variable) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Seq Number: ë°ìŽí°ì 첫 ë°ìŽíž ìì¹
Ack Number: ë€ìì ë°ì ë°ìŽí°ì ìì¹
Flags:
- CWR (Congestion Window Reduced): íŒì¡ ìëì° ê°ì
- ECE (ECN-Echo): íŒì¡ ì늌
- URG (Urgent): êžŽêž ë°ìŽí°
- ACK (Acknowledgment): íìž ìëµ
- PSH (Push): ìŠì ì ë¬
- RST (Reset): ì°ê²° ê°ì ì¢
ë£
- SYN (Synchronize): ì°ê²° ìì
- FIN (Finish): ì°ê²° ì¢
ë£
Window Size: ìì ë²íŒ í¬êž° (Flow Control)
ì€ì íší· ë¶ì (tcpdump):
# HTTP GET ìì² ìº¡ì²
sudo tcpdump -i eth0 -nn -X 'tcp port 80 and host example.com'
ì¶ë ¥:
14:30:15.123456 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S], seq 1234567890
0x0000: 4500 003c 1c46 4000 4006 b1e6 c0a8 010a E..<.F@.@.......
0x0010: 5db8 d822 d431 0050 499d 162a 0000 0000 ]..".1.PI..*....
0x0020: a002 7210 e32d 0000 0204 05b4 0402 080a ..r..-..........
ë¶ì:
0x4500: Version=4, IHL=5, TOS=00
0x003c: Total Length = 60 bytes
0x1c46: Identification
0x4000: Flags=DF (Don't Fragment)
0x40: TTL = 64
0x06: Protocol = TCP (6)
0xc0a8010a: Source IP = 192.168.1.10
0x5db8d822: Dest IP = 93.184.216.34
0xd431: Source Port = 54321
0x0050: Dest Port = 80
0xa002: Flags = SYN, Window Size = 7210Wireshark ëì€íë ìŽ íí°:
TCP 3-Way Handshake:
tcp.flags.syn==1 && tcp.flags.ack==0 # SYN
tcp.flags.syn==1 && tcp.flags.ack==1 # SYN-ACK
tcp.flags.syn==0 && tcp.flags.ack==1 && tcp.seq==1 # ACK
HTTP ìì²:
http.request.method == "GET"
http.response.code == 200
ì¬ì ì¡ íší·:
tcp.analysis.retransmission
ë늰 ìëµ:
tcp.time_delta > 0.1
íší· ìì€:
tcp.analysis.lost_segment
MTU vs MSS:
MTU (Maximum Transmission Unit):
âââââââââââââââââââââââââââââââââââââââââââââââ
â Ethernet Header (14) â IP Packet (1500) â FCS (4) â
âââââââââââââââââââââââââââââââââââââââââââââââ
â
MTU = 1500 bytes
MSS (Maximum Segment Size):
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â IP Header (20) â TCP Header (20) â TCP Data (1460) â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
MSS = 1460 bytes
ê³µì: MSS = MTU - IP Header(20) - TCP Header(20)
ìŒë°ì ìž MTU ê°:
Ethernet: 1500 bytes
802.1Q VLAN: 1504 bytes (VLAN tag 4 bytes)
PPPoE: 1492 bytes (PPPoE header 8 bytes)
VPN (IPsec): 1400 bytes (ìíží ì€ë²í€ë ìœ 100 bytes)
GRE Tunnel: 1476 bytes (GRE header 24 bytes)
VXLAN: 1450 bytes (VXLAN header 50 bytes)
Jumbo Frame: 9000 bytes (ë°ìŽí°ìŒí°)
íší· ëšíží 묞ì :
ìë늬ì€: Client MTU=1500, ì€ê° ê²œë¡ MTU=1400
Client â Router1 (MTU 1500) â Router2 (MTU 1400) â Server
1. Client: 1500 bytes íší· ì ì¡
2. Router2: MTU ìŽê³Œ, ëšíží íì
DF Flag = 0 (ëšíží íì©):
Original: [IP Header | 1480 bytes data]
Fragment1: [IP Header | 1380 bytes | MF=1]
Fragment2: [IP Header | 100 bytes | MF=0]
DF Flag = 1 (ëšíží êžì§):
Router2: ICMP "Fragmentation Needed" ì ì¡
íší· íêž°
PMTUD (Path MTU Discovery) ëì:
1. Client: DF íëê·ž ì€ì íì¬ 1500 bytes íší· ì ì¡
2. MTU 1400 ëŒì°í° ëë¬:
â ICMP Type 3 Code 4 (Fragmentation Needed and DF set) ìëµ
â Next-Hop MTU: 1400
3. Client: MTU륌 1400ìŒë¡ ì¡°ì
â 1400 bytes íší· ì¬ì ì¡
4. 겜ë¡ì 몚ë êµ¬ê° íµê³Œ ì±ê³µ
â Path MTU = 1400 íì
5. TCP Connectionì MSS ì¡°ì :
MSS = 1400 - 20(IP) - 20(TCP) = 1360 bytes
PMTUD ì€ìµ:
# PingìŒë¡ MTU í
ì€íž
ping -M do -s 1472 8.8.8.8
# -M do: DF íëê·ž ì€ì
# -s 1472: 1472 bytes ë°ìŽí° (1500 - 20 IP - 8 ICMP)
ì±ê³µ: 1472 bytes ì ì¡ ê°ë¥ â MTU 1500
ì€íš: ICMP "Frag needed" â MTU < 1500
# Binary Searchë¡ Path MTU ì°Ÿêž°
ping -M do -s 1400 8.8.8.8 # ì±ê³µ
ping -M do -s 1450 8.8.8.8 # ì±ê³µ
ping -M do -s 1470 8.8.8.8 # ì€íš
ping -M do -s 1460 8.8.8.8 # ì±ê³µ
â Path MTU = 1488 (1460 + 20 IP + 8 ICMP)PMTUD Black Hole 묞ì :
묞ì : ë°©íë²œìŽ ICMP "Fragmentation Needed" ì°šëš
Client âââ Router (MTU 1400, ICMP ì°šëš) âââ Server
â â
âââââ 1500 bytes (DF=1) ââââX (íêž°) â
â â
âââââ ICMP ìëµ êž°ë€ëŠŒ ââââX (íììì) â
â â
âââââ ì¬ì ì¡ ââââX (ë°ë³µ) â
결곌: ì°ê²° ë¶ê° ëë ê·¹ëë¡ ë늌
íŽê²° ë°©ë²:
1. TCP MSS Clamping (ê¶ì¥):
# iptablesë¡ MSS ê°ì ì¡°ì
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --set-mss 1360
# Cisco ëŒì°í°
interface GigabitEthernet0/0
ip tcp adjust-mss 1360
ì늬:
SYN íší·ì MSS ìµì
ì ê°ì ë¡ ë®ì¶€
â ì쪜 몚ë ìì ìžê·žëšŒíž ì¬ì©
â ëšíží ë°ì ì íš2. MTU ìë ì¡°ì :
# Linux
ip link set dev eth0 mtu 1400
# Windows
netsh interface ipv4 set subinterface "Ethernet" mtu=1400
# ì구 ì€ì (Linux /etc/network/interfaces)
auto eth0
iface eth0 inet dhcp
mtu 14003. PLPMTUD (Packetization Layer PMTUD):
TCPì ì첎 PMTUD (RFC 4821):
- ICMPì ì졎íì§ ìì
- Probe íší·ìŒë¡ MTU íì
- ë ìì ì ìŽì§ë§ ë늌
VPN í겜 MSS ê³ì°:
IPsec VPN:
Physical MTU: 1500
IPsec Overhead: ~100 (ESP header, IV, Padding, Auth)
Effective MTU: 1400
TCP MSS: 1400 - 20(IP) - 20(TCP) = 1360
VXLAN:
Physical MTU: 1500
VXLAN Overhead: 50 (Outer Ethernet 14 + Outer IP 20 + Outer UDP 8 + VXLAN 8)
Effective MTU: 1450
TCP MSS: 1450 - 20 - 20 = 1410
몚ëí°ë§:
# ëšížíë íší· íìž
tcpdump -i eth0 'ip[6:2] & 0x3fff != 0'
# Path MTU íìž (Linux)
ip route get 8.8.8.8 | grep mtu
# TCP MSS íìž (Wireshark)
tcp.options.mssìëëŠ¬ì€ 1: ë늰 ì¹ì¬ìŽíž ìëµ
ìŠì: ì¹íìŽì§ ë¡ë©ìŽ 5ìŽ ìŽì ìì
tcpdump 캡ì²:
# 80 í¬íž HTTP ížëíœ ìº¡ì², íìì€í¬í ë§ìŽí¬ë¡ìŽ ëšì
sudo tcpdump -i eth0 -nn -tttt -s 65535 'tcp port 80' -w slow-web.pcap
# ì€ìê° ë¶ì (íìì€í¬í í¬íš)
sudo tcpdump -i eth0 -nn -tttt 'host example.com and tcp port 80'
ì¶ë ¥:
2024-01-15 14:30:00.123456 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S]
2024-01-15 14:30:00.323456 IP 93.184.216.34.80 > 192.168.1.10.54321: Flags [S.]
â 200ms ì§ì° (SYN-ACK)
2024-01-15 14:30:00.323789 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [.]
2024-01-15 14:30:00.324567 IP 192.168.1.10.54321 > 93.184.216.34.80: ... HTTP GET
2024-01-15 14:30:05.123456 IP 93.184.216.34.80 > 192.168.1.10.54321: ... HTTP 200
â 4.8ìŽ ì§ì° (ìë² ìëµ)Wireshark ë¶ì:
1. Statistics â Conversations â TCP
â Duration 4.8ìŽ, Bytes íìž
2. Statistics â I/O Graph
â ìê°ëë³ ížëíœ ìê°í
â ìëµ ëêž° êµ¬ê° íìž
3. Display Filter:
tcp.time_delta > 1.0
â 1ìŽ ìŽì ì§ì° íší·ë§ íí°ë§
4. Expert Info (Analyze â Expert Information)
â "TCP Window Full" ê²œê³ íìž
â ìë² ìëì° í¬êž° ë¶ì¡± (ìì ë²íŒ ìì)
ììž: ìë² TCP Window Size ë¶ì¡± (16KB) íŽê²°: ìë² ìì ë²íŒ ìŠê°
sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456'ìëëŠ¬ì€ 2: ê°íì ìž íší· ìì€
ìŠì: VoIP íµí íì§ ì í, ëê¹ íì
tcpdump 캡ì²:
# RTP ížëíœ ìº¡ì² (ìŒë°ì ìŒë¡ UDP 10000-20000 í¬íž)
sudo tcpdump -i eth0 -nn -s 65535 'udp portrange 10000-20000' -w voip.pcap
# Packet Loss ê³ì°
sudo tcpdump -i eth0 -nn 'udp port 10000' | \
awk '{print $NF}' | \
awk -F. '{if (prev && $1-prev!=1) print "Lost:", prev+1, "to", $1-1; prev=$1}'Wireshark ë¶ì:
1. Telephony â RTP â RTP Streams
â Packet Loss: 3.5% (ì ì < 1%)
â Jitter: 50ms (ì ì < 30ms)
2. Display Filter:
rtp
â RTP Sequence Number íìž
â ìŠê° íšíŽìì ëëœ íì§
3. I/O Graph:
Y Axis: SUM(rtp.timestamp)
â ê· ìŒíì§ ìì íšíŽ = Jitter
4. Expert Info:
â "Out-of-Order" ê²œê³ ë€ì
ììž ì¶ê° ë¶ì:
# ë€ížìí¬ ìží°íìŽì€ ìë¬ íìž
ethtool -S eth0 | grep -E 'err|drop|fifo'
rx_dropped: 12345 â ìì ë²íŒ ì€ë²íë¡ì°
tx_errors: 678 â ì¡ì ìë¬
# ìží°íìŽì€ íµê³
ip -s link show eth0
RX errors 12345
# ìì€í
ë¡ê·ž
dmesg | grep -i 'network\|eth0'
[ 123.456] eth0: RX buffer overflowíŽê²°:
# Ring Buffer í¬êž° ìŠê°
ethtool -G eth0 rx 4096 tx 4096
# QoS ì€ì (VoIP ì°ì ìì)
tc qdisc add dev eth0 root handle 1: prio bands 3
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 10000 0xffff flowid 1:1ìëëŠ¬ì€ 3: TCP ì¬ì ì¡ íìŠ
ìŠì: ì í늬ìŒìŽì ìëµ ì§ì°, CPU ì¬ì©ë¥ ì ì
tcpdump íšíŽ ë¶ì:
# ì¬ì ì¡ íší· 캡ì²
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 or \
(tcp[13] & 0x07 != 0)' -w retrans.pcap
# SYN Flood ê°ì§
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn' | \
awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -nr | head
ì¶ë ¥:
5432 192.168.1.100 â ë¹ì ìì ìŒë¡ ë§ì SYN
234 192.168.1.101
123 192.168.1.102Wireshark Expert Analysis:
1. Statistics â TCP StreamGraph â Time-Sequence (Stevens)
â ìí ëŒìž ë€ì = ì¬ì ì¡ ëêž°
2. Display Filter:
tcp.analysis.retransmission
tcp.analysis.fast_retransmission
tcp.analysis.duplicate_ack
3. ì¬ì ì¡ ë¹ìš:
Statistics â Protocol Hierarchy
â TCP Retransmission: 15% (ì ì < 3%)
4. Follow TCP Stream:
â 3-Way Handshake í RST
â SYN Flood 공격 ìì¬
공격 íìž:
# ë°ì¯€ ìŽëа ì°ê²° ì íìž
netstat -an | grep SYN_RECV | wc -l
12345 â ë¹ì ì (ì ì < 100)
# SYN Cookie íì±í (ìì ë°©ìŽ)
sysctl -w net.ipv4.tcp_syncookies=1
# ì°ê²° íììì ëšì¶
sysctl -w net.ipv4.tcp_synack_retries=1
# iptables Rate Limiting
iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROPìëëŠ¬ì€ 4: DNS 쿌늬 ì€íš
tcpdump DNS ë¶ì:
# DNS 쿌늬/ìëµ ìº¡ì²
sudo tcpdump -i eth0 -nn -s 65535 'udp port 53' -w dns-issue.pcap
# ì€ìê° ëªšëí°ë§
sudo tcpdump -i eth0 -nn 'port 53'
ì¶ë ¥:
14:30:00.123 IP 192.168.1.10.54321 > 8.8.8.8.53: 12345+ A? example.com
14:30:05.123 IP 192.168.1.10.54321 > 8.8.8.8.53: 12345+ A? example.com
â 5ìŽ í ì¬ìë
(ìëµ ìì)Wireshark ë¶ì:
1. Display Filter:
dns.flags.response == 0 && !dns.flags.response == 1
â ìëµ ìë ì¿ŒëŠ¬ë§ íí°ë§
2. Statistics â DNS
â Query Rate: 100/s
â Response Rate: 0/s
â 100% ìì€
3. Follow UDP Stream:
â DNS ìë² ë°©í벜 ì°šëš íìž
â ICMP "Port Unreachable" ìì
묞ì ì§ëš:
# DNS ìë² ì°ê²° í
ì€íž
dig @8.8.8.8 example.com +trace
# ë°©í벜 íìž
sudo iptables -L -n -v | grep -i dns
0 0 DROP udp -- * * 0.0.0.0/0 8.8.8.8 udp dpt:53
# ë첎 DNS í
ì€íž
dig @1.1.1.1 example.com # Cloudflare DNS ì ìíŽê²°:
# ë°©í벜 ê·ì¹ ìì
iptables -D OUTPUT -p udp --dport 53 -d 8.8.8.8 -j DROP
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# /etc/resolv.conf ì
ë°ìŽíž
nameserver 1.1.1.1
nameserver 8.8.8.8ì ì©í tcpdump íí°:
# HTTP ìì²ë§
tcpdump -i eth0 -A 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420)'
# GET 묞ììŽ (0x47455420)
# SYN íší·ë§
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
# RST íší·ë§
tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0'
# í¹ì MAC 죌ì
tcpdump -i eth0 ether host aa:bb:cc:dd:ee:ff
# VLAN íê·ž
tcpdump -i eth0 'vlan and host 192.168.1.10'
# í° íší· (1400 bytes ìŽì)
tcpdump -i eth0 'ip[2:2] > 1400'
# ICMP Redirect
tcpdump -i eth0 'icmp[icmptype] == 5'Wireshark ê³ êž íí°:
# TCP Windowê° 0ìž íší· (íëŠ ì ìŽ)
tcp.window_size == 0
# TCP Zero Window Probe
tcp.analysis.zero_window_probe
# Delayed ACK
tcp.analysis.ack_rtt > 0.2
# TCP Out-of-Order
tcp.analysis.out_of_order
# HTTP í¹ì User-Agent
http.user_agent contains "bot"
# SSL/TLS Handshake ì€íš
ssl.alert_message.desc == 40 # Handshake Failure
TCP Flow Control vs Congestion Control:
Flow Control (íëŠ ì ìŽ):
- 목ì : ìì ì ë²íŒ ì€ë²íë¡ì° ë°©ì§
- ë©ì»€ëìŠ: TCP Window Size (Receiver Advertised Window)
- ë²ì: Point-to-Point (ì¡ì ì â ìì ì)
Congestion Control (íŒì¡ ì ìŽ):
- 목ì : ë€ížìí¬ íŒì¡ ë°©ì§
- ë©ì»€ëìŠ: Congestion Window (cwnd)
- ë²ì: End-to-End (ì 첎 겜ë¡)
TCP Congestion Control ìí ëšžì :
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Slow Start â
â cwnd: 1 MSS â 2 â 4 â 8 â 16 ... (Exponential) â
â ë§€ ACKë§ë€ cwnd += 1 MSS â
ââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââ
â cwnd >= ssthresh (Slow Start Threshold)
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Congestion Avoidance â
â cwnd ìŠê°: Linear (ë§€ RTTë§ë€ 1 MSS) â
â ë§€ ACKë§ë€ cwnd += MSS * MSS / cwnd â
ââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââ
â Packet Loss ê°ì§
â
âââââââââŽâââââââââ
â â
3 Dup ACK Timeout
â â
â â
âââââââââââââââ ââââââââââââââââââââ
â Fast â â Slow Start â
â Recovery â â (ì²ìë¶í° ì¬ìì)â
â ssthresh= â â ssthresh= â
â cwnd/2 â â cwnd/2 â
â cwnd= â â cwnd= 1 MSS â
â ssthresh+3 â â â
âââââââââââââââ ââââââââââââââââââââ
구첎ì ìž ìì:
ìŽêž° ìí:
cwnd = 1 MSS (1460 bytes)
ssthresh = 64 KB
RTT = 100ms
Round 1 (Slow Start):
- 1 MSS ì ì¡ â ACK ìì â cwnd = 2 MSS
Round 2:
- 2 MSS ì ì¡ â 2 ACK ìì â cwnd = 4 MSS
Round 3:
- 4 MSS ì ì¡ â 4 ACK ìì â cwnd = 8 MSS
...
Round 7:
- cwnd = 64 MSS = 93,440 bytes
- cwnd >= ssthresh â Congestion Avoidance ì í
Round 8 (Congestion Avoidance):
- 64 MSS ì ì¡ â 64 ACK ìì
- cwnd += 64 * 1460 / 93440 = 1 MSS
- cwnd = 65 MSS
Round 9:
- cwnd = 66 MSS (Linear ìŠê°)
Round 15:
- Packet Loss (3 Duplicate ACK)
- Fast Retransmit ì€í
- ssthresh = cwnd / 2 = 36 MSS
- cwnd = ssthresh + 3 = 39 MSS
- Fast Recovery ì§ì
죌ì Congestion Control ìê³ ëŠ¬ìŠ:
1. Reno (Classic):
- Fast Retransmit: 3 Duplicate ACK â ìŠì ì¬ì ì¡
- Fast Recovery: cwnd륌 ì ë°ìŒë¡ ì€ìŽê³ Congestion Avoidance
- Timeout: cwnd = 1, Slow Start ì¬ìì
2. Cubic (Linux Ʞ볞ê°):
- Window ìŠê°ê° Cubic íšì ë°ëŠ
- Loss ë°ì ì§ì (Wmax)ì êž°ìµ
- Wmax ê·Œì²ìì ì ì€íê² ìŠê°
- ê³ ì ë€ížìí¬(Long Fat Network)ì ìµì í
K = cubic_root((Wmax - cwnd) / C)
cwnd = C * (t - K)³ + Wmax
ì¥ì : RTTê° êžžìŽë ë¹ ë¥ž ëìí íì©
3. BBR (Bottleneck Bandwidth and RTT):
- Google ê°ë° (2016)
- Loss êž°ë°ìŽ ìë Bandwidthì RTT ìž¡ì êž°ë°
- 4ê°ì§ ìí: Startup, Drain, ProbeBW, ProbeRTT
ì¥ì :
- ë²íŒ ëžë¡íž(Bufferbloat) íŽê²°
- Packet Loss í겜ììë ìì ì
- YouTube, Google Cloud ë±ìì ì¬ì©
sysctl -w net.ipv4.tcp_congestion_control=bbr
TCP Window Scaling (RFC 1323):
묞ì :
TCP Window Size íë: 16 bits â ìµë 65,535 bytes
ê³ ì ë€ížìí¬ (1 Gbps, RTT 100ms):
- BDP (Bandwidth-Delay Product) = 1Gbps * 100ms = 12.5 MB
- Ʞ볞 Window Sizeë¡ë ì²ëЬë ì í
Throughput = Window Size / RTT = 65KB / 0.1s = 650 KB/s
â 1 Gbps íì ìì 5 Mbpsë§ íì©
íŽê²°: Window Scale Option
TCP SYN íší·ì í¬íš:
ââââââââââââââââââââââââââââââââââ
â Option Kind: 3 (Window Scale) â
â Option Length: 3 â
â Shift Count: 7 â â 2^7 = 128 ë°° íì¥
ââââââââââââââââââââââââââââââââââ
ì€ì Window Size = (TCP Header Window) << (Shift Count)
ì: Header Window = 65,535
Shift Count = 7
Actual Window = 65,535 * 128 = 8,388,480 bytes (8 MB)
Window Scaling íìž:
# tcpdumpë¡ SYN íší· íìž
sudo tcpdump -i eth0 -nn -vv 'tcp[tcpflags] & tcp-syn != 0'
ì¶ë ¥:
IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S], seq 123, win 65535,
options [mss 1460,nop,wscale 7,nop,nop,TS val 123 ecr 0,sackOK,eol]
â wscale 7 = 128ë°° íì¥
# Wireshark ë¶ì
tcp.options.wscale.shift
tcp.window_size_scalefactorì€ë¬Ž ì€ì (Linux):
# TCP ìì ë²íŒ í¬êž°
sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456'
# min default max (6 MB)
# TCP ì¡ì ë²íŒ í¬êž°
sysctl -w net.ipv4.tcp_wmem='4096 16384 4194304'
# min default max (4 MB)
# Window Scaling íì±í (êž°ë³žê° 1)
sysctl -w net.ipv4.tcp_window_scaling=1
# SACK (Selective Acknowledgment) íì±í
sysctl -w net.ipv4.tcp_sack=1
# Timestamps íì±í (RTT ìž¡ì )
sysctl -w net.ipv4.tcp_timestamps=1
# ì²ëЬë ê³ì°
# BDP = Bandwidth * RTT
# 1 Gbps * 100ms = 125 MB/s * 0.1s = 12.5 MB
# Window Size >= BDPì±ë¥ ìž¡ì :
# iperf3ë¡ ì²ëЬë í
ì€íž
iperf3 -c server.example.com -t 60 -P 4
ì¶ë ¥ (ìµì í ì ):
[ 5] 0.00-60.00 sec 5.12 GBytes 734 Mbits/sec receiver
â Window Size ë¶ì¡±
# Window Scaling í:
[ 5] 0.00-60.00 sec 65.3 GBytes 9.35 Gbits/sec receiver
â ê±°ì ì 첎 ëìí íì©
# cwnd 몚ëí°ë§
ss -i | grep -i cwnd
cubic wscale:7,7 rto:204 rtt:3.5/2 cwnd:10 send 33.1Mbps
â Window Scale â Congestion WindowWiresharkë¡ ì±ë¥ 묞ì ì§ëš:
1. TCP Window Full:
â ìì ì ìëì° í¬êž° ë¶ì¡±
â ì¡ì ìê° ëêž°íŽìŒ íš
tcp.analysis.window_full
2. TCP Zero Window:
â ìì ì ë²íŒ ê°ë ì°ž
â ì¡ì ì€ëš
tcp.window_size == 0
3. TCP Window Update:
â ìì ìê° ìëì° íì¥ ì늌
tcp.analysis.window_update
íŽê²°:
- ìì ë²íŒ í¬êž° ìŠê°
- Window Scaling íì±í
- ì í늬ìŒìŽì
ì²ëЬ ìë ê°ì
BPF (Berkeley Packet Filter) 묞ë²:
Ʞ볞 구조:
[protocol] [direction] [type] [value]
protocol: ip, ip6, arp, tcp, udp, icmp
direction: src, dst, src and dst, src or dst
type: host, net, port, portrange
ì€ì ìì :
1. í¹ì ížì€íž ê° íµì :
# ìë°©í¥
tcpdump host 192.168.1.10
# ì¶ë°ì§ë§
tcpdump src host 192.168.1.10
# 목ì ì§ë§
tcpdump dst host 192.168.1.10
# ë ížì€íž ê° íµì
tcpdump host 192.168.1.10 and host 192.168.1.202. ë€ížìí¬ ë²ì:
# ìëžë·
tcpdump net 192.168.1.0/24
tcpdump net 192.168.1.0 mask 255.255.255.0
# ì¬ë¬ ìëžë·
tcpdump 'net 192.168.1.0/24 or net 10.0.0.0/8'3. í¬íž íí°ë§:
# ëšìŒ í¬íž
tcpdump port 80
tcpdump dst port 443
# í¬íž ë²ì
tcpdump portrange 10000-20000
# ì¬ë¬ í¬íž
tcpdump 'port 80 or port 443 or port 8080'
# í¹ì í¬íž ì ìž
tcpdump 'not port 22'4. TCP íëê·ž íí°:
# SYN íší·ë§
tcpdump 'tcp[tcpflags] & tcp-syn != 0'
tcpdump 'tcp[13] & 2 != 0' # ëìŒ (13ë²ì§ž ë°ìŽíž, bit 1)
# SYN-ACK
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
tcpdump 'tcp[13] == 18' # SYN(2) + ACK(16) = 18
# FIN íší·
tcpdump 'tcp[tcpflags] & tcp-fin != 0'
# RST íší·
tcpdump 'tcp[tcpflags] & tcp-rst != 0'
# PSH-ACK (ë°ìŽí° ì ì¡)
tcpdump 'tcp[tcpflags] & (tcp-push|tcp-ack) == (tcp-push|tcp-ack)'
# ACKë§ (SYN, FIN, RST ì ìž)
tcpdump 'tcp[tcpflags] == tcp-ack'5. IP í€ë íí°:
# TTL í¹ì ê°
tcpdump 'ip[8] == 64' # TTL = 64
# TTL < 10 (ìì¬ì€ë¬ìŽ íší·)
tcpdump 'ip[8] < 10'
# IP ìµì
ìŽ ìë íší·
tcpdump 'ip[0] & 0x0f > 5' # IHL > 5 (ìµì
졎ì¬)
# DF (Don't Fragment) íëê·ž
tcpdump 'ip[6] & 0x40 != 0'
# MF (More Fragments) íëê·ž
tcpdump 'ip[6] & 0x20 != 0'
# ëšížíë íší·
tcpdump 'ip[6:2] & 0x1fff != 0'
# ToS/DSCP ê°
tcpdump 'ip[1] & 0xfc == 0xb8' # EF (Expedited Forwarding)6. íìŽë¡ë ê²ì:
# HTTP GET ìì²
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# "GET " ASCII
# HTTP POST
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'
# "POST"
# HTTP ìëµ 200
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450'
# "HTTP"
# SSH íë¡í ìœ ìë³
tcpdump -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x5353482d'
# "SSH-"7. ë³µí© íí°:
# ìžë¶ â ëŽë¶ ì¹ ížëíœ (í¬íž 80, 443)
tcpdump 'dst net 192.168.0.0/16 and (port 80 or port 443)'
# SSH륌 ì ìží 몚ë ížëíœ
tcpdump 'not port 22'
# í¹ì ížì€ížë¡ì DNS 쿌늬
tcpdump 'src host 192.168.1.10 and dst port 53'
# ICMP Echo Request/Reply
tcpdump 'icmp[icmptype] == 8 or icmp[icmptype] == 0'
# ARP ìì²ë§
tcpdump 'arp[6:2] == 1' # ARP opcode = 1 (request)ì±ë¥ ìµì í:
1. Capture Filter vs Display Filter:
# ì¢ì: Capture Filter (BPF, 컀ë ë 벚)
tcpdump -i eth0 'host 192.168.1.10'
â ë¶íìí íší·ì ìº¡ì² ì íš
â CPU/ë©ëªšëЬ ì ìœ
# ëìš: 몚ë íší· ìº¡ì² í íí°ë§
tcpdump -i eth0 -w all.pcap
wireshark all.pcap # Display Filter ì¬ì©
â ëì€í¬ I/O 곌ë€
â ëì©ë íìŒ ìì±2. ì€ë ì· êžžìŽ ìµì í:
# í€ëë§ íìí ê²œì° (êž°ë³žê° 262144)
tcpdump -i eth0 -s 96 'tcp'
# Ethernet(14) + IP(20) + TCP(20) + ìµì
(42) = 96 bytes
# ì 첎 íší· (íìŽë¡ë ë¶ì íì)
tcpdump -i eth0 -s 65535 'port 80'
# ìµì í¬êž° (í€ëë§)
tcpdump -i eth0 -s 0 'tcp' # 0 = ì 첎3. ë²íŒ í¬êž° ì¡°ì :
# Ʞ볞 ë²íŒ: 2 MB
tcpdump -i eth0 -B 16384 'port 80'
# 16 MB ë²íŒ (ê³ ì ë€ížìí¬)
# ëë¡ íší· íìž
tcpdump -i eth0 -vv 'port 80'
^C
1000 packets captured
950 packets received by filter
50 packets dropped by kernel â ë²íŒ ë¶ì¡±4. Ring Buffer ì¬ì© (íìŒ ë¡í ìŽì ):
# 10MB íìŒ 5ê° ìí (ìŽ 50MB)
tcpdump -i eth0 -C 10 -W 5 -w capture.pcap 'port 80'
# capture.pcap0, capture.pcap1, ..., capture.pcap4
# ìê° êž°ë° ë¡í
ìŽì
(5ë¶ë§ë€)
tcpdump -i eth0 -G 300 -w 'capture-%Y%m%d-%H%M%S.pcap'5. ë©í°ìœìŽ íì©:
# CPU Affinity ì€ì
taskset -c 0 tcpdump -i eth0 -w cpu0.pcap 'port 80'
taskset -c 1 tcpdump -i eth1 -w cpu1.pcap 'port 443'
# PF_RING (ê³ ì±ë¥ íší· 캡ì²)
tcpdump -i eth0@1 -w capture.pcap # PF_RING ì±ë 16. ì€ìê° ë¶ì vs íìŒ ì ì¥:
# ì€ìê° ë¶ì (í멎 ì¶ë ¥)
tcpdump -i eth0 -l 'port 80' | grep "GET"
# -l: Line Buffered (ìŠì ì¶ë ¥)
# íìŒ ì ì¥ í ë¶ì (ê¶ì¥)
tcpdump -i eth0 -w capture.pcap 'port 80'
wireshark capture.pcap7. ìíë§:
# 1/10 íší·ë§ ìº¡ì² (íµê³ 목ì )
tcpdump -i eth0 -w capture.pcap \
'tcp and (tcp[13] & 0x17 = 0x02) and (rand() % 10 = 0)'ê³ êž BPF ìì :
ì¹ ížëíœ ë¶ì:
# HTTP í€ëë§ (첫 1024 bytes)
tcpdump -i eth0 -s 1024 -A 'tcp port 80 and (
(tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420) or
(tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450)
)'
# HTTPS ClientHello (TLS Handshake)
tcpdump -i eth0 '(tcp[((tcp[12:1] & 0xf0) >> 2)] = 0x16) and
(tcp[((tcp[12:1] & 0xf0) >> 2) + 1] = 0x03) and
(tcp[((tcp[12:1] & 0xf0) >> 2) + 5] = 0x01)'볎ì ë¶ì:
# Port Scan ê°ì§ (SYNë§ ë§ì 겜ì°)
tcpdump -i eth0 'tcp[tcpflags] == tcp-syn and src host 192.168.1.0/24'
# SYN Flood
tcpdump -i eth0 -nn -q 'tcp[tcpflags] == tcp-syn' | \
awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | \
awk '$1 > 100 {print "Possible SYN flood from", $2, "with", $1, "SYNs"}'
# DNS Amplification
tcpdump -i eth0 'udp port 53 and ip[2:2] > 512'ì±ë¥ í ì€íž:
# ê³ ì ë€ížìí¬ (10 Gbps)
# ìŒë° tcpdump: ~1 Gbps ì²ëЬ ê°ë¥
# PF_RING: ~10 Gbps
# DPDK: ~40 Gbps
# tcpdump ì±ë¥ ìž¡ì
time tcpdump -i eth0 -c 100000 -w /dev/null 'tcp'
real 0m2.345s
user 0m0.123s
sys 0m1.234s
â ~42,000 pps (packets per second)ð¡ ì©ìŽ ì€ëª :
- íší· ë¶ì êŽë š ì§ë¬žë€(Q19-Q23)ìì ì¬ì©ë ì©ìŽë€(Ethernet Frame, IP Packet, TCP Segment, MTU/MSS, PMTUD, TCP Window Scaling, BPF ë±)ì ëí
- ììží ì€ëª ì 묞ì ìëšì 죌ì ì©ìŽ íµí© ì 늬 > íší· ë¶ì & ížë¬ëžìí ì¹ì ì ì°žê³ íìžì.