3 คะแนน โดย GN⁺ 2024-10-06 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เมื่อสัดส่วนทราฟฟิก QUIC และ HTTP/3 เพิ่มขึ้น mitmproxy 11 จึง เปิดใช้ HTTP/3 เป็นค่าเริ่มต้น เพื่อขยายขอบเขตการวิเคราะห์ทราฟฟิกเว็บยุคใหม่
  • HTTP/3 ทำงานได้ไม่เพียงในพร็อกซีแบบโปร่งใสและรีเวิร์สพร็อกซีเท่านั้น แต่ยังรวมถึง WireGuard และ local mode จึงนำไปใช้กับสภาพแวดล้อมการจับทราฟฟิกได้หลากหลาย
  • Chrome ไม่เชื่อถือ Certificate Authority ที่ผู้ใช้เพิ่มเองบน QUIC จึงต้องเลือกอย่างใดอย่างหนึ่งระหว่างใบรับรองที่ได้รับความเชื่อถือแบบสาธารณะ, สวิตช์บรรทัดคำสั่ง หรือการ fallback ไปใช้ HTTP/2
  • การติดตั้งใช้งาน DNS เปลี่ยนมาอิง Hickory DNS โดยรองรับคิวรีอื่นนอกเหนือจาก A/AAAA, HTTPS records, DNS-over-TCP, การควบคุมไฟล์ hosts และการลบคีย์ ECH
  • ฟีเจอร์ด้านความเป็นส่วนตัวอย่าง ECH ทำให้โฟลว์การสร้างใบรับรองของพร็อกซีแบบ man-in-the-middle ยากขึ้น แต่ mitmproxy ยังคงความเป็นไปได้ในการทำงานด้วยการปรับแต่งการตอบกลับ DNS

ขอบเขตการรองรับ HTTP/3

  • mitmproxy 11 รองรับ HTTP/3 ในโหมดพร็อกซีแบบโปร่งใสและรีเวิร์สพร็อกซี
  • ในรีเวิร์สพร็อกซี mitmproxy อินสแตนซ์เดียวจะรับทั้งแพ็กเก็ต TCP และ UDP และจัดการเวอร์ชัน HTTP ที่ถูกส่งต่อมา
    • ตัวอย่างคำสั่ง:
      mitmproxy --mode reverse:https://http3.is
      
  • WireGuard และ local mode ก็สามารถใช้ HTTP/3 ได้เช่นกัน
    • ตัวอย่างคำสั่ง:
      mitmproxy --mode wireguard
      mitmproxy --mode local
      
  • ทดสอบกับ Firefox, Chrome, cURL หลายบิลด์ และไคลเอนต์อื่น ๆ เพื่อลดปัญหาความเข้ากันได้
  • งานรองรับ HTTP/3 เริ่มขึ้นในปี 2022 โดย Manuel Meitinger และ Maximilian Hils และถูกเปิดใช้เป็นค่าเริ่มต้นใน mitmproxy 11

ข้อจำกัดใบรับรอง QUIC ของ Chrome

  • ข้อจำกัดหลักที่ทราบในปัจจุบันคือ Chrome ไม่เชื่อถือ Certificate Authority ที่ผู้ใช้เพิ่มเองบน QUIC
  • หากต้องการจัดการทราฟฟิก HTTP/3 ใน Chrome จำเป็นต้องใช้อย่างใดอย่างหนึ่งต่อไปนี้
    • จัดเตรียมใบรับรองที่ได้รับความเชื่อถือแบบสาธารณะ เช่น Let’s Encrypt
    • รัน Chrome พร้อม สวิตช์บรรทัดคำสั่ง ที่เกี่ยวข้อง
    • ยอมรับพฤติกรรมที่ fallback ไปใช้ HTTP/2
  • Firefox ไม่มีพฤติกรรมเช่นนี้
  • ดูทิปการแก้ปัญหา HTTP/3 ได้ที่ #7025

