From 098f4fd2bfea32dcf776ce731a83d5bd239a6ec6 Mon Sep 17 00:00:00 2001 From: Yuzuki616 Date: Sat, 15 Jul 2023 19:37:44 +0800 Subject: [PATCH] add gen X25519 private key --- api/panel/node.go | 33 +++++++++++++----- cmd/x25519.go | 52 +++++++++++---------------- common/crypt/sha.go | 11 ------ common/crypt/x25519.go | 13 +++++++ conf/node.go | 14 -------- conf/old.go | 5 --- core/xray/inbound.go | 79 +++++++++++++++++------------------------- 7 files changed, 89 insertions(+), 118 deletions(-) delete mode 100644 common/crypt/sha.go create mode 100644 common/crypt/x25519.go diff --git a/api/panel/node.go b/api/panel/node.go index 7f1767f..0519a8d 100644 --- a/api/panel/node.go +++ b/api/panel/node.go @@ -1,6 +1,7 @@ package panel import ( + "encoding/base64" "fmt" "reflect" "regexp" @@ -10,7 +11,6 @@ import ( "github.com/Yuzuki616/V2bX/common/crypt" - "github.com/Yuzuki616/V2bX/conf" "github.com/goccy/go-json" ) @@ -72,10 +72,21 @@ type NodeInfo struct { } type V2rayExtraConfig struct { - EnableVless bool `json:"EnableVless"` - VlessFlow string `json:"VlessFlow"` - EnableReality bool `json:"EnableReality"` - RealityConfig conf.RealityConfig `json:"RealityConfig"` + EnableVless bool `json:"EnableVless"` + VlessFlow string `json:"VlessFlow"` + EnableReality bool `json:"EnableReality"` + RealityConfig *RealityConfig `json:"RealityConfig"` +} + +type RealityConfig struct { + Dest interface{} `yaml:"Dest" json:"Dest"` + Xver uint64 `yaml:"Xver" json:"Xver"` + ServerNames []string `yaml:"ServerNames" json:"ServerNames"` + PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"` + MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"` + MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"` + MaxTimeDiff uint64 `yaml:"MaxTimeDiff" json:"MaxTimeDiff"` + ShortIds []string `yaml:"ShortIds" json:"ShortIds"` } func (c *Client) GetNodeInfo() (node *NodeInfo, err error) { @@ -144,10 +155,14 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) { if err != nil { return nil, fmt.Errorf("decode v2ray extra error: %s", err) } - if node.ExtraConfig.RealityConfig.PrivateKey != "" { - temp := crypt.GenShaHash([]byte(c.APIHost + c.Token))[:32] - temp, err = crypt.AesDecrypt(node.ExtraConfig.RealityConfig.PrivateKey, []byte(temp)) - node.ExtraConfig.RealityConfig.PrivateKey = temp + if node.ExtraConfig.EnableReality { + if node.ExtraConfig.RealityConfig == nil { + node.ExtraConfig.EnableReality = false + } else { + key := crypt.GenX25519Private([]byte(strconv.Itoa(c.NodeId) + c.NodeType + c.Token + + node.ExtraConfig.RealityConfig.PrivateKey)) + node.ExtraConfig.RealityConfig.PrivateKey = base64.RawURLEncoding.EncodeToString(key) + } } case "shadowsocks": rsp := ShadowsocksNodeRsp{} diff --git a/cmd/x25519.go b/cmd/x25519.go index 361d4a8..d7ee9ce 100644 --- a/cmd/x25519.go +++ b/cmd/x25519.go @@ -25,19 +25,6 @@ func init() { } func executeX25519() { - var yes, key string - fmt.Println("要对私钥进行加密吗?(Y/n)") - fmt.Scan(&yes) - if strings.ToLower(yes) == "y" { - var temp string - fmt.Println("请输入Api接口地址:") - fmt.Scan(&temp) - key = temp - fmt.Println("请输入Api认证Token:") - fmt.Scan(&temp) - key += temp - key = crypt.GenShaHash([]byte(key)) - } var output string var err error defer func() { @@ -45,18 +32,28 @@ func executeX25519() { }() var privateKey []byte var publicKey []byte - privateKey = make([]byte, curve25519.ScalarSize) - if _, err = rand.Read(privateKey); err != nil { - output = Err("read rand error: ", err) - return + var yes, key string + fmt.Println("要基于节点信息生成密钥吗?(Y/n)") + fmt.Scan(&yes) + if strings.ToLower(yes) == "y" { + var temp string + fmt.Println("请输入节点id:") + fmt.Scan(&temp) + key = temp + fmt.Println("请输入节点类型:") + fmt.Scan(&temp) + key += strings.ToLower(temp) + fmt.Println("请输入Token:") + fmt.Scan(&temp) + key += temp + privateKey = crypt.GenX25519Private([]byte(key)) + } else { + privateKey = make([]byte, curve25519.ScalarSize) + if _, err = rand.Read(privateKey); err != nil { + output = Err("read rand error: ", err) + return + } } - - // Modify random bytes using algorithm described at: - // https://cr.yp.to/ecdh.html. - privateKey[0] &= 248 - privateKey[31] &= 127 - privateKey[31] |= 64 - if publicKey, err = curve25519.X25519(privateKey, curve25519.Basepoint); err != nil { output = Err("gen X25519 error: ", err) return @@ -66,11 +63,4 @@ func executeX25519() { p, "\nPublic key: ", base64.RawURLEncoding.EncodeToString(publicKey)) - if strings.ToLower(yes) == "y" { - key, err = crypt.AesEncrypt([]byte(p), []byte(key[:32])) - if err != nil { - output = Err("encrypt private key error: ", err) - } - output += "\n加密后的Private key:" + key - } } diff --git a/common/crypt/sha.go b/common/crypt/sha.go deleted file mode 100644 index 05ddbeb..0000000 --- a/common/crypt/sha.go +++ /dev/null @@ -1,11 +0,0 @@ -package crypt - -import ( - "crypto/sha256" - "encoding/hex" -) - -func GenShaHash(data []byte) string { - d := sha256.Sum256(data) - return hex.EncodeToString(d[:]) -} diff --git a/common/crypt/x25519.go b/common/crypt/x25519.go new file mode 100644 index 0000000..9fec20b --- /dev/null +++ b/common/crypt/x25519.go @@ -0,0 +1,13 @@ +package crypt + +import ( + "crypto/sha256" +) + +func GenX25519Private(data []byte) []byte { + key := sha256.Sum256(data) + key[0] &= 248 + key[31] &= 127 + key[31] |= 64 + return key[:32] +} diff --git a/conf/node.go b/conf/node.go index b843a78..939fabd 100644 --- a/conf/node.go +++ b/conf/node.go @@ -27,8 +27,6 @@ type XrayOptions struct { EnableProxyProtocol bool `yaml:"EnableProxyProtocol"` EnableDNS bool `yaml:"EnableDNS"` DNSType string `yaml:"DNSType"` - EnableVless bool `yaml:"EnableVless"` - VlessFlow string `json:"VlessFlow"` EnableUot bool `yaml:"EnableUot"` EnableTFO bool `yaml:"EnableTFO"` DisableIVCheck bool `yaml:"DisableIVCheck"` @@ -99,16 +97,4 @@ type CertConfig struct { Provider string `yaml:"Provider"` // alidns, cloudflare, gandi, godaddy.... Email string `yaml:"Email"` DNSEnv map[string]string `yaml:"DNSEnv"` - RealityConfig *RealityConfig `yaml:"RealityConfig"` -} - -type RealityConfig struct { - Dest interface{} `yaml:"Dest" json:"Dest"` - Xver uint64 `yaml:"Xver" json:"Xver"` - ServerNames []string `yaml:"ServerNames" json:"ServerNames"` - PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"` - MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"` - MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"` - MaxTimeDiff uint64 `yaml:"MaxTimeDiff" json:"MaxTimeDiff"` - ShortIds []string `yaml:"ShortIds" json:"ShortIds"` } diff --git a/conf/old.go b/conf/old.go index 7c8d92e..f8be2e2 100644 --- a/conf/old.go +++ b/conf/old.go @@ -47,11 +47,6 @@ func migrateOldConfig(c *Conf, old *OldConfig) { if i >= len(old.NodesConfig) { break } - // node option - if old.NodesConfig[i].ApiConfig.EnableVless { - n.ControllerConfig.XrayOptions.EnableVless = true - changed = true - } // limit config if old.NodesConfig[i].ApiConfig.SpeedLimit != 0 { n.ControllerConfig.LimitConfig.SpeedLimit = old.NodesConfig[i].ApiConfig.SpeedLimit diff --git a/core/xray/inbound.go b/core/xray/inbound.go index c59c5f7..e25f358 100644 --- a/core/xray/inbound.go +++ b/core/xray/inbound.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/Yuzuki616/V2bX/api/panel" "github.com/Yuzuki616/V2bX/conf" "github.com/goccy/go-json" @@ -70,54 +71,37 @@ func buildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s } switch config.CertConfig.CertMode { case "none", "": // disable - case "reality": - // Reality - in.StreamSetting.Security = "reality" - d, err := json.Marshal(config.CertConfig.RealityConfig.Dest) - if err != nil { - return nil, fmt.Errorf("marshal reality dest error: %s", err) - } - in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{ - Dest: d, - Xver: config.CertConfig.RealityConfig.Xver, - ServerNames: config.CertConfig.RealityConfig.ServerNames, - PrivateKey: config.CertConfig.RealityConfig.PrivateKey, - MinClientVer: config.CertConfig.RealityConfig.MinClientVer, - MaxClientVer: config.CertConfig.RealityConfig.MaxClientVer, - MaxTimeDiff: config.CertConfig.RealityConfig.MaxTimeDiff, - ShortIds: config.CertConfig.RealityConfig.ShortIds, - } default: - // Normal tls - in.StreamSetting.Security = "tls" - in.StreamSetting.TLSSettings = &coreConf.TLSConfig{ - Certs: []*coreConf.TLSCertConfig{ - { - CertFile: config.CertConfig.CertFile, - KeyFile: config.CertConfig.KeyFile, - OcspStapling: 3600, + if nodeInfo.ExtraConfig.EnableReality { + rc := nodeInfo.ExtraConfig.RealityConfig + in.StreamSetting.Security = "reality" + d, err := json.Marshal(rc.Dest) + if err != nil { + return nil, fmt.Errorf("marshal reality dest error: %s", err) + } + in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{ + Dest: d, + Xver: rc.Xver, + ServerNames: rc.ServerNames, + PrivateKey: rc.PrivateKey, + MinClientVer: rc.MinClientVer, + MaxClientVer: rc.MaxClientVer, + MaxTimeDiff: rc.MaxTimeDiff, + ShortIds: rc.ShortIds, + } + } else { + // Normal tls + in.StreamSetting.Security = "tls" + in.StreamSetting.TLSSettings = &coreConf.TLSConfig{ + Certs: []*coreConf.TLSCertConfig{ + { + CertFile: config.CertConfig.CertFile, + KeyFile: config.CertConfig.KeyFile, + OcspStapling: 3600, + }, }, - }, - RejectUnknownSNI: config.CertConfig.RejectUnknownSni, - } - } - // use remote reality replace local config - if nodeInfo.ExtraConfig.EnableReality { - rc := nodeInfo.ExtraConfig.RealityConfig - in.StreamSetting.Security = "reality" - d, err := json.Marshal(rc.Dest) - if err != nil { - return nil, fmt.Errorf("marshal reality dest error: %s", err) - } - in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{ - Dest: d, - Xver: rc.Xver, - ServerNames: rc.ServerNames, - PrivateKey: rc.PrivateKey, - MinClientVer: rc.MinClientVer, - MaxClientVer: rc.MaxClientVer, - MaxTimeDiff: rc.MaxTimeDiff, - ShortIds: rc.ShortIds, + RejectUnknownSNI: config.CertConfig.RejectUnknownSni, + } } } } @@ -136,8 +120,7 @@ func buildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s } func buildV2ray(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error { - if config.XrayOptions.EnableVless || - nodeInfo.ExtraConfig.EnableVless { + if nodeInfo.ExtraConfig.EnableVless { //Set vless inbound.Protocol = "vless" if config.XrayOptions.EnableFallback {