Git Product home page Git Product logo

wsproxy's Introduction

wsproxy

Wsproxy是一个将websocket转成tcp的代理,用了此代理之后,可以直接用原来的tcp服务器,然后客户端用websocket进行通信。

WSproxy v2.3.1 beta
- 2023-06-30 [优化]增加 X-Forwarded-For 头部,用于后端获取真实IP
- 2023-03-24 [新增]支持proxy protocol协议,以便后端服务器获取客户端真实ip
- 2023-03-17 [新增]支持 ws 后端代理协议
- 2023-03-17 优化BufferSize缓冲区,可能会导致tcp协议粘包,建议业务协议里加入包头识别
- 2023-03-13 [优化]内存分配,减轻GC压力
- 2023-03-13 [新增]支持 text/binary 转发流格式
- 2023-03-13 [新增]支持 tcp/udp 后端代理协议
- 2023-03-13 [新增]支持 max_conns 最大代理连接数
- 高并发性能,资源消耗低
- 网关支持前端ws、wss服务协议
- 使用aes加密算法,后端ip地址不直接对外
- 没有多余的配置,可作为全局代理网关

PS: 开启proxy protocol协议,需要后端服务器支持获取PP协议报文,可阅读 https://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt

性能测试

PS: CPU E5-2699 v3 2.30GHz、8核、16G (仅开4个核)。 保守支持 1W并发连接,20W pps。

编译:

开发环境:

go version go1.20 linux/amd64
Intel(R) E5-2699 v3 2.30GHz /8核/16G
#进入主目录
git clone https://github.com/ywjt/wsproxy.git
cd wsproxy

export PATH=$PATH:/usr/local/go/bin:`pwd`
export GOPATH=`pwd`
go env -w GO111MODULE=auto
go get -u golang.org/x/sys/unix

cd wsproxy
go build .  #可能还需要安装必须的依赖

用法:

usage: ./wsproxy -addr 0.0.0.0:1443 -secret test1234

制作Docker镜像:

将当前目录下编译好的二进制文件,复制到 bin文件夹,并编写Dockerfile 进行打包。

mv wsproxy ../bin/
cd ../bin/

cat >Dockerfile <<EOF
FROM busybox
WORKDIR /
COPY wsproxy /

EXPOSE 1443
LABEL org.opencontainers.image.authors="YWJT"
LABEL org.opencontainers.image.version="2.3.1-beta"

ENTRYPOINT ["./wsproxy"]
CMD ["-h"]
EOF

docker build -t wsproxy:2.3.1 .

启动容器:

docker run --name wsproxy -d -p 1443:1443 wsproxy:2.3.1 -secret test1234
docker ps -a|grep wsproxy

可用参数:

[root@~ ]# ./wsproxy -h

Usage of ./wsproxy:
  -addr string
        Network address for gateway (default "0.0.0.0:1443")
  -aes_only
        Run WSproxy on encryption mode for AES
  -buffer uint
        Buffer size for ReadBuffer()/WriteBuffer() (default 1024)
  -frkey string
        Key name for URL request. like '/?token=xeR7LpmprJS8U...'
        (Exp: -frkey token or -frkey token123) Fmt: ^[a-z]+[0-9]*  (default "token")
  -fsplit string
        Split token from formValue, like '?t=xeR7LpmprJS8U...?v=4693225'
        (Exp: -fsplit "?v=",0 )  Res: 'xeR7LpmprJS8U...' 
  -max_conns uint
        Max connections to slots available. (default 65536)
  -secret string
        The passphrase used to decrypt target server address
  -ssl_cert string
        SSL certificate file (default "./cert.pem")
  -ssl_key string
        SSL key file (if separate from cert) (default "./key.pem")
  -ssl_only
        Run WSproxy for TLS version
  -stream string
        Buffer stream format for (text, bin). Only TCP/UDP backend.
        (Exp: -stream bin or -stream text ) (default "bin")
  -timeout uint
        Timeout seconds when dial to targer server (default 3)
  -version
        Print WSproxy version

加密:

客户端发送到网关的目标服务器地址使用AES256-CBC加密并进行base64编码。

示例:

U2FsdGVkX19KIJ9OQJKT/yHGMrS+5SsBAAjetomptQ0=

进行加密目的是为了隐藏后端服务IP地址和端口,保证较高的安全性。而网关是可以作为全局代理,所有业务均可无缝使用。

使用AES算法加密文本格式的后端地址,生成base64编码的密文。可以在线生成:http://tool.oschina.net/encrypt

也可以使用openssl命令生成,如:

echo -n "127.0.0.1:8088" | openssl enc -e -aes-256-cbc -a -salt -k "test1234"

举例,当后端地址为127.0.0.1:8088并且Secret为 testr1234 时,密文结果应类似:

U2FsdGVkX1+G76LHp6mvNpyMSqR1WoGGTcSLIyD+/7A=

注:上述方式都会使用随机Salt,这也是建议的方式。其结果是每次加密得出的密文结果并不一样,但并不会影响解密。

请求方法

加密方式:

ws://your-domain:1443/?token=U2FsdGVkX1+G76LHp6mvNpyMSqR1WoGGTcSLIyD+/7A=
ws://your-domain:1443/ws?token=U2FsdGVkX1+G76LHp6mvNpyMSqR1WoGGTcSLIyD+/7A=

支持开启TLS:

wss://your-domain:1443/?token=U2FsdGVkX1+G76LHp6mvNpyMSqR1WoGGTcSLIyD+/7A=
wss://your-domain:1443/ws?token=U2FsdGVkX1+G76LHp6mvNpyMSqR1WoGGTcSLIyD+/7A=

非加密方式:

ws://your-domain:1443/?token=127.0.0.1:80
wss://your-domain:1443/?token=127.0.0.1:80
ws://your-domain:1443/ws?token=127.0.0.1:80
wss://your-domain:1443/ws?token=127.0.0.1:80

备注:强烈建议正式上线时务必使用 强制加密方式。

按代理协议请求

网关能复用代理端口进行不同后端协议的转换。

请求URL 后端协议 说明
/?token= TCP 从网关WS/WSS --> 后端TCP (必须是tcp协议)
/udp?token= UDP 从网关WS/WSS --> 后端UDP (未测试)
/ws?token= WS 从网关WS/WSS --> 后端WS (必须是ws协议)

*注意必须匹配好对应的后端协议,否则代理不成功。

wsproxy's People

Contributors

sunshinekoo avatar

Stargazers

 avatar allanche avatar  avatar  avatar  avatar  avatar

wsproxy's Issues

切换成其他的wss to tcp 工具不报错

2023-09-11 20:41:10 [Notice] read tcp 10.0.6.237:5611->183.6.114.136:2285: use of closed network connection, User-Id:2294372889
2023-09-11 20:41:39 [Info] 144.682?s 183.6.114.136 "net:10.0.6.237:46663->10.0.6.237:5002" "GET /?token=10.0.6.237:5002 HTTP/1.1" 200 "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.33(0x18002129) NetType/WIFI Language/zh_CN" - - "User-Id:2115424079"
2023-09-11 20:41:39 [Error] [Ws -> Sock] websocket read error: websocket: close 1006 (abnormal closure): unexpected EOF, User-Id:2115424079
2023-09-11 20:42:04 [Notice] websocket: close 1000 (normal): interrupted, User-Id:1484134660
2023-09-11 20:44:35 [Info] 143.869?s 183.6.114.136 "net:10.0.6.237:46671->10.0.6.237:5002" "GET /?token=10.0.6.237:5002 HTTP/1.1" 200 "Mozilla/5.0 (Linux; Android 13; 22011211C Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/5261 MMWEBSDK/20230701 MMWEBID/4941 MicroMessenger/8.0.40.2420(0x28002858) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android" - - "User-Id:2242585962"
2023-09-11 20:44:40 [Notice] websocket: close 1000 (normal): destory wcwss, User-Id:2242585962
2023-09-11 20:44:57 [Info] 147.813?s 183.6.114.136 "net:10.0.6.237:46673->10.0.6.237:5002" "GET /?token=10.0.6.237:5002 HTTP/1.1" 200 "Mozilla/5.0 (Linux; Android 13; 22011211C Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/5261 MMWEBSDK/20230701 MMWEBID/4941 MicroMessenger/8.0.40.2420(0x28002858) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android" - - "User-Id:2783717998"
2023-09-11 20:47:13 [Notice] websocket: close 1000 (normal): interrupted, User-Id:2783717998

转ws收发正常,转tcp能发不能收

import socket

def tcp_server(host, port):
# 创建一个TCP套接字
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
# 绑定到指定的主机和端口
server_socket.bind((host, port))
# 开始监听传入的连接
server_socket.listen()
print(f"Server listening on {host}:{port}")

    while True:
        # 接受连接
        client_socket, client_address = server_socket.accept()
        print(f"Connection from {client_address}")
        
        with client_socket:
            while True:
                # 接收客户端发送的数据
                data = client_socket.recv(1024)
                if not data:
                    break
                print(f"Received: {data.decode()}")
                
                # 回复相同的数据
                client_socket.sendall(data)
                print("Sent: ", data.decode())
                
        print(f"Connection with {client_address} closed")

if name == "main":
HOST = '127.0.0.1' # 服务器主机
PORT = 12345 # 服务器端口
tcp_server(HOST, PORT)

使用上述简单的tcp服务器进行测试,连接正常,发送正常,但是收不到数据。
测试工具:http://wstool.js.org/
测试地址:ws://10.15.101.99:1443?token=127.0.0.1:12345

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.