2 điểm bởi GN⁺ 2024-04-03 | 1 bình luận | Chia sẻ qua WhatsApp
  • Wireproxy là một trình khách WireGuard chạy hoàn toàn trong không gian người dùng, kết nối tới peer WireGuard rồi cung cấp ra máy cục bộ dưới dạng proxy SOCKS5/HTTP hoặc tunnel
  • Nhắm tới các trường hợp chỉ muốn gửi lưu lượng của một số trang web cụ thể qua peer WireGuard mà không cần thiết lập giao diện mạng mới, hoặc không muốn dùng quyền root để thay đổi cấu hình WireGuard
  • Các tính năng gồm định tuyến tĩnh TCP, proxy SOCKS5/HTTP, và proxy TLS trong suốt dựa trên TLS SNI; proxy HTTP hiện chỉ hỗ trợ CONNECT
  • Cấu hình tuân theo ý nghĩa của [Interface], [Peer] trong wg-quick, có thể nhập tệp cấu hình WireGuard hiện có bằng WGConfig hoặc định tuyến nhiều peer bằng AllowedIPs
  • Với mục đích vận hành, công cụ cung cấp health endpoint dựa trên --info/-i; có thể kiểm tra trạng thái WireGuard và tình trạng sẵn sàng dựa trên CheckAlive qua /metrics/readyz

Wireproxy làm gì

  • wireproxy là một ứng dụng chạy trong không gian người dùng, kết nối tới peer WireGuard và cung cấp proxy SOCKS5/HTTP hoặc tunnel trên máy cục bộ
  • Có thể dùng khi bạn chỉ muốn truy cập một số trang web nhất định thông qua peer WireGuard nhưng không muốn tạo giao diện mạng mới
  • Nó hoạt động hoàn toàn tách biệt với giao diện mạng và không cần quyền root để cấu hình
  • Người dùng cần mục đích sử dụng tương tự Amnezia VPN có thể dùng bản fork wireproxy-awg

Tính năng được hỗ trợ và những gì chưa có

  • Tính năng được hỗ trợ
    • Định tuyến tĩnh TCP cho client và server
    • Proxy SOCKS5/HTTP
      • HTTP hiện chỉ hỗ trợ CONNECT
    • Proxy TLS trong suốt sử dụng Server Name Indication
  • Các tính năng còn trong TODO
    • Hỗ trợ UDP cho SOCKS5
    • Định tuyến tĩnh UDP

Chạy và cài đặt

  • Cú pháp chạy cơ bản là ./wireproxy [-c path to config]
  • Các tùy chọn chính
    • -c, --config: chỉ định đường dẫn tệp cấu hình
      • Đường dẫn mặc định là /etc/wireproxy/wireproxy.conf, $HOME/.config/wireproxy.conf
    • -s, --silent: chế độ silent
    • -d, --daemon: chạy nền
    • -i, --info: chỉ định địa chỉ và cổng để công bố health status
    • -v, --version: in ra phiên bản
    • -n, --configtest: chỉ kiểm tra tính hợp lệ của tệp cấu hình
  • Có thể build bằng cách clone kho mã rồi chạy make
  • Ví dụ cài đặt dùng go install github.com/windtf/wireproxy/cmd/wireproxy@v1.1.2 hoặc @latest

Mô hình cấu hình

  • Cấu hình [Interface][Peer] có cùng ý nghĩa như trong cấu hình wg-quick
  • Address phải dùng subnet /32 với IPv4 và /128 với IPv6
  • PrivateKey cũng có thể tham chiếu từ biến môi trường
  • Nếu đã có cấu hình WireGuard sẵn, có thể nhập bằng WGConfig = <path to the wireguard config>

Cấu hình tunnel và proxy

  • TCPClientTunnel
    • Chuyển tiếp lưu lượng TCP nhận trên máy cục bộ tới đích được chỉ định qua WireGuard
    • Luồng ví dụ là <ứng dụng LAN> → localhost:25565 → WireGuard → play.cubecraft.net:25565
  • TCPServerTunnel
    • Chuyển tiếp lưu lượng TCP nhận từ mạng WireGuard tới đích được chỉ định trong mạng cục bộ
    • Luồng ví dụ là <ứng dụng mạng WireGuard> → WireGuard → 172.16.31.2:3422 → localhost:25545
  • STDIOTunnel
    • Kết nối đầu vào và đầu ra chuẩn của tiến trình wireproxy tới đích TCP qua WireGuard
    • Hữu ích khi dùng với tham số ProxyCommand của openssh
  • Socks5
    • Tạo proxy SOCKS5 trên LAN cục bộ và định tuyến toàn bộ lưu lượng qua WireGuard
    • Nếu chỉ định tên người dùng và mật khẩu thì sẽ bật xác thực proxy
  • http
    • Tạo proxy HTTP trên LAN cục bộ và định tuyến toàn bộ lưu lượng qua WireGuard
    • Nếu chỉ định tên người dùng và mật khẩu thì sẽ bật xác thực
    • Nếu chỉ định CertFileKeyFile thì sẽ bật HTTPS
  • SNI
    • Tạo proxy TLS trong suốt trên LAN cục bộ, dùng SNI làm đích định tuyến để gửi lưu lượng qua WireGuard

