2 คะแนน โดย GN⁺ 2024-04-03 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Wireproxy คือไคลเอนต์ WireGuard แบบทำงานใน user space เต็มรูปแบบที่เชื่อมต่อกับ WireGuard peer แล้วเปิดให้ใช้งานบนเครื่องโลคัลเป็น พร็อกซี SOCKS5/HTTP หรือทันเนล
  • ออกแบบมาสำหรับกรณีที่ต้องการส่งทราฟฟิกของบางเว็บไซต์ไปยัง WireGuard peer เท่านั้นโดยไม่ต้องตั้งค่า network interface ใหม่ หรือไม่ต้องการใช้ สิทธิ์ root ในการเปลี่ยนการตั้งค่า WireGuard
  • ฟีเจอร์ประกอบด้วย TCP static routing, พร็อกซี SOCKS5/HTTP และ transparent proxy แบบอิง TLS SNI โดยพร็อกซี HTTP ตอนนี้รองรับเฉพาะ CONNECT
  • การตั้งค่าทำตามความหมายของ [Interface] และ [Peer] ใน wg-quick และสามารถนำเข้าไฟล์ตั้งค่า WireGuard เดิมด้วย WGConfig หรือกำหนดเส้นทางหลาย peer ด้วย AllowedIPs ได้
  • สำหรับการใช้งานจริง มี health endpoint ผ่าน --info/-i เพื่อตรวจสอบสถานะ WireGuard และความพร้อมแบบอิง CheckAlive ผ่าน /metrics และ /readyz

Wireproxy ทำอะไร

  • wireproxy เป็นแอปพลิเคชันแบบ user space ที่เชื่อมต่อกับ WireGuard peer และเปิดให้ใช้งานบนเครื่องโลคัลเป็น พร็อกซี SOCKS5/HTTP หรือทันเนล
  • ใช้ได้เมื่ออยากให้เฉพาะบางเว็บไซต์เชื่อมต่อผ่าน WireGuard peer แต่ไม่ต้องการสร้าง network interface ใหม่
  • ทำงานแยกจาก network interface โดยสมบูรณ์ และไม่ต้องใช้ สิทธิ์ root ในการตั้งค่า
  • ผู้ใช้ที่ต้องการการใช้งานคล้าย Amnezia VPN สามารถใช้ฟอร์ก wireproxy-awg ได้

ฟีเจอร์ที่รองรับและสิ่งที่ยังไม่มี

  • ฟีเจอร์ที่รองรับ
    • TCP static routing สำหรับไคลเอนต์และเซิร์ฟเวอร์
    • พร็อกซี SOCKS5/HTTP
      • ตอนนี้ HTTP รองรับเฉพาะ CONNECT
    • Transparent TLS proxy ที่ใช้ Server Name Indication
  • ฟีเจอร์ที่ยังอยู่ใน TODO
    • การรองรับ UDP ของ SOCKS5
    • UDP static routing

การรันและการติดตั้ง

  • รูปแบบการรันพื้นฐานคือ ./wireproxy [-c path to config]
  • ตัวเลือกหลัก
    • -c, --config: ระบุพาธของไฟล์ตั้งค่า
      • พาธเริ่มต้นคือ /etc/wireproxy/wireproxy.conf, $HOME/.config/wireproxy.conf
    • -s, --silent: โหมด silent
    • -d, --daemon: รันเบื้องหลัง
    • -i, --info: ระบุที่อยู่และพอร์ตสำหรับเปิดเผย health status
    • -v, --version: แสดงเวอร์ชัน
    • -n, --configtest: ตรวจสอบเฉพาะความถูกต้องของไฟล์ตั้งค่า
  • การ build ทำได้โดย clone รีโพซิทอรีแล้วรัน make
  • ตัวอย่างการติดตั้งใช้ go install github.com/windtf/wireproxy/cmd/wireproxy@v1.1.2 หรือ @latest

