Pipy 实现 SOCKS 代理

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pipy 实现 SOCKS 代理相关的知识,希望对你有一定的参考价值。

上篇我们介绍了服务网格 osm-edge 出口网关使用的 HTTP 隧道,其处理方式与另一种代理有点类似,就是今天要介绍的 SOCKS 代理。二者的主要差别简单来说就是前者使用 HTTP CONNECT 告知代理目的地址,而后者则是通过 SOCKS 协议。值得一提的是,SOCKS 也是出口网关的可选协议之一。

SOCKS 是一种网络传输协议,是 Socket Secure 的缩写,主要用于客户端与外网服务器之间通讯的中间传递。根据 OSI 模型,SOCKS 是会话层的协议,位于表示层与传输层之间。

SOCKS 协议的最新版本是 SOCKS5,在 SOCKS4 的基础上增加了 UDP、认证 和 IPv6 的支持。因此,后面提到的 SOCKS 都是使用最广泛的 SOCKS5。

先看一下 SOCKS 代理的工作流程。

socks-proxy-process
  1. 1. 协商阶段:客户端与代理建立连接,并进行协商,包括协议版本、认证的方式等等。

  2. 2. 连接阶段:客户端告知代理要连接的目的地址和端口(SOCKS 报文),代理使用报文中的地址和端口与服务端创建连接,并将结果作为状态返回给客户端。

  3. 3. 数据传输阶段:客户端向代理发送数据,代理将数据发送到服务端;然后将服务端返回的数据返回给客户端。

Demo

socks-proxy-demo

还是使用上篇中的例子,在防火墙后有个 TCP 服务端,由于监听在 127.0.0.1:8081 还能在本地访问。同样,使用 Pipy 来模拟这个服务。

pipy()

  .listen('127.0.0.1:8081')
  .replaceData(
    () => new Data('Hi, TCP!\\n')
  )

接下来,在服务端一侧建立一个 SOCKS 代理。

socks-proxy

PipyJS 编码

我们的代理监听在 8000 端口,使用 acceptSOCKS 过滤器[1] 来处理 SOCKS 协议报文,从报文中获取目的地址和端口,然后使用该地址和端口创建到服务端的连接。

pipy(
  _host: null,
  _port: null,
)
  //socks
  .listen(8000)
  .acceptSOCKS(
    (host, port) => (
      _host = host,
      _port = port,
      true // return true to accept the session
    )
  ).to(
    $ => $.connect(
      () => `$_host:$_port`
    )
  )

测试

在主机 192.168.1.110 上运行我们的代理以及服务端,客户端 curl 运行在主机 192.168.1.11 上。使用下面的命令进行测试:

curl -x socks5://192.168.1.110:8000 telnet://127.0.0.1:8081
test-socks-proxy

引用链接

[1] acceptSOCKS 过滤器: https://flomesh.io/pipy/docs/zh/reference/api/Configuration/acceptSOCKS

以上是关于Pipy 实现 SOCKS 代理的主要内容,如果未能解决你的问题,请参考以下文章

SOCKS5代理的介绍

如何在Linux下配置socks5代理

JSch 是不是支持 SOCKS5 代理?

HTTPS over Socks5 服务器实现

socks5代理服务是啥意思 有啥做用?

使用 SSH 隧道实现端口转发SOCKS 代理