Classic Proxy Client

Objectives

  1. Build a Shadowsocks Client with a SOCKS5 inbound, akin to the classic Shadowsocks client.
  2. Focus on TCP only.

Plugins

┌──────────┐ ┌───────────────┐ ┌──────────────┐ ┌───────────┐ │ │ │ │ │ │ │ │ │ listener │ tcp │ socks5-server │ tcp │ main-forward │ tcp │ ss-client │ │ ├────►│ ├────►│ ├────►│ │ └──────────┘ └───────────────┘ └──────────────┘ └────┬──────┘ │ ┌──────────────┐ │ │ │ │ │ sys-resolver │ │ tcp │ │ │ └───▲──────────┘ │ │ resolver │ ┌─┴──────────┐ ┌──────▼──────┐ │ │ │ │ │ phy-socket │ tcp │ proxy-redir │ │ │◄────┤ │ └────────────┘ └─────────────┘
{ "tcp_listen": ["127.0.0.1:1080"], "udp_listen": [], "tcp_next": "socks5-server.tcp", "udp_next": "reject.udp" }
{ "tcp_next": "main-forward.tcp", "udp_next": "reject.udp" }
{ "tcp_next": "ss-client.tcp", "udp_next": "null.udp" }
{ "method": "aes-128-gcm", "password": { "__byte_repr": "utf8", "data": "my_ss_password" }, "tcp_next": "proxy-redir.tcp", "udp_next": "null.udp" }
{ "dest": { "host": "my.proxy.server.com.", "port": 8388 }, "tcp_next": "phy-socket", "udp_next": "null.udp" }
{ "resolver": "sys-resolver.resolver" }
null
null
null

Explanation

  1. listener binds to a local host endpoint and listens for incoming connections.
  2. For each incoming connection, socks5-server performs a SOCKS5 handshake and obtains a destination address from the SOCKS5 request, say google.com:443.
  3. main-forward initiates a new connection with ss-client.
  4. Since ss-client has encoded the destination address into the Shadowsocks protocol, proxy-redir will redirect the connection to the proxy address (my.proxy.server.com.:8388). Otherwise, encrypted Shadowsocks payload will be sent directly to google.com:443, which is not expected.
  5. phy-socket resolves the IP address of my.proxy.server.com. using a system-resolver.
  6. The Shadowsocks server at my.proxy.server.com.:8388 receives the request and starts relay between google.com:443 and your PC.

Revision History

  • 2023-04-29: Removed phy.
  • 2024-04-05: Fixed reference to resolve-dest in proxy-redir.