Wireproxy: ไคลเอนต์ WireGuard ที่ให้บริการผ่านพร็อกซี HTTP/SOCKS5
(github.com/pufferffish)- 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สำหรับ IPv6PrivateKeyสามารถอ้างอิงตัวแปรสภาพแวดล้อมได้- หากมีการตั้งค่า 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 DNSipv4: ให้ความสำคัญกับ A recordipv6: ให้ความสำคัญกับ AAAA recordauto: เป็นค่าเริ่มต้น และจะเหมือน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 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เป็นเครื่องมือเล็ก ๆ แต่ยอดเยี่ยม ผมใช้ร่วมกับ multi-account containers ของ Firefox เพื่อเลือกพร็อกซีเฉพาะบางแท็บไปยังเราเตอร์ที่บ้าน ซึ่งรองรับ WireGuard แต่ไม่มีพร็อกซีระดับแอปพลิเคชันหรือ SSH
นึกว่าถ้าจะตั้งค่านี้ต้องใช้ส่วนขยายแยกอย่าง 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/
ดูเหมือนเป็นการตัดสินใจว่าจะใช้ SOCKS5 proxy หรือไม่ แทนที่จะใช้ตาราง routing เป็นกลไกควบคุม
เมื่อก่อนเคยทำอะไรคล้ายกันด้วย Docker container บน Raspberry Pi แต่โซลูชันใน user space ดูเป็นตัวเลือกที่ดีกว่ามาก เพราะรับประกันได้ว่ารันได้บนทุกระบบปฏิบัติการ และจะไม่เผลอทำตาราง routing ของโฮสต์พัง
มี onetun ด้วย: https://github.com/aramperes/onetun
สงสัยว่ามี การใช้งานฝั่งเซิร์ฟเวอร์ที่อยู่ใน user space ทั้งหมด ด้วยไหม ถ้าจะทำโดยไม่มีอุปกรณ์ tun/tap ก็คงต้องมี IP stack ใน user space อะไรทำนองนั้น แต่ก็ไม่แน่ใจ
ใน 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
ตามที่ผมเข้าใจ มันใช้ TCP/IP stack แบบ user space ของ Google
น่าจะเหมาะไว้แทน 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
มีความสามารถด้าน traffic routing หลายอย่างที่ไม่ค่อยเป็นที่รู้จัก และมี implementation บน Android ด้วย เมื่อก่อนเคยลองใช้เพื่อเปิด hotspot บน Android ที่ไม่ได้ root กับ SIM ที่ไม่รองรับ hotspot
แต่ก็มีโค้ดจำนวนมากที่หยิบมาจากทั่วอินเทอร์เน็ต และชุมชนนักพัฒนาก็ค่อนข้างแปลกด้วยหลายเหตุผล เลยสงสัยอยู่เสมอว่าจะเชื่อถือได้แค่ไหน
ยังไม่ได้เจาะลึกว่ามันทำงานอย่างไร แต่ชอบแนวคิดเรื่องการใช้ rule group ตัดสินใจว่าโดเมนไหนควรพร็อกซีผ่าน VPN
อยากรู้เรื่องประสิทธิภาพ เท่าที่จำได้ SOCKS แบบ “vanilla” ตั้งค่าง่ายมาก คือแค่รัน SSH ด้วย option ที่เหมาะสม แล้วบอกแอปพลิเคชันให้ใช้ แต่ค่อนข้างช้า
เครื่องมือนี้ดูเหมือนทำมาใช้ในกรณีที่ไม่มีเซิร์ฟเวอร์ SOCKS/SSH ปกติ แต่ก็อยากรู้ว่าฝั่งนั้นมีข้อดีด้วยไหม
ในกรณีของผม SOCKS บน SSH ทำประสิทธิภาพได้ค่อนข้างดีเสมอ และไม่เหมือนวิธีที่เอา TCP ซ้อนบน TCP แบบโหมด TUN ของ OpenSSH
ถึงอย่างนั้นก็สนใจโซลูชันนี้มาก
กำลังคิดพอดีว่าอยากมีเครื่องมือที่พร็อกซีการเชื่อมต่ออีเมลทั้งหมดของ Thunderbird ผ่าน Tailscale exit node โดยไม่ต้องส่งทราฟฟิกทั้งหมดไปยัง exit node
tailscaleCLI เป็น SOCKS proxy ได้: https://tailscale.com/kb/1113/aws-lambdaใส่มันไว้ใน container image แล้วเปิดเผย SOCKS port ที่ tailscale listen อยู่ ก็จะกลายเป็นพร็อกซีได้ทันที
ถ้าต้องการสิ่งนี้สำหรับ Mullvad VPN โดยเฉพาะ ผมลองใช้ https://github.com/imiric/mullvad-proxy แล้วดี
ไม่ใช่โปรเจกต์ของผม แค่ fork ไว้สำหรับอัปเดตเท่านั้น ข้อดีคือมันฝังเครื่องมือ Mullvad CLI มาให้ ทำให้สลับเซิร์ฟเวอร์ได้ง่ายมาก และทุกอย่างถูกแยกออกจากเครื่องโฮสต์ นอกจากนี้มันก็ “แค่” nginx กับสคริปต์บางส่วน ดังนั้นการรองรับ SOCKS5 ก็น่าจะโอเค
https://mullvad.net/en/blog/wireguard-configuration-tool-has...