โมเดลการตั้งค่า

  • การตั้งค่า [Interface] และ [Peer] มีความหมายเหมือนกับการตั้งค่า wg-quick
  • Address ต้องใช้ซับเน็ต /32 สำหรับ IPv4 และ /128 สำหรับ IPv6
  • PrivateKey สามารถอ้างอิงตัวแปรสภาพแวดล้อมได้
  • หากมีการตั้งค่า WireGuard เดิมอยู่แล้ว สามารถนำเข้าได้ด้วย WGConfig = <path to the wireguard config>

การตั้งค่าทันเนลและพร็อกซี

  • TCPClientTunnel
    • ส่งต่อทราฟฟิก TCP ที่รับมาจากเครื่องโลคัลไปยังปลายทางที่กำหนดผ่าน WireGuard
    • ตัวอย่างเส้นทางคือ <แอป LAN> → localhost:25565 → WireGuard → play.cubecraft.net:25565
  • TCPServerTunnel
    • ส่งต่อทราฟฟิก TCP ที่รับมาจากเครือข่าย WireGuard ไปยังปลายทางที่กำหนดในเครือข่ายโลคัล
    • ตัวอย่างเส้นทางคือ <แอปในเครือข่าย WireGuard> → WireGuard → 172.16.31.2:3422 → localhost:25545
  • STDIOTunnel
    • เชื่อม standard input และ output ของโปรเซส wireproxy เข้ากับปลายทาง TCP ผ่าน WireGuard
    • มีประโยชน์สำหรับใช้เป็นพารามิเตอร์ ProxyCommand ของ openssh
  • Socks5
    • สร้างพร็อกซี SOCKS5 บน LAN โลคัล และกำหนดเส้นทางทราฟฟิกทั้งหมดผ่าน WireGuard
    • หากระบุชื่อผู้ใช้และรหัสผ่าน จะเปิดใช้การยืนยันตัวตนของพร็อกซี
  • http
    • สร้างพร็อกซี HTTP บน LAN โลคัล และกำหนดเส้นทางทราฟฟิกทั้งหมดผ่าน WireGuard
    • หากระบุชื่อผู้ใช้และรหัสผ่าน จะเปิดใช้การยืนยันตัวตน
    • หากระบุ CertFile และ KeyFile จะเปิดใช้ HTTPS
  • SNI
    • สร้าง transparent TLS proxy บน LAN โลคัล และใช้ SNI เป็นปลายทางสำหรับการกำหนดเส้นทางเพื่อส่งทราฟฟิกผ่าน WireGuard

หลาย peer และการกำหนดเส้นทาง

  • สามารถใช้ WireGuard ได้หลาย peer
  • เมื่อต้องใช้หลาย peer ต้องกำหนด AllowedIPs เพื่อให้ wireproxy รู้ว่าควรส่งต่อไปยัง peer ใด
  • ตัวอย่างการตั้งค่าใช้หลาย [Peer] ที่มี AllowedIPs ต่างกันร่วมกับหลาย TCPServerTunnel
  • มีตัวอย่าง UDPProxyTunnel รวมอยู่ด้วย
    • ใช้ BindAddress เพื่อระบุที่อยู่ bind บนโลคัล
    • ใช้ Target เพื่อระบุที่อยู่ปลายทาง
    • หาก InactivityTimeout เป็น 0 จะไม่มีการ timeout
  • [Resolve] ใช้ตั้งค่ากลยุทธ์การ resolve DNS
    • ipv4: ให้ความสำคัญกับ A record
    • ipv6: ให้ความสำคัญกับ AAAA record
    • auto: เป็นค่าเริ่มต้น และจะเหมือน ipv4 หากอินเทอร์เฟซ WireGuard มีเพียงที่อยู่ IPv4 มิฉะนั้นจะเหมือน ipv6
  • สามารถอนุญาตให้ peer เชื่อมต่อเข้าหา wireproxy ได้ด้วยการตั้งค่า [Peer] ที่ไม่มี Endpoint