Nhiều peer và định tuyến

  • Có thể dùng nhiều peer WireGuard
  • Khi dùng nhiều peer, cần chỉ định AllowedIPs để wireproxy biết phải chuyển tiếp qua peer nào
  • Ví dụ cấu hình sử dụng nhiều [Peer] với AllowedIPs khác nhau cùng nhiều TCPServerTunnel
  • Cũng có ví dụ về UDPProxyTunnel
    • BindAddress dùng để chỉ định địa chỉ bind cục bộ
    • Target dùng để chỉ định địa chỉ đích
    • Nếu InactivityTimeout0 thì sẽ không timeout
  • [Resolve] dùng để thiết lập chiến lược phân giải DNS
    • ipv4: ưu tiên bản ghi A
    • ipv6: ưu tiên bản ghi AAAA
    • auto: mặc định; nếu giao diện WireGuard chỉ có địa chỉ IPv4 thì giống ipv4, ngược lại thì giống ipv6
  • Có thể cho phép peer kết nối vào wireproxy bằng cấu hình [Peer] không có Endpoint

Health endpoint

  • --info/-i nhận địa chỉ và cổng như localhost:9080 để công bố máy chủ HTTP cung cấp metric health status
  • Hiện có hai endpoint đã được triển khai
    • /metrics: công bố thông tin daemon WireGuard, cung cấp thông tin tương tự wg show
    • /readyz: trả về thời điểm cuối cùng nhận được pong từ IP chỉ định trong CheckAlive dưới dạng JSON
  • Nếu CheckAlive được cấu hình, công cụ sẽ gửi ping qua WireGuard tới địa chỉ được chỉ định mỗi CheckAliveInterval giây
    • CheckAliveInterval mặc định là 5 giây
    • Nếu không nhận được pong trong khoảng thời gian bằng CheckAliveInterval gần nhất cộng thêm 2 giây dung sai độ trễ thì sẽ trả về 503
    • Nếu thỏa điều kiện thì sẽ trả về 200
  • Nếu CheckAlive không được cấu hình thì /readyz sẽ trả về đối tượng JSON rỗng và 200
  • Peer định tuyến gói ICMP ping sẽ phụ thuộc vào cấu hình AllowedIPs của từng peer