การสร้างใหม่บนฐาน Hickory DNS

  • เมื่อฟีเจอร์ด้านความเป็นส่วนตัวอย่าง DNS HTTPS records และ Encrypted Client Hello(ECH) ปรากฏขึ้น ความสำคัญของการประมวลผล DNS ใน mitmproxy จึงเพิ่มขึ้น
  • การติดตั้งใช้งาน DNS เดิมใช้ getaddrinfo จึงมีข้อจำกัด
    • รองรับเฉพาะ คิวรี A/AAAA สำหรับที่อยู่ IPv4 และ IPv6
    • ไม่สามารถตอบคิวรีอย่าง HTTPS records ที่แจ้งการรองรับ HTTP/3 ได้
  • mitmproxy 11 สร้างการรองรับ DNS ขึ้นใหม่บน Hickory DNS ซึ่งเป็นไลบรารี DNS ที่ใช้ Rust
  • ด้วย Hickory ระบบจะดึงเนมเซิร์ฟเวอร์ค่าเริ่มต้นของระบบปฏิบัติการบน Windows, Linux และ macOS และส่งต่อคิวรีที่ไม่ใช่ A/AAAA ไปยังเนมเซิร์ฟเวอร์เหล่านั้น
  • สามารถกำหนดเนมเซิร์ฟเวอร์ปลายทางสำหรับการส่งต่อได้ด้วย dns_name_servers option ใหม่
    mitmdump --mode dns --set dns_name_servers=8.8.8.8
    

การควบคุมไฟล์ hosts และ DNS-over-TCP

  • พร้อมกับการย้ายไปใช้ Hickory มีการเพิ่มตัวเลือกสำหรับละเว้น ไฟล์ hosts ของระบบ
  • ใช้ dns_use_hosts_file option ใหม่เพื่อควบคุมว่าจะนำไฟล์ hosts เช่น /etc/hosts บน Linux มาใช้หรือไม่
  • มีแผนจะย้ายการแก้ชื่อ DNS ภายในของ mitmproxy ไปยัง Hickory ด้วย และหลังจากนั้นฟีเจอร์นี้จะมีประโยชน์เมื่อทำการรีไดเรกต์โดเมนเฉพาะแบบโปร่งใสบนเครื่องเดียวกัน
    • ปัจจุบัน mitmproxy จะพิจารณาไฟล์ hosts เสมอ จึงอาจเชื่อมต่อแบบวนซ้ำกลับเข้าหาตัวเองในการตั้งค่ารีไดเรกต์บนเครื่องเดียวกัน
  • ตัวอย่างพฤติกรรม:
    echo "192.0.2.1 mitmproxy.org" >> /etc/hosts
    mitmdump --mode dns
    dig @127.0.0.1 +short mitmproxy.org
    192.0.2.1
    mitmdump --mode dns --set dns_use_hosts_file=false
    dig @127.0.0.1 +short mitmproxy.org
    3.161.82.13
    
  • โดยค่าเริ่มต้น DNS ใช้ UDP แต่เมื่อจัดการเรคอร์ดที่ไม่พอดีในแพ็กเก็ต UDP เดียว อาจจำเป็นต้องใช้ TCP
  • เมื่อ mitmproxy 11 รองรับประเภทคิวรีใด ๆ ความสำคัญของขนาดข้อความและการประมวลผล TCP จึงเพิ่มขึ้น และ DNS-over-TCP ก็ทำงานได้ด้วย

การลบคีย์ ECH และการสร้างใบรับรอง

  • เมื่อไม่มีใบรับรองที่ผู้ใช้กำหนดเอง mitmproxy จะใช้ Server Name Indication(SNI) ใน TLS ClientHello เพื่อประกอบใบรับรองที่ถูกต้อง
  • หากไม่มี SNI อาจไม่สามารถสร้างใบรับรองที่ไคลเอนต์จะเชื่อถือได้
  • Encrypted Client Hello(ECH) เป็นวิธีที่ไคลเอนต์รับคีย์ ECH ผ่าน DNS HTTPS records แล้วเข้ารหัสข้อความแฮนด์เชก ClientHello เริ่มต้นด้วยคีย์นั้น
  • หากทั้งคิวรี DNS และแฮนด์เชกถูกเข้ารหัส ผู้ดักกลางแบบพาสซีฟจะไม่สามารถรู้โดเมนเป้าหมาย และจะเห็นได้เพียงที่อยู่ IP เป้าหมายเท่านั้น
    • ใน shared hosting และ Content Delivery Networks การยืนยันโดเมนเป้าหมายจากที่อยู่ IP เพียงอย่างเดียวทำได้ยาก
  • การปรับปรุงความเป็นส่วนตัวนี้ขัดแย้งกับวิธีสร้างใบรับรองของ mitmproxy
  • mitmproxy 11 ลบคีย์ ECH ออกจาก HTTPS records เพื่อให้ได้ข้อมูลโดเมนที่จำเป็นต่อการสร้างใบรับรอง
    • ไคลเอนต์จะไม่ได้รับคีย์สำหรับเข้ารหัสข้อความแฮนด์เชกเริ่มต้น
    • mitmproxy สามารถระบุโดเมนเป้าหมายและประกอบใบรับรองที่ตรงกันได้
  • ECH อาจทำให้การใช้ mitmproxy ยากขึ้น แต่ถือเป็นการเปลี่ยนแปลงที่ช่วยเพิ่มความเป็นส่วนตัวโดยรวมของเว็บ

