mirror of https://github.com/Dreamacro/clash.git
Feature: support vmess 'zero' security (#2513)
This commit is contained in:
parent
58732ee8b1
commit
81b1e9f931
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 10002,
|
||||
"listen": "0.0.0.0",
|
||||
"protocol": "vmess",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "b831381d-6324-4d53-ad4f-8cda48b30811",
|
||||
"alterId": 0,
|
||||
"security": "zero"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "ws",
|
||||
"security": "tls",
|
||||
"tlsSettings": {
|
||||
"certificates": [
|
||||
{
|
||||
"certificateFile": "/etc/ssl/v2ray/fullchain.pem",
|
||||
"keyFile": "/etc/ssl/v2ray/privkey.pem"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -18,6 +18,8 @@ func TestClash_Vmess(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -49,6 +51,8 @@ func TestClash_VmessTLS(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -86,6 +90,8 @@ func TestClash_VmessHTTP2(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -128,6 +134,8 @@ func TestClash_VmessHTTP(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -178,6 +186,8 @@ func TestClash_VmessWebsocket(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -211,6 +221,8 @@ func TestClash_VmessWebsocketTLS(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -221,7 +233,7 @@ func TestClash_VmessWebsocketTLS(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
id, err := startContainer(cfg, hostCfg, "vmess-ws")
|
||||
id, err := startContainer(cfg, hostCfg, "vmess-ws-tls")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
cleanContainer(id)
|
||||
|
@ -244,10 +256,51 @@ func TestClash_VmessWebsocketTLS(t *testing.T) {
|
|||
testSuit(t, proxy)
|
||||
}
|
||||
|
||||
func TestClash_VmessWebsocketTLSZero(t *testing.T) {
|
||||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
Binds: []string{
|
||||
fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-ws-tls-zero.json")),
|
||||
fmt.Sprintf("%s:/etc/ssl/v2ray/fullchain.pem", C.Path.Resolve("example.org.pem")),
|
||||
fmt.Sprintf("%s:/etc/ssl/v2ray/privkey.pem", C.Path.Resolve("example.org-key.pem")),
|
||||
},
|
||||
}
|
||||
|
||||
id, err := startContainer(cfg, hostCfg, "vmess-ws-tls-zero")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
cleanContainer(id)
|
||||
})
|
||||
|
||||
proxy, err := outbound.NewVmess(outbound.VmessOption{
|
||||
Name: "vmess",
|
||||
Server: localIP.String(),
|
||||
Port: 10002,
|
||||
UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
|
||||
Cipher: "zero",
|
||||
Network: "ws",
|
||||
TLS: true,
|
||||
SkipCertVerify: true,
|
||||
UDP: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(waitTime)
|
||||
testSuit(t, proxy)
|
||||
}
|
||||
|
||||
func TestClash_VmessGrpc(t *testing.T) {
|
||||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -289,6 +342,8 @@ func TestClash_VmessWebsocket0RTT(t *testing.T) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
@ -366,6 +421,8 @@ func Benchmark_Vmess(b *testing.B) {
|
|||
cfg := &container.Config{
|
||||
Image: ImageVmess,
|
||||
ExposedPorts: defaultExposedPorts,
|
||||
Entrypoint: []string{"/usr/bin/v2ray"},
|
||||
Cmd: []string{"run", "-c", "/etc/v2ray/config.json"},
|
||||
}
|
||||
hostCfg := &container.HostConfig{
|
||||
PortBindings: defaultPortBindings,
|
||||
|
|
|
@ -35,6 +35,7 @@ type Conn struct {
|
|||
respBodyKey []byte
|
||||
respV byte
|
||||
security byte
|
||||
option byte
|
||||
isAead bool
|
||||
|
||||
received bool
|
||||
|
@ -74,7 +75,7 @@ func (vc *Conn) sendRequest() error {
|
|||
buf.Write(vc.reqBodyIV[:])
|
||||
buf.Write(vc.reqBodyKey[:])
|
||||
buf.WriteByte(vc.respV)
|
||||
buf.WriteByte(OptionChunkStream)
|
||||
buf.WriteByte(vc.option)
|
||||
|
||||
p := rand.Intn(16)
|
||||
// P Sec Reserve Cmd
|
||||
|
@ -206,6 +207,7 @@ func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool
|
|||
copy(reqBodyIV[:], randBytes[:16])
|
||||
copy(reqBodyKey[:], randBytes[16:32])
|
||||
respV := randBytes[32]
|
||||
option := OptionChunkStream
|
||||
|
||||
var (
|
||||
respBodyKey []byte
|
||||
|
@ -227,6 +229,16 @@ func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool
|
|||
var writer io.Writer
|
||||
var reader io.Reader
|
||||
switch security {
|
||||
case SecurityZero:
|
||||
security = SecurityNone
|
||||
if !dst.UDP {
|
||||
reader = conn
|
||||
writer = conn
|
||||
option = 0
|
||||
} else {
|
||||
reader = newChunkReader(conn)
|
||||
writer = newChunkWriter(conn)
|
||||
}
|
||||
case SecurityNone:
|
||||
reader = newChunkReader(conn)
|
||||
writer = newChunkWriter(conn)
|
||||
|
@ -267,6 +279,7 @@ func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool
|
|||
reader: reader,
|
||||
writer: writer,
|
||||
security: security,
|
||||
option: option,
|
||||
isAead: isAead,
|
||||
}
|
||||
if err := c.sendRequest(); err != nil {
|
||||
|
|
|
@ -26,15 +26,9 @@ const (
|
|||
SecurityAES128GCM Security = 3
|
||||
SecurityCHACHA20POLY1305 Security = 4
|
||||
SecurityNone Security = 5
|
||||
SecurityZero Security = 6
|
||||
)
|
||||
|
||||
// CipherMapping return
|
||||
var CipherMapping = map[string]byte{
|
||||
"none": SecurityNone,
|
||||
"aes-128-gcm": SecurityAES128GCM,
|
||||
"chacha20-poly1305": SecurityCHACHA20POLY1305,
|
||||
}
|
||||
|
||||
// Command types
|
||||
const (
|
||||
CommandTCP byte = 1
|
||||
|
@ -95,6 +89,8 @@ func NewClient(config Config) (*Client, error) {
|
|||
security = SecurityCHACHA20POLY1305
|
||||
case "none":
|
||||
security = SecurityNone
|
||||
case "zero":
|
||||
security = SecurityZero
|
||||
case "auto":
|
||||
security = SecurityCHACHA20POLY1305
|
||||
if runtime.GOARCH == "amd64" || runtime.GOARCH == "s390x" || runtime.GOARCH == "arm64" {
|
||||
|
|
Loading…
Reference in New Issue