1 bình luận

 
GN⁺ 2024-04-03
Ý kiến trên Hacker News
  • Công cụ nhỏ nhưng rất tuyệt. Tôi đang dùng nó cùng multi-account containers của Firefox để chỉ chọn một số tab nhất định rồi proxy qua bộ định tuyến gia đình có hỗ trợ WireGuard nhưng không có proxy ở tầng ứng dụng hay SSH

    • Đây là lần đầu tôi biết rằng multi-account containers hỗ trợ cấu hình proxy theo từng container
      Tôi cứ tưởng để cấu hình cái này thì cần một tiện ích mở rộng riêng như https://addons.mozilla.org/en-GB/firefox/addon/container-pro..., nhưng hóa ra không phải, và có vẻ giờ ngay cả kiểu hiểu lầm đó cũng là lý do để bị downvote
    • Nếu có tài liệu nào hay giải thích cách thiết lập kiểu cấu hình này thì tôi rất muốn xem
  • Với công việc tôi định làm bằng WireGuard thì https://github.com/dariost/soks phù hợp hơn. Nó làm gần như cùng một việc nhưng tái sử dụng giao diện WireGuard có sẵn
    Cách sử dụng được viết khá chi tiết trong bài này: https://www.nicoco.fr/blog/2023/09/10/wireguard/

    • Cái này khác khá nhiều. wireproxy có vẻ bao gồm TCP và phần triển khai WireGuard trong không gian người dùng, còn soks giống một bộ định tuyến IP hơn, chỉ có thể xử lý TCP
      Có vẻ thay vì dùng bảng định tuyến làm cơ chế điều khiển, nó quyết định có dùng proxy SOCKS5 hay không
    • Tôi tò mò vì sao bên đó lại phù hợp hơn
      Trước đây tôi từng làm tương tự bằng container Docker trên Raspberry Pi, nhưng một giải pháp không gian người dùng có vẻ là lựa chọn tốt hơn nhiều vì có thể chạy trên bất kỳ hệ điều hành nào và đảm bảo không vô tình phá hỏng bảng định tuyến của máy chủ
  • Cũng có onetun: https://github.com/aramperes/onetun

  • Tôi tự hỏi liệu có cả triển khai máy chủ hoàn toàn trong không gian người dùng hay không. Muốn làm mà không dùng thiết bị tun/tap thì có lẽ cần thứ gì đó như stack IP trong không gian người dùng, nhưng tôi không chắc

  • Có vẻ rất phù hợp để thay thế đường hầm SSH mà tôi vẫn dùng khi cần một IP khác
    Một công cụ liên quan là pproxy, trong nhiều tính năng của nó có khả năng “chuyển đổi” giữa các giao thức tunnel khác nhau và có cả tính năng định tuyến. Tôi đã dùng nó để biến SSH SOCKS5 thành proxy HTTP: https://github.com/moreati/pproxy

  • Tôi đã nghĩ “cái này chắc làm bằng Go cũng khá dễ nhỉ?”, và đúng là nó được viết bằng Go

  • Nhiều client proxy đa giao thức hỗ trợ tính năng này. Một số ví dụ mã nguồn mở tiêu biểu là sing-box, clash-meta và các client khác dựa trên clash, cùng xray
    Về phía client mã nguồn đóng thì có Surge Mac/iOS

    • Đúng vậy. Những proxy đa giao thức này có lẽ được tạo ra để vượt tường lửa Trung Quốc, và đó là một hệ sinh thái nhỏ khá thú vị
      Có rất nhiều khả năng định tuyến lưu lượng ít người biết đến, và cũng có cả triển khai trên Android. Trước đây tôi từng thử dùng chúng để bật hotspot trên SIM không hỗ trợ hotspot và Android chưa root
      Tuy vậy, trong đó có rất nhiều mã lấy từ khắp nơi trên Internet và cộng đồng nhà phát triển cũng khá đặc biệt vì nhiều lý do, nên tôi luôn băn khoăn không biết mức độ đáng tin cậy đến đâu
    • Ở phía mã nguồn đóng, Cloudflare WARP cũng có thể chạy ở chế độ proxy. Nếu chuyển cấu hình WARP sang cấu hình WireGuard thông thường thì cả tài khoản miễn phí cũng có thể dùng theo cách này
    • Ở Trung Quốc, thứ duy nhất có vẻ hoạt động ổn định gần như là clash + v2ray. Hầu hết các nhà cung cấp VPN lớn đều nói là dùng được ở Trung Quốc, nhưng thực tế thì không
      Tôi chưa đào sâu cách nó hoạt động, nhưng tôi thích ý tưởng dùng các nhóm quy tắc để quyết định tên miền nào sẽ được proxy qua VPN
  • Tôi tò mò về hiệu năng. Theo tôi nhớ thì SOCKS “thuần” rất dễ cấu hình, tức là chỉ cần chạy SSH với các tùy chọn phù hợp rồi bảo ứng dụng dùng nó, nhưng lại khá chậm
    Có vẻ công cụ này dành cho trường hợp không có máy chủ SOCKS/SSH thông thường, nhưng tôi cũng muốn biết liệu nó có lợi thế ở cả bên đó không

    • Tôi không rõ “SOCKS thuần” nghĩa là gì. Tôi không biết nó đang được dùng để đối lập với kiểu triển khai SOCKS nào khác
      Với tôi thì SOCKS qua SSH luôn cho hiệu năng khá tốt, và không giống kiểu xếp TCP chồng lên TCP như chế độ TUN của OpenSSH
    • Sẽ hay nếu có so sánh giữa hai cách. Hiện tại tôi kết nối vào WireGuard rồi dùng SSH để tạo proxy SOCKS, và ngạc nhiên là nó hoạt động rất ổn
      Dù vậy tôi vẫn rất quan tâm đến giải pháp này
  • Tôi vừa mới nghĩ giá mà có công cụ để proxy toàn bộ kết nối email của Thunderbird qua Tailscale exit node mà không phải gửi toàn bộ lưu lượng qua exit node thì tốt biết mấy

    • Có thể dùng CLI tailscale làm proxy SOCKS: https://tailscale.com/kb/1113/aws-lambda
      Chỉ cần đưa nó vào image container và expose cổng SOCKS mà tailscale lắng nghe là dùng được ngay như một proxy
    • Cũng có thể cài 3proxy hoặc squid proxy trên máy đang chạy exit node. Mọi máy trong tailnet đều có thể nhìn thấy nó
  • Nếu bạn cần kiểu này riêng cho Mullvad VPN thì tôi đã thử https://github.com/imiric/mullvad-proxy và thấy khá tốt
    Đây không phải dự án của tôi, tôi chỉ fork để cập nhật. Điểm hay là nó tích hợp sẵn công cụ CLI của Mullvad nên việc chuyển máy chủ rất dễ, và mọi thứ đều được cách ly với máy chủ. Ngoài ra nó cũng “chỉ” là nginx cùng vài script nên có lẽ hỗ trợ SOCKS5 cũng ổn