Health endpoint

  • --info/-i รับที่อยู่และพอร์ต เช่น localhost:9080 แล้วเปิด HTTP server ที่ให้ metric ของ health status
  • ตอนนี้มีการติดตั้ง endpoint อยู่ 2 รายการ
    • /metrics: แสดงข้อมูลของ WireGuard daemon และให้ข้อมูลแบบเดียวกับ wg show
    • /readyz: ส่งคืนเวลาเป็น JSON ของการได้รับ pong ครั้งล่าสุดจาก IP ที่ระบุใน CheckAlive
  • หากตั้งค่า CheckAlive ไว้ จะส่ง ping ไปยังที่อยู่ที่กำหนดผ่าน WireGuard ทุก ๆ CheckAliveInterval วินาที
    • ค่าเริ่มต้นของ CheckAliveInterval คือ 5 วินาที
    • หากไม่ได้รับ pong ภายในช่วงเวลาของ CheckAliveInterval ล่าสุดบวกเผื่อความหน่วงอีก 2 วินาที จะส่งคืน 503
    • หากตรงตามเงื่อนไข จะส่งคืน 200
  • หากไม่ได้ตั้งค่า CheckAlive ไว้ /readyz จะส่งคืนอ็อบเจ็กต์ JSON ว่างและ 200
  • peer ที่ได้รับการกำหนดเส้นทางสำหรับแพ็กเก็ต ICMP ping จะขึ้นอยู่กับการตั้งค่า AllowedIPs ของแต่ละ peer

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

 
GN⁺ 2024-04-03
ความคิดเห็นจาก Hacker News
  • เป็นเครื่องมือเล็ก ๆ แต่ยอดเยี่ยม ผมใช้ร่วมกับ multi-account containers ของ Firefox เพื่อเลือกพร็อกซีเฉพาะบางแท็บไปยังเราเตอร์ที่บ้าน ซึ่งรองรับ WireGuard แต่ไม่มีพร็อกซีระดับแอปพลิเคชันหรือ SSH

    • เพิ่งรู้ว่า multi-account containers รองรับ การตั้งค่าพร็อกซีแยกตามคอนเทนเนอร์
      นึกว่าถ้าจะตั้งค่านี้ต้องใช้ส่วนขยายแยกอย่าง https://addons.mozilla.org/en-GB/firefox/addon/container-pro... แต่ไม่ใช่ และดูเหมือนว่าตอนนี้แม้แต่ความเข้าใจผิดแบบนี้ก็เป็นเหตุผลให้ถูก downvote ได้แล้ว
    • อยากรู้ว่ามีแหล่งข้อมูลดี ๆ ที่อธิบายวิธีตั้งค่าคอนฟิกแบบนี้ไหม
  • สำหรับงานที่ตั้งใจจะทำด้วย WireGuard นั้น https://github.com/dariost/soks เหมาะกว่ามาก ทำงานแทบจะเหมือนกัน แต่ใช้ อินเทอร์เฟซ WireGuard ที่มีอยู่แล้วซ้ำ
    วิธีใช้งานเขียนไว้ละเอียดในบทความนี้: https://www.nicoco.fr/blog/2023/09/10/wireguard/

    • อันนี้ค่อนข้างต่างกัน wireproxy ดูเหมือนจะมี การใช้งาน TCP และ WireGuard อยู่ใน user space ส่วน soks ใกล้เคียงกับ IP router ที่จัดการได้แค่ TCP
      ดูเหมือนเป็นการตัดสินใจว่าจะใช้ SOCKS5 proxy หรือไม่ แทนที่จะใช้ตาราง routing เป็นกลไกควบคุม
    • อยากรู้ว่าทำไมฝั่งนั้นถึงเหมาะกว่ามาก
      เมื่อก่อนเคยทำอะไรคล้ายกันด้วย Docker container บน Raspberry Pi แต่โซลูชันใน user space ดูเป็นตัวเลือกที่ดีกว่ามาก เพราะรับประกันได้ว่ารันได้บนทุกระบบปฏิบัติการ และจะไม่เผลอทำตาราง routing ของโฮสต์พัง
  • มี onetun ด้วย: https://github.com/aramperes/onetun

  • สงสัยว่ามี การใช้งานฝั่งเซิร์ฟเวอร์ที่อยู่ใน user space ทั้งหมด ด้วยไหม ถ้าจะทำโดยไม่มีอุปกรณ์ tun/tap ก็คงต้องมี IP stack ใน user space อะไรทำนองนั้น แต่ก็ไม่แน่ใจ

    • https://github.com/noisysockets/noisysockets
      ใน Go สามารถแทนที่ Dialer ที่ใช้เชื่อมต่อ socket ได้ ซึ่งเท่ากับว่าสามารถห่อ socket ด้วย WireGuard ได้โดยตรง ทำงานใน user space จึงไม่ต้องใช้ tun/tap ทั้งหมดนี้ @dpeckett เปิดซอร์สไว้
      ยังสร้าง WireGuard gateway ใน user space ที่รวมการ resolve DNS ไว้ด้วยบนฐานเดียวกัน: https://github.com/noisysockets/gateway
      https://news.ycombinator.com/user?id=dpeckett
    • มันทำงานใน user space ทั้งหมดจริง ๆ และไม่ต้องใช้ทั้ง kernel module หรือแม้แต่ สิทธิ์ผู้ดูแลระบบสำหรับจัดการอุปกรณ์ TUN/TAP แบบโหมด TUN device ของ OpenSSH
      ตามที่ผมเข้าใจ มันใช้ TCP/IP stack แบบ user space ของ Google
    • อาจเป็น https://github.com/cloudflare/boringtun หรือ https://github.com/WireGuard/wireguard-go ก็ได้
  • น่าจะเหมาะไว้แทน SSH tunnel ที่เคยใช้เวลาต้องการ IP อื่น
    มีเครื่องมือที่เกี่ยวข้องชื่อ pproxy ด้วย ซึ่งหนึ่งในหลายฟีเจอร์คือสามารถ “แปลง” โปรโตคอล tunnel ต่าง ๆ ระหว่างกันได้ และมีฟังก์ชัน routing ด้วย เคยใช้แปลง SSH SOCKS5 เป็น HTTP proxy: https://github.com/moreati/pproxy

  • ตอนแรกคิดว่า “ของแบบนี้น่าจะทำด้วย Go ได้ค่อนข้างง่ายนะ?” แล้วก็เป็นไปตามนั้น มัน เขียนด้วย Go จริง ๆ

  • มี ไคลเอนต์พร็อกซีแบบหลายโปรโตคอล หลายตัวที่รองรับฟีเจอร์นี้ ตัวอย่างโอเพนซอร์สที่เด่น ๆ ได้แก่ sing-box, clash-meta และไคลเอนต์อื่น ๆ ที่อิง clash, xray
    ส่วนไคลเอนต์ซอร์สปิดมี Surge Mac/iOS

    • ใช่เลย พร็อกซีหลายโปรโตคอลพวกนี้น่าจะถูกสร้างขึ้นเพื่อ หลบเลี่ยงไฟร์วอลล์จีน และเป็น ecosystem เล็ก ๆ ที่น่าสนใจ
      มีความสามารถด้าน traffic routing หลายอย่างที่ไม่ค่อยเป็นที่รู้จัก และมี implementation บน Android ด้วย เมื่อก่อนเคยลองใช้เพื่อเปิด hotspot บน Android ที่ไม่ได้ root กับ SIM ที่ไม่รองรับ hotspot
      แต่ก็มีโค้ดจำนวนมากที่หยิบมาจากทั่วอินเทอร์เน็ต และชุมชนนักพัฒนาก็ค่อนข้างแปลกด้วยหลายเหตุผล เลยสงสัยอยู่เสมอว่าจะเชื่อถือได้แค่ไหน
    • ฝั่งซอร์สปิด Cloudflare WARP ก็ทำงานในโหมด proxy ได้เช่นกัน ถ้าแปลงการตั้งค่า WARP ให้เป็นการตั้งค่า WireGuard ทั่วไป บัญชีฟรีก็ใช้แบบนี้ได้
    • ในจีน สิ่งที่ดูเหมือนทำงานได้เสถียรแทบจะมีแค่ clash + v2ray เท่านั้น ผู้ให้บริการ VPN รายใหญ่ส่วนใหญ่บอกว่าใช้ได้ในจีน แต่ในความเป็นจริงใช้ไม่ได้
      ยังไม่ได้เจาะลึกว่ามันทำงานอย่างไร แต่ชอบแนวคิดเรื่องการใช้ rule group ตัดสินใจว่าโดเมนไหนควรพร็อกซีผ่าน VPN
  • อยากรู้เรื่องประสิทธิภาพ เท่าที่จำได้ SOCKS แบบ “vanilla” ตั้งค่าง่ายมาก คือแค่รัน SSH ด้วย option ที่เหมาะสม แล้วบอกแอปพลิเคชันให้ใช้ แต่ค่อนข้างช้า
    เครื่องมือนี้ดูเหมือนทำมาใช้ในกรณีที่ไม่มีเซิร์ฟเวอร์ SOCKS/SSH ปกติ แต่ก็อยากรู้ว่าฝั่งนั้นมีข้อดีด้วยไหม

    • สงสัยว่า SOCKS แบบ “vanilla” หมายถึงอะไร ไม่รู้ว่ากำลังเทียบกับ implementation ของ SOCKS แบบไหน
      ในกรณีของผม SOCKS บน SSH ทำประสิทธิภาพได้ค่อนข้างดีเสมอ และไม่เหมือนวิธีที่เอา TCP ซ้อนบน TCP แบบโหมด TUN ของ OpenSSH
    • น่าลองเทียบสองแบบนี้ ตอนนี้เชื่อมต่อ WireGuard แล้วสร้าง SOCKS proxy ด้วย SSH อยู่ ซึ่งทำงานได้ดีอย่างน่าประหลาดใจ
      ถึงอย่างนั้นก็สนใจโซลูชันนี้มาก
  • กำลังคิดพอดีว่าอยากมีเครื่องมือที่พร็อกซีการเชื่อมต่ออีเมลทั้งหมดของ Thunderbird ผ่าน Tailscale exit node โดยไม่ต้องส่งทราฟฟิกทั้งหมดไปยัง exit node

    • สามารถใช้ tailscale CLI เป็น SOCKS proxy ได้: https://tailscale.com/kb/1113/aws-lambda
      ใส่มันไว้ใน container image แล้วเปิดเผย SOCKS port ที่ tailscale listen อยู่ ก็จะกลายเป็นพร็อกซีได้ทันที
    • จะติดตั้ง 3proxy หรือ squid proxy บนเครื่องที่รัน exit node อยู่ก็ได้ เครื่องทั้งหมดใน tailnet จะมองเห็นมันได้
  • ถ้าต้องการสิ่งนี้สำหรับ Mullvad VPN โดยเฉพาะ ผมลองใช้ https://github.com/imiric/mullvad-proxy แล้วดี
    ไม่ใช่โปรเจกต์ของผม แค่ fork ไว้สำหรับอัปเดตเท่านั้น ข้อดีคือมันฝังเครื่องมือ Mullvad CLI มาให้ ทำให้สลับเซิร์ฟเวอร์ได้ง่ายมาก และทุกอย่างถูกแยกออกจากเครื่องโฮสต์ นอกจากนี้มันก็ “แค่” nginx กับสคริปต์บางส่วน ดังนั้นการรองรับ SOCKS5 ก็น่าจะโอเค

    • จาก Mullvad สามารถดาวน์โหลด การตั้งค่า “all” แล้วนำไปใช้กับ WireGuard ปกติได้ จากนั้นตำแหน่งทั้งหมดของ Mullvad จะปรากฏเป็น dropdown ขนาดใหญ่ใน WireGuard
      https://mullvad.net/en/blog/wireguard-configuration-tool-has...