Mitmproxy 11: รองรับ HTTP/3 อย่างสมบูรณ์
(mitmproxy.org)- เมื่อสัดส่วนทราฟฟิก 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_serversoption ใหม่mitmdump --mode dns --set dns_name_servers=8.8.8.8
การควบคุมไฟล์ hosts และ DNS-over-TCP
- พร้อมกับการย้ายไปใช้ Hickory มีการเพิ่มตัวเลือกสำหรับละเว้น ไฟล์ hosts ของระบบ
- ใช้
dns_use_hosts_fileoption ใหม่เพื่อควบคุมว่าจะนำไฟล์ 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 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ดีใจที่ Mitmproxy ยังมีการพัฒนาอยู่ เครื่องมือนี้มีส่วนสร้างเส้นทางอาชีพของผมทางอ้อมเลย
เมื่อปี 2011 ตอนที่ผมกำลังเรียนรู้การพัฒนา API โดยดักจับ request ของแอปมือถือ ผมพบว่า Airbnb API เปิดช่องให้โจมตีผ่านช่องโหว่ mass assignment ของ Rails (https://github.com/rails/rails/issues/5228) หลังจากลองเปลี่ยนแอตทริบิวต์ที่ไม่เป็นอันตรายไม่กี่อย่าง ผมก็ติดต่อบริษัทไป เรื่องนั้นนำไปสู่การสัมภาษณ์งาน และจากนั้นก็กลายเป็นประวัติศาสตร์ตามตัวอักษร
บางครั้งการเอา mitmproxy ไปครอบ implementation ที่มีอยู่ก็ง่ายขายกว่าการอ่านเอกสาร
น่าสนใจที่ Chrome ไม่เชื่อถือ certificate authority ที่ผู้ใช้เพิ่มเองใน QUIC
ใน issue ที่ลิงก์ไว้ ทีม Chrome บอกว่า “เราไม่อนุญาต certificate ที่ไม่ได้รับความเชื่อถือแบบสาธารณะโดยชัดเจน เพื่อป้องกันการ deploy ซอฟต์แวร์/ฮาร์ดแวร์สำหรับดักจับ QUIC ไม่เช่นนั้นในระยะยาวจะทำลายความสามารถในการวิวัฒนาการของโปรโตคอล QUIC กรณีใช้งานที่พึ่งพา certificate ที่ไม่ใช่ public trust certificate ควรใช้ TLS+TCP แทน QUIC”
ผมไม่ได้ตามวิวัฒนาการของโปรโตคอลนี้ แต่ไม่ค่อยเข้าใจว่าการบล็อก certificate แบบกำหนดเองเกี่ยวข้องกับ ความสามารถในการวิวัฒนาการ อย่างไร อยากรู้ว่ามีใครทราบเหตุผลไหม
พวกเขาใส่ QUIC เวอร์ชันที่แก้ไขเล็กน้อยลงใน Chrome แล้วให้ที่อย่าง Youtube รองรับ จากนั้นใช้ตัวชี้วัดที่ได้ไปเสนอการเปลี่ยนมาตรฐาน “จริง” หรือจะรันเวอร์ชันพิเศษเฉพาะในบริการของตัวเองต่อไปก็ได้
ถ้าอนุญาต certificate แบบกำหนดเอง องค์กรที่ตรวจสอบทราฟฟิกพนักงานแบบ man-in-the-middle ด้วยของอย่าง ZScaler ZIA ก็เสี่ยงจะพังเมื่อมีการเปลี่ยนโปรโตคอล ถ้า data stream ถูกเข้ารหัสทั้งหมดจน middlebox มองไม่เห็น Google ก็ทำได้แทบทุกอย่างตามต้องการ
แนวคิดที่เกี่ยวข้อง: https://en.wikipedia.org/wiki/Protocol_ossification
โปรโตคอลที่ขยายได้โดยปกติแค่อัปเกรดไคลเอนต์กับเซิร์ฟเวอร์ก็พอ แต่ถ้ามี middlebox ก็อาจต้องอัปเดตอุปกรณ์อีก N ตัวด้วย ผู้ใช้และผู้ให้บริการมีแรงจูงใจในการนำฟีเจอร์ใหม่มาใช้ แต่เจ้าของ middlebox อาจไม่มี ผลก็คือโปรโตคอลวิวัฒนาการได้ยากขึ้น
มี middleware จำนวนมากที่พึ่งพารายละเอียด implementation อย่างหนัก พอเปลี่ยนอะไรเล็กน้อยก็ทำให้ประสบการณ์ผู้ใช้พังโดยไม่ตั้งใจได้ง่าย ดูเหมือนว่าในเวอร์ชันใหม่จะพยายามหลีกเลี่ยงสถานการณ์แบบเดียวกัน
สงสัยว่า HTTP/2 หรือ HTTP/3 จะมีประโยชน์ไหมถ้ารองรับเฉพาะที่ reverse proxy แต่เว็บเซิร์ฟเวอร์จริงไม่รองรับ
เฟรมเวิร์กกระแสหลักส่วนใหญ่ของ JS/Python/Ruby ไม่รองรับมาตรฐาน HTTP ใหม่ ๆ แบบนี้ ถ้าอย่างนั้นเว็บเซิร์ฟเวอร์จะไม่กลายเป็นคอขวดของการเชื่อมต่อ reverse proxy หรือ?
การเชื่อมต่อระหว่าง reverse proxy กับเว็บเซิร์ฟเวอร์จริงมักเร็วและเสถียรกว่ามาก ดังนั้นการอัปเกรดช่วงนั้นเป็น HTTP/2 หรือ HTTP/3 จึงให้ประโยชน์น้อยกว่ามาก
แม้ในกรณีที่ใช้ HTTP reverse proxy ก็สามารถเชื่อมต่อกับ backend ได้เร็วกว่ากับไคลเอนต์ระยะไกลจริงมาก ดังนั้นการใช้ HTTP/2 stream ในช่วงที่ช้ายังคงได้เปรียบ
มันเป็นเครื่องมือที่รันบนเครื่อง local เพื่อทดสอบโปรโตคอลระดับต่ำหรือเรื่องความปลอดภัยเว็บ
ตั้งแต่ HTTP/2 ขึ้นไป คำขอพร้อมกันหลายรายการจะถูกจัดการผ่านการเชื่อมต่อเดียว
ยังมีปัญหาเรื่อง fingerprinting อยู่ จนกว่าจะเลียนแบบ TLS handshake ของเบราว์เซอร์ทั่วไปได้ คุณจะเห็นหน้าอย่าง “Just a quick check...” หรือ “Sorry, it looks like you're a bot” ในเว็บราว 80%
https://github.com/mitmproxy/mitmproxy/issues/4575
ขอบคุณที่พูดถึง Hickory การได้เห็นว่าผู้คนเอามันไปสร้างอะไรเป็นเรื่องสนุกเสมอ และเป็นงานที่ทำออกมาดี
ของแบบนี้เดิมทีคงทำได้ยากถ้าใช้ Python ล้วน ๆ
สงสัยว่าสามารถใช้ Mitmproxy แบบเดียวกับ Privoxy/Proxomitron/Yarip ได้ไหม
เช่น เวลาเปิดเว็บด้วย Ungoogled Chromium แล้วตั้ง Mitmproxy เป็น proxy เพื่อเอาแท็ก script ของบางเว็บไซต์ออกได้หรือเปล่า? จะมีผลต่อประสิทธิภาพแค่ไหน?
เวลาเปิดเว็บเพจ ความหน่วงเล็ก ๆ ที่สะสมหลายร้อยครั้งอาจรู้สึกได้
ถึงอย่างนั้นมันก็อาจเป็นตัวเลือกสำหรับคนที่สนใจการใช้งานแบบนี้ ไม่มีอะไรปิดกั้นในเชิงเทคนิค
ตอน rewrite ไฟล์ JavaScript มีความเสี่ยงเล็กน้อยว่าจะกระทบการตรวจสอบ subresource integrity แต่ถ้ามีปัญหาจริงก็น่าจะแก้ได้ด้วยการ rewrite hash ด้วย
mitmproxy ใช้แทน Fiddler ได้ไหม?
https://docs.mitmproxy.org/stable/addons-overview/
อืม: https://github.com/mitmproxy/mitmproxy/issues/4170