Zvpn

module
v0.0.0-...-b48972f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 18, 2021 License: Apache-2.0

README

Zvpn

假设有有一道防火墙阻挡了你和目的主机之间的网络连接,而存在另一台你能够访问的代理服务器A,A和目的主机之间能建立正常的网络连接,那么你就可以使用Zvpn来构建client和server分别部署在你的电脑和代理服务器上来实现流量的转发,让你能正常的访问目的主机。

其中一种情况,代理服务器在墙外

在这种情况下,我们再假设这个防火墙会审查通过的流量,阻隔所有带有目的主机地址特征的数据包,为了突破防火墙,我们希望使用私有的传输、代理和加密协议。

为了减少重复的代码,Zvpn解耦出了三个模块,分别是可靠传输协议、代理协议和私有协议,分别对应Protocol、Proxy和Obfuscate三个interface

type Conn interface {
	Write(buf []byte) (l int, err error)
	Read(buf []byte) (l int, err error)
	Close() error
}

type Listener interface {
	Accept() (Conn, error)
	Close() error
}

type Protocol interface {
	Bind(string) (Listener, error)
	Dial(string) (Conn, error)
}
type Proxy interface {
	// return the Conn ready to forward data
	// 本地连接: 浏览器->本地服务器
	// 远程连接: 本地服务器->远程服务器
	// 传入一个本地连接和远程连接,返回一个完成代理握手的远程连接
	// 如果本地和远程的代理协议一样,那么直接return remote即可
	ClientHandshake(local, remote protocol.Conn, p protocol.Protocol) (protocol.Conn, error)
	// take a established Conn between client and server as argument
	// return the established Conn which is the client want to established
	// 传入一个已经完成可靠网络协议握手的conn,在这个conn上进行
	// 代理协议握手,并且返回一个按客户端要求在服务端上建立的连接
	ServerHandshake(protocol.Conn, protocol.Protocol) (protocol.Conn, error)
}
type Obfuscate interface {
    // take a established conn between client and server as argument
	// 传入一个已经握手完毕的基于可靠传输协议的连接
	// 你可以在上面利用非对称加密交换密秘钥或者直接
	// 使用本地配置文件中的密钥
	ClientHandShake(protocol.Conn) (Encrypter, Decrypter, error)
	ServerHandShake(protocol.Conn) (Encrypter, Decrypter, error)
}

type Encrypter interface {
	Write(conn protocol.Conn, src []byte) (int, error)
}

type Decrypter interface {
	Read(conn protocol.Conn, dst []byte) (int, error)
}

你只需要自己实现这三个interface,并传入NewWallerCrosser中便可创建一个vpn实例。当然你也可以使用几个已经完成了的实现,Protocol可用的有TCP;Proxy可用的有Socks5;Obfuscate可用的有AES、RC4,加密协议均需要预先将秘钥储存在client和server本地。

import (
	"github.com/ZerQAQ/Zvpn/obfus"
	"github.com/ZerQAQ/Zvpn/protocol"
	"github.com/ZerQAQ/Zvpn/proxy"
	"github.com/ZerQAQ/Zvpn/Zvpn"
)

w := Zvpn.NewWallerCrosser(protocol.TCP, proxy.Sock5, obfus.NewRC4(key))

随后在本机上调用startClient方法:

w.StartClient(CliAddr, SerAddr)
// for example:
// CliAddr = 127.0.0.1:1080
// serAddr = 10.17.24.234:2080

在服务端上调用startServer方法:

w.StartServer(Addr)
// for example:
// in 10.17.24.234
// Addr = 0.0.0.0:2080

便可以在本机上通过socks5://10.17.24.234:1080代理上网了

一个简单的二进制文件封装见release分支,此分支还演示了如何封装一个来自外部的可靠传输协议KCP

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL