2 คะแนน โดย zxsi2003 12 일 전 | 4 ความคิดเห็น | แชร์ทาง WhatsApp

สวัสดีครับ นี่คือเครื่องมือที่ผมสร้างขึ้นเพราะมีสถานการณ์ซ้ำ ๆ ที่อยากส่งเฉพาะทราฟฟิกของบางพอร์ตที่กำลังออกไปยังเซิร์ฟเวอร์ภายนอก
ไปยัง mock server ที่รันไว้บนเครื่องชั่วคราว
(ใช้ Claude Code ช่วย)

ไฟล์ hosts ไม่รองรับการแมปเป็นรายพอร์ต และพร็อกซีก็จะทำงานได้ก็ต่อเมื่อ
แอปพลิเคชันรองรับพร็อกซี
detour ดักแพ็กเก็ตในชั้นที่ต่ำกว่า (เคอร์เนล)
ดังนั้นแอปพลิเคชันจึงยังคงทำงานเหมือนเดิม โดยคิดว่าตัวเอง dial ไปยังที่อยู่เดิม

วิธีการทำงาน

  • ใช้ไดรเวอร์ WinDivert ดัก outbound packet ที่เคอร์เนล แล้ว
    ทำ destination NAT ใน userspace → rewrite ปลายทางเป็น TO แล้วคำนวณ checksum ใหม่ก่อนฉีดกลับเข้าไป
  • สำหรับ response packet จะ rewrite ต้นทางกลับเป็น FROM
    แล้วส่งกลับไป ทำให้แอปพลิเคชันรับรู้ราวกับว่าที่อยู่ที่มัน dial ไว้เป็นผู้ตอบกลับ
  • มีผลกับทั้งระบบ (ไม่มีการกรองตาม PID)

องค์ประกอบ

  • detour.exe (CLI): ใช้คำสั่งบรรทัดเดียว --from 1.2.3.4:5000 --to 127.0.0.1:5001 เพื่อใช้กฎ
    และยกเลิกด้วย Ctrl+C
  • detour-gui.exe: ไอคอน tray + ตารางหลายกฎ
    บันทึกกฎอัตโนมัติไว้ที่ %APPDATA%\detour\rules.json และกู้คืนเมื่อเปิดครั้งถัดไป
    แต่ละกฎจะมีคู่ WinDivert handle ของตัวเอง จึงใช้งานการเปลี่ยนเส้นทางหลายรายการพร้อมกันได้
  • ฝัง UAC manifest มาให้ — ดับเบิลคลิกแล้วมีพรอมป์ต์ยกระดับสิทธิ์อัตโนมัติ
  • ฝัง WinDivert.dll / WinDivert64.sys ไว้ในไบนารีด้วย —
    จบใน exe เดียวโดยไม่ต้องติดตั้งไดรเวอร์แยก

สแตก

  • Go 1.23+
  • GUI ใช้ lxn/walk (เรียก Win32 โดยตรง ไม่มี dependency ของ cgo จึง cross-compile จาก macOS ได้)
  • รีลีสแพ็กด้วย GoReleaser เป็น zip เดียว (รวมทั้ง CLI + GUI)

ข้อจำกัด (v1)

  • รองรับเฉพาะ IPv4 (ยังไม่รองรับ IPv6)
  • ทราฟฟิก local ↔ local (127.0.0.1) อาจทำงานไม่สม่ำเสมอ เพราะ Windows networking stack จัดการเป็นกรณีพิเศษ
  • ยังไม่ได้ทำ TCP MSS clamping — ถ้า MTU ของเส้นทางที่เปลี่ยนไปมีขนาดเล็กกว่า อาจเกิด fragmentation ได้

ไลเซนส์คือ GPLv3 (WinDivert พึ่งพา LGPLv3)
ยินดีรับ feedback / use case / bug report ครับ

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

 
kaydash 11 일 전

ก็หมายถึงพร็อกซีใช่ไหม..?

 
zxsi2003 11 일 전

พูดอย่างเคร่งครัดแล้ว นี่อาจมองได้ว่าเป็น Destination NAT มากกว่าจะเป็นพร็อกซี ผมสรุปกรณีการใช้งานที่ผมใช้ไว้ด้านล่าง เพราะคำอธิบายข้างบนยาวเกินไป

  1. ต้องการส่งคำขอไปยังเซิร์ฟเวอร์บนเครื่องพีซีของผมเอง (172.16.100.201:5000) แทนที่จะส่งไปยังปลายทางของโปรแกรมไคลเอนต์ที่ถูกบิลด์มาแล้ว (1.2.3.4.:5000)

  2. เส้นทางของคำขอถูกฮาร์ดโค้ดไว้ ทำให้ในหลายกรณี หากต้องการเปลี่ยนแปลงจะต้องขอให้นักพัฒนาไคลเอนต์ทำการบิลด์ใหม่

  3. ต้องการแก้ปัญหาโดยเปลี่ยนปลายทางและเฮดเดอร์ปลายทางของทราฟฟิกที่มุ่งไปยัง IP และพอร์ตที่กำหนด (1.2.3.4.:5000) ที่ระดับเคอร์เนลของ OS ไม่ใช่ที่ระดับแอปพลิเคชัน ให้เป็น IP และพอร์ตที่ต้องการ (172.16.100.201:5000)

  4. พัฒนา detour

 
findnamo 11 일 전

สามารถทำพร็อกซีคำขอที่ป้อนเป็นที่อยู่โดเมนได้ด้วยไหม?

 
zxsi2003 11 일 전

ในกรณีที่เป็นคำขอที่ป้อนเป็นที่อยู่โดเมน เราประเมินว่าความซับซ้อนในการพัฒนาจะสูงขึ้น จึงตั้งค่าไว้ตั้งแต่แรกไม่ให้ป้อนเข้าได้... เนื่องจากพัฒนาขึ้นเพื่อใช้ทดสอบภายใน จึงไม่ได้รองรับความสามารถแบบใช้งานทั่วไป
สามารถค้นหา IP ของโดเมนที่ต้องการด้วย nslookup แล้วนำไปตั้งค่าได้

จะลองนำไปปรับใช้ในการอัปเดตครั้งถัดไปครับ