1 ความคิดเห็น

 
GN⁺ 2024-10-06
ความคิดเห็นจาก Hacker News
  • ดีใจที่ Mitmproxy ยังมีการพัฒนาอยู่ เครื่องมือนี้มีส่วนสร้างเส้นทางอาชีพของผมทางอ้อมเลย
    เมื่อปี 2011 ตอนที่ผมกำลังเรียนรู้การพัฒนา API โดยดักจับ request ของแอปมือถือ ผมพบว่า Airbnb API เปิดช่องให้โจมตีผ่านช่องโหว่ mass assignment ของ Rails (https://github.com/rails/rails/issues/5228) หลังจากลองเปลี่ยนแอตทริบิวต์ที่ไม่เป็นอันตรายไม่กี่อย่าง ผมก็ติดต่อบริษัทไป เรื่องนั้นนำไปสู่การสัมภาษณ์งาน และจากนั้นก็กลายเป็นประวัติศาสตร์ตามตัวอักษร

    • จำนวน นักพัฒนาหลัก ใน issue นั้นที่คัดค้านการเปลี่ยนแปลงนี่มากจนน่าเหลือเชื่อจริง ๆ
    • ทุกวันนี้มันยังมีประโยชน์มากสำหรับผม แต่คนที่น่าจะรู้จักหลายคนกลับไม่ค่อยรู้จัก Mitmproxy อย่างน่าประหลาดใจ
      บางครั้งการเอา mitmproxy ไปครอบ implementation ที่มีอยู่ก็ง่ายขายกว่าการอ่านเอกสาร
  • น่าสนใจที่ Chrome ไม่เชื่อถือ certificate authority ที่ผู้ใช้เพิ่มเองใน QUIC
    ใน issue ที่ลิงก์ไว้ ทีม Chrome บอกว่า “เราไม่อนุญาต certificate ที่ไม่ได้รับความเชื่อถือแบบสาธารณะโดยชัดเจน เพื่อป้องกันการ deploy ซอฟต์แวร์/ฮาร์ดแวร์สำหรับดักจับ QUIC ไม่เช่นนั้นในระยะยาวจะทำลายความสามารถในการวิวัฒนาการของโปรโตคอล QUIC กรณีใช้งานที่พึ่งพา certificate ที่ไม่ใช่ public trust certificate ควรใช้ TLS+TCP แทน QUIC”
    ผมไม่ได้ตามวิวัฒนาการของโปรโตคอลนี้ แต่ไม่ค่อยเข้าใจว่าการบล็อก certificate แบบกำหนดเองเกี่ยวข้องกับ ความสามารถในการวิวัฒนาการ อย่างไร อยากรู้ว่ามีใครทราบเหตุผลไหม

    • เดาว่าเพราะ Google ควบคุมได้ทั้งฝั่งไคลเอนต์และ endpoint เซิร์ฟเวอร์รายใหญ่ ๆ (Google Search, Youtube ฯลฯ) เลยอยากมีอิสระในการ ทดลองเปลี่ยนแปลง QUIC
      พวกเขาใส่ QUIC เวอร์ชันที่แก้ไขเล็กน้อยลงใน Chrome แล้วให้ที่อย่าง Youtube รองรับ จากนั้นใช้ตัวชี้วัดที่ได้ไปเสนอการเปลี่ยนมาตรฐาน “จริง” หรือจะรันเวอร์ชันพิเศษเฉพาะในบริการของตัวเองต่อไปก็ได้
      ถ้าอนุญาต certificate แบบกำหนดเอง องค์กรที่ตรวจสอบทราฟฟิกพนักงานแบบ man-in-the-middle ด้วยของอย่าง ZScaler ZIA ก็เสี่ยงจะพังเมื่อมีการเปลี่ยนโปรโตคอล ถ้า data stream ถูกเข้ารหัสทั้งหมดจน middlebox มองไม่เห็น Google ก็ทำได้แทบทุกอย่างตามต้องการ
      แนวคิดที่เกี่ยวข้อง: https://en.wikipedia.org/wiki/Protocol_ossification
    • middlebox(https://en.m.wikipedia.org/wiki/Middlebox) เป็นสาเหตุที่รู้กันดีของการทำให้โปรโตคอลหยุดนิ่ง
      โปรโตคอลที่ขยายได้โดยปกติแค่อัปเกรดไคลเอนต์กับเซิร์ฟเวอร์ก็พอ แต่ถ้ามี middlebox ก็อาจต้องอัปเดตอุปกรณ์อีก N ตัวด้วย ผู้ใช้และผู้ให้บริการมีแรงจูงใจในการนำฟีเจอร์ใหม่มาใช้ แต่เจ้าของ middlebox อาจไม่มี ผลก็คือโปรโตคอลวิวัฒนาการได้ยากขึ้น
    • อาจหมายถึงกรณีดังที่สถาบันการเงินคัดค้าน TLS 1.3 ก็ได้ แรงจูงใจคือไม่อยากอัปเดตซอฟต์แวร์ man-in-the-middle ที่จำเป็นต่อการปฏิบัติตามกฎระเบียบ: https://mailarchive.ietf.org/arch/msg/tls/CzjJB1g0uFypY8UDdr6P9SCQBqA/
    • เหตุผลหนึ่งที่สร้าง HTTP 2 และ 3 ขึ้นมาก็เพราะการ เปลี่ยนแปลง HTTP 1.1 ทำได้ยากเกินไป
      มี middleware จำนวนมากที่พึ่งพารายละเอียด implementation อย่างหนัก พอเปลี่ยนอะไรเล็กน้อยก็ทำให้ประสบการณ์ผู้ใช้พังโดยไม่ตั้งใจได้ง่าย ดูเหมือนว่าในเวอร์ชันใหม่จะพยายามหลีกเลี่ยงสถานการณ์แบบเดียวกัน
    • QUIC มีอยู่เพื่อเพิ่มอัตราการส่งโฆษณา ดังนั้นการให้อิสระแก่ผู้ใช้จึงขัดกับเป้าหมายนั้น
  • สงสัยว่า HTTP/2 หรือ HTTP/3 จะมีประโยชน์ไหมถ้ารองรับเฉพาะที่ reverse proxy แต่เว็บเซิร์ฟเวอร์จริงไม่รองรับ
    เฟรมเวิร์กกระแสหลักส่วนใหญ่ของ JS/Python/Ruby ไม่รองรับมาตรฐาน HTTP ใหม่ ๆ แบบนี้ ถ้าอย่างนั้นเว็บเซิร์ฟเวอร์จะไม่กลายเป็นคอขวดของการเชื่อมต่อ reverse proxy หรือ?

    • มีประโยชน์ HTTP/2 หรือ HTTP/3 ช่วยเพิ่ม ความน่าเชื่อถือ ของการเชื่อมต่อระหว่างไคลเอนต์กับ reverse proxy
      การเชื่อมต่อระหว่าง reverse proxy กับเว็บเซิร์ฟเวอร์จริงมักเร็วและเสถียรกว่ามาก ดังนั้นการอัปเกรดช่วงนั้นเป็น HTTP/2 หรือ HTTP/3 จึงให้ประโยชน์น้อยกว่ามาก
    • การส่งข้อมูลระหว่าง reverse proxy กับ backend ก็ไม่ได้เป็น HTTP เสมอไป เช่น Python อาจใช้ uWSGI และ PHP อาจใช้ FastCGI
      แม้ในกรณีที่ใช้ HTTP reverse proxy ก็สามารถเชื่อมต่อกับ backend ได้เร็วกว่ากับไคลเอนต์ระยะไกลจริงมาก ดังนั้นการใช้ HTTP/2 stream ในช่วงที่ช้ายังคงได้เปรียบ
    • อาจไม่ค่อยเกี่ยวกันนัก แต่ mitmproxy ไม่ใช่ reverse proxy สำหรับ production
      มันเป็นเครื่องมือที่รันบนเครื่อง local เพื่อทดสอบโปรโตคอลระดับต่ำหรือเรื่องความปลอดภัยเว็บ
    • มีประเด็นหนึ่งที่ขาดไป เว็บเบราว์เซอร์จำกัดจำนวนการเชื่อมต่อ 6 รายการ ต่อโดเมน
      ตั้งแต่ HTTP/2 ขึ้นไป คำขอพร้อมกันหลายรายการจะถูกจัดการผ่านการเชื่อมต่อเดียว
    • มีประโยชน์ นอกจากข้อดีด้านประสิทธิภาพอื่น ๆ แล้ว HTTP/3 ยังรวม TCP และ TLS handshake เข้าด้วยกัน ทำให้ลด round trip 1 ครั้ง ตอนเชื่อมต่อ
  • ยังมีปัญหาเรื่อง fingerprinting อยู่ จนกว่าจะเลียนแบบ TLS handshake ของเบราว์เซอร์ทั่วไปได้ คุณจะเห็นหน้าอย่าง “Just a quick check...” หรือ “Sorry, it looks like you're a bot” ในเว็บราว 80%
    https://github.com/mitmproxy/mitmproxy/issues/4575

    • ถ้าอย่างนั้น Firefox ก็คงไม่ใช่ เบราว์เซอร์ทั่วไป อีกต่อไปแล้วสินะ
  • ขอบคุณที่พูดถึง Hickory การได้เห็นว่าผู้คนเอามันไปสร้างอะไรเป็นเรื่องสนุกเสมอ และเป็นงานที่ทำออกมาดี

    • ขอบคุณสำหรับงานบน Hickory สิ่งที่น่าสนใจจริง ๆ คือ interoperability ระหว่าง Python↔Rust ของ PyO3 ทำให้สามารถใช้ไลบรารี DNS ระดับ production อย่าง Hickory และสแตกเครือข่าย userspace ที่แข็งแรงอย่าง smoltcp จาก Python ได้
      ของแบบนี้เดิมทีคงทำได้ยากถ้าใช้ Python ล้วน ๆ
  • สงสัยว่าสามารถใช้ Mitmproxy แบบเดียวกับ Privoxy/Proxomitron/Yarip ได้ไหม
    เช่น เวลาเปิดเว็บด้วย Ungoogled Chromium แล้วตั้ง Mitmproxy เป็น proxy เพื่อเอาแท็ก script ของบางเว็บไซต์ออกได้หรือเปล่า? จะมีผลต่อประสิทธิภาพแค่ไหน?

    • ตามทฤษฎีทำได้ ในทางปฏิบัติ mitmproxy เขียนด้วย Python จึงมี latency เพราะภาษานี้ไม่ได้เร็วมาก
      เวลาเปิดเว็บเพจ ความหน่วงเล็ก ๆ ที่สะสมหลายร้อยครั้งอาจรู้สึกได้
      ถึงอย่างนั้นมันก็อาจเป็นตัวเลือกสำหรับคนที่สนใจการใช้งานแบบนี้ ไม่มีอะไรปิดกั้นในเชิงเทคนิค
      ตอน rewrite ไฟล์ JavaScript มีความเสี่ยงเล็กน้อยว่าจะกระทบการตรวจสอบ subresource integrity แต่ถ้ามีปัญหาจริงก็น่าจะแก้ได้ด้วยการ rewrite hash ด้วย
  • mitmproxy ใช้แทน Fiddler ได้ไหม?

    • เรียกได้ว่าเกือบใช่ สิ่งที่ผมชอบใน mitmproxy คือการใช้ Python plugin เพื่อดักจับหรือแก้ไข request และ response ทำได้ง่าย
      https://docs.mitmproxy.org/stable/addons-overview/
  • อืม: https://github.com/mitmproxy/mitmproxy/issues/4170