한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › ต้นเหตุของการส่งซ้ำใน TCP

อุปกรณ์กลางทางตัด TCP option ทิ้ง Middlebox strips TCP options

ID สาเหตุ rt-sack-stripped · ผู้รับผิดชอบหลัก อินฟราเครือข่าย (ทีมอินฟรา) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

ถ้าไฟร์วอลล์หรืออุปกรณ์เร่งความเร็วบางตัวลบหรือแก้ TCP option เมื่อแพ็กเก็ตหายหลายตัว จะกู้คืนได้แค่ตัวเดียวต่อหนึ่งรอบไปกลับ หรือ window (ปริมาณที่ส่งได้ในครั้งเดียว) จะเล็กลงจนช้า

ทำไม “TCP normalization” ของไฟร์วอลล์ หรืออุปกรณ์เร่งความเร็วรุ่นเก่าลบ option SACK, timestamps และ window scaling → ผลคือ ถ้าแพ็กเก็ตหายหลายตัว จะกู้คืนได้ทีละตัวต่อรอบไปกลับ, window ถูกจำกัดไว้ที่ 64 KB → บนหน้าจอ ทุกครั้งที่หายจะค้างนานขึ้นมาก (ไม่มี SACK ก็ใช้ RACK-TLP ไม่ได้) แล้วตามด้วยอาการกรอเร็ว การส่งข้อมูลปริมาณมากอย่างแพตช์ก็ช้า

อาการ
ค้าง, กรอเร็ว
ปัจจัย
การหยุดชะงัก, ความหน่วง
ใครเจอ
บางพื้นที่/บาง ISP, ทั้งเซิร์ฟเวอร์
เกิดเมื่อไร
ตลอดเวลา
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก อินฟราเครือข่าย (ทีมอินฟรา) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
งานฝั่งทีมอินฟรา
เครือข่าย: ปิดการตั้งค่า TCP normalization ของอุปกรณ์นั้น, ตรวจ sequence randomization ของไฟร์วอลล์ด้วย, เทียบ option ใน SYN จาก packet capture ที่ปลายทั้งสองฝั่ง เครื่องเซิร์ฟเวอร์/OS: ตรวจว่าการเชื่อมต่อที่ไม่มี sack และ wscale ใน ss -ti กระจุกที่เส้นทางใดหรือไม่ (PC Windows บางเครื่องไม่ใช้ ts ตามการตั้งค่า การที่ขาดแค่ ts จึงอาจเป็นเรื่องปกติ), ตรวจว่า net.ipv4.tcp_sack ของเซิร์ฟเวอร์เป็น 1
บนกราฟ
สูงตลอดตั้งแต่แรก · จำนวนการกู้คืนที่เริ่มโดยไม่มี SACK (TcpExtTCPRenoRecovery)
จุดที่ต้องดู
ดูว่าแต่ละการเชื่อมต่อใน ss -ti มี sack และ wscale หรือไม่ ดูสัดส่วน TcpExtTCPRenoRecovery (การกู้คืนที่เริ่มโดยไม่มี SACK) ต่อ TcpExtTCPSackRecovery และ TcpExtTCPSACKDiscard (จำนวน SACK block ที่ทิ้งเพราะตัวเลขไม่สอดคล้องกัน) ใน nstat เส้นทางที่สงสัยให้ capture SYN ที่ปลายทั้งสองฝั่งแล้วเทียบ option (เช่น tcp.options.sack_perm ใน Wireshark)
สัญญาณว่าใช่
เฉพาะการเชื่อมต่อที่ผ่านเส้นทางหรืออุปกรณ์หนึ่งที่ไม่มี sack และ wscale และสัดส่วน TcpExtTCPRenoRecovery สูง option อนุญาต SACK ที่มีใน SYN ฝั่งส่งไม่มีใน SYN ฝั่งรับ ถ้าสาเหตุคือ sequence randomization option จะยังอยู่ แต่ TcpExtTCPSACKDiscard เพิ่มขึ้น
สัญญาณว่าไม่ใช่
ทุกการเชื่อมต่อไม่มี sack: ตรวจค่า net.ipv4.tcp_sack ของเซิร์ฟเวอร์ก่อน ถ้า option ครบและ TcpExtTCPSACKDiscard ไม่ขยับ การกู้คืนช้ามาจากที่อื่น (“thin stream กู้คืนช้า”)
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
รายละเอียดเพิ่มเติม
ถึง option ยังอยู่ SACK ก็อาจเสียได้ ถ้า sequence randomization ของไฟร์วอลล์เปลี่ยนแค่ sequence number ใน header แต่ไม่แก้ตัวเลขใน SACK ฝั่งส่งจะทิ้ง SACK ที่ตัวเลขไม่สอดคล้องกัน กรณีที่ปิด tcp_sack=0 บนเซิร์ฟเวอร์ไว้ตอนเกิดปัญหาความปลอดภัยของ SACK ในปี 2019 แล้วลืมเปิดคืน ก็ให้ผลแบบเดียวกัน

แหล่งอ้างอิง

  1. RFC 2018: TCP Selective Acknowledgment Options IETF
    ถ้าไม่มี SACK และมีแค่ cumulative ACK จะรู้ได้แค่แพ็กเก็ตที่หายหนึ่งตัวต่อรอบไปกลับ
  2. RFC 7323: TCP Extensions for High Performance IETF
    ถ้าไม่มี option window scaling window จะใหญ่สุด 2^16 = 64 KiB
  3. RFC 8985: The RACK-TLP Loss Detection Algorithm for TCP IETF
    RACK-TLP ต้องใช้ SACK
  4. net/ipv4/tcp_output.c Linux kernel
    TLP ของ Linux ถูกตั้งเวลาเฉพาะในการเชื่อมต่อที่ใช้ SACK
  5. IP Sysctl Linux kernel
    tcp_sack ค่าเริ่มต้น 1 (เปิด)
  6. misc/ss.c iproute2
    ss -ti แสดง ts, sack, wscale:ส่ง,รับ ตาม option ที่การเชื่อมต่อใช้
  7. tcp: limit payload size of sacked skbs Linux kernel
    commit แก้ช่องโหว่การจัดการ SACK ปี 2019 (CVE-2019-11477)
  8. Linux and FreeBSD Kernel: Multiple TCP-based remote denial of service vulnerabilities (NFLX-2019-001) Netflix
    ตอนนั้นมีการแนะนำ tcp_sack=0 (ปิดการจัดการ SACK) เป็นมาตรการชั่วคราว
  9. SNMP counter Linux kernel
    TcpExtTCPRenoRecovery (เริ่มกู้คืนโดยไม่มี SACK) และ TcpExtTCPSackRecovery (เริ่มกู้คืนด้วย SACK), TcpExtTCPSACKDiscard (จำนวน SACK block ที่ไม่ถูกต้อง)
  10. Display Filter Reference: Transmission Control Protocol Wireshark
    display filter tcp.options.sack_perm (option อนุญาต SACK ใน SYN)

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: ต้นเหตุของการส่งซ้ำใน TCP

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (ค้าง)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง