diff --git a/api/panel/node.go b/api/panel/node.go index 4d7dac1..7f1767f 100644 --- a/api/panel/node.go +++ b/api/panel/node.go @@ -2,13 +2,16 @@ package panel import ( "fmt" - "github.com/Yuzuki616/V2bX/conf" - "github.com/goccy/go-json" "reflect" "regexp" "strconv" "strings" "time" + + "github.com/Yuzuki616/V2bX/common/crypt" + + "github.com/Yuzuki616/V2bX/conf" + "github.com/goccy/go-json" ) type CommonNodeRsp struct { @@ -97,7 +100,6 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) { if err != nil { return nil, fmt.Errorf("decode common params error: %s", err) } - var extra []byte for i := range common.Routes { // parse rules from routes var matchs []string if _, ok := common.Routes[i].Match.(string); ok { @@ -117,10 +119,6 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) { node.Rules = append(node.Rules, regexp.MustCompile(v)) } case "dns": - if matchs[0] != "extra" { - break - } - extra = []byte(strings.Join(matchs[1:], "")) } } node.ServerName = common.ServerName @@ -142,11 +140,14 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) { if rsp.Tls == 1 { node.Tls = true } - if len(extra) != 0 { - err = json.Unmarshal(extra, &node.ExtraConfig) - if err != nil { - return nil, fmt.Errorf("decode v2ray extra error: %s", err) - } + err = json.Unmarshal(rsp.NetworkSettings, &node.ExtraConfig) + 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 } case "shadowsocks": rsp := ShadowsocksNodeRsp{} diff --git a/api/panel/panel.go b/api/panel/panel.go index f6e90dd..c1acaa2 100644 --- a/api/panel/panel.go +++ b/api/panel/panel.go @@ -3,14 +3,15 @@ package panel import ( "bufio" "fmt" - "github.com/Yuzuki616/V2bX/conf" - "github.com/go-resty/resty/v2" "log" "os" "regexp" "strconv" "strings" "time" + + "github.com/Yuzuki616/V2bX/conf" + "github.com/go-resty/resty/v2" ) // Panel is the interface for different panel's api. @@ -18,7 +19,7 @@ import ( type Client struct { client *resty.Client APIHost string - Key string + Token string NodeType string NodeId int LocalRuleList []*regexp.Regexp @@ -48,7 +49,7 @@ func New(c *conf.ApiConfig) (*Client, error) { default: return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType) } - // Create Key for each requests + // set params client.SetQueryParams(map[string]string{ "node_type": c.NodeType, "node_id": strconv.Itoa(c.NodeID), @@ -58,7 +59,7 @@ func New(c *conf.ApiConfig) (*Client, error) { localRuleList := readLocalRuleList(c.RuleListPath) return &Client{ client: client, - Key: c.Key, + Token: c.Key, APIHost: c.APIHost, NodeType: c.NodeType, NodeId: c.NodeID, diff --git a/cmd/x25519.go b/cmd/x25519.go index 791a4b0..361d4a8 100644 --- a/cmd/x25519.go +++ b/cmd/x25519.go @@ -4,6 +4,9 @@ import ( "crypto/rand" "encoding/base64" "fmt" + "strings" + + "github.com/Yuzuki616/V2bX/common/crypt" "github.com/spf13/cobra" "golang.org/x/crypto/curve25519" @@ -22,6 +25,19 @@ 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,9 +61,16 @@ func executeX25519() { output = Err("gen X25519 error: ", err) return } - + p := base64.RawURLEncoding.EncodeToString(privateKey) output = fmt.Sprint("Private key: ", - base64.RawURLEncoding.EncodeToString(privateKey), + 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/builder/user.go b/common/builder/user.go deleted file mode 100644 index 91a5399..0000000 --- a/common/builder/user.go +++ /dev/null @@ -1,131 +0,0 @@ -package builder - -import ( - "encoding/base64" - "fmt" - "github.com/Yuzuki616/V2bX/api/panel" - "github.com/xtls/xray-core/common/protocol" - "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/infra/conf" - "github.com/xtls/xray-core/proxy/shadowsocks" - "github.com/xtls/xray-core/proxy/shadowsocks_2022" - "github.com/xtls/xray-core/proxy/trojan" - "github.com/xtls/xray-core/proxy/vless" - "strings" -) - -func BuildVmessUsers(tag string, userInfo []panel.UserInfo) (users []*protocol.User) { - users = make([]*protocol.User, len(userInfo)) - for i, user := range userInfo { - users[i] = BuildVmessUser(tag, &user) - } - return users -} - -func BuildVmessUser(tag string, userInfo *panel.UserInfo) (user *protocol.User) { - vmessAccount := &conf.VMessAccount{ - ID: userInfo.Uuid, - AlterIds: 0, - Security: "auto", - } - return &protocol.User{ - Level: 0, - Email: BuildUserTag(tag, userInfo.Uuid), // Uid: InboundTag|email - Account: serial.ToTypedMessage(vmessAccount.Build()), - } -} - -func BuildVlessUsers(tag string, userInfo []panel.UserInfo, flow string) (users []*protocol.User) { - users = make([]*protocol.User, len(userInfo)) - for i := range userInfo { - users[i] = BuildVlessUser(tag, &(userInfo)[i], flow) - } - return users -} - -func BuildVlessUser(tag string, userInfo *panel.UserInfo, flow string) (user *protocol.User) { - vlessAccount := &vless.Account{ - Id: userInfo.Uuid, - } - vlessAccount.Flow = flow - return &protocol.User{ - Level: 0, - Email: BuildUserTag(tag, userInfo.Uuid), - Account: serial.ToTypedMessage(vlessAccount), - } -} - -func BuildTrojanUsers(tag string, userInfo []panel.UserInfo) (users []*protocol.User) { - users = make([]*protocol.User, len(userInfo)) - for i := range userInfo { - users[i] = BuildTrojanUser(tag, &(userInfo)[i]) - } - return users -} - -func BuildTrojanUser(tag string, userInfo *panel.UserInfo) (user *protocol.User) { - trojanAccount := &trojan.Account{ - Password: userInfo.Uuid, - } - return &protocol.User{ - Level: 0, - Email: BuildUserTag(tag, userInfo.Uuid), - Account: serial.ToTypedMessage(trojanAccount), - } -} -func BuildSSUsers(tag string, userInfo []panel.UserInfo, cypher string, serverKey string) (users []*protocol.User) { - users = make([]*protocol.User, len(userInfo)) - for i := range userInfo { - users[i] = BuildSSUser(tag, &userInfo[i], cypher, serverKey) - } - return users -} - -func BuildSSUser(tag string, userInfo *panel.UserInfo, cypher string, serverKey string) (user *protocol.User) { - if serverKey == "" { - ssAccount := &shadowsocks.Account{ - Password: userInfo.Uuid, - CipherType: getCipherFromString(cypher), - } - return &protocol.User{ - Level: 0, - Email: BuildUserTag(tag, userInfo.Uuid), - Account: serial.ToTypedMessage(ssAccount), - } - } else { - var keyLength int - switch cypher { - case "2022-blake3-aes-128-gcm": - keyLength = 16 - case "2022-blake3-aes-256-gcm": - keyLength = 32 - } - ssAccount := &shadowsocks_2022.User{ - Key: base64.StdEncoding.EncodeToString([]byte(userInfo.Uuid[:keyLength])), - } - return &protocol.User{ - Level: 0, - Email: BuildUserTag(tag, userInfo.Uuid), - Account: serial.ToTypedMessage(ssAccount), - } - } -} - -func BuildUserTag(tag string, uuid string) string { - return fmt.Sprintf("%s|%s", tag, uuid) -} - -func getCipherFromString(c string) shadowsocks.CipherType { - switch strings.ToLower(c) { - case "aes-128-gcm", "aead_aes_128_gcm": - return shadowsocks.CipherType_AES_128_GCM - case "aes-256-gcm", "aead_aes_256_gcm": - return shadowsocks.CipherType_AES_256_GCM - case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305": - return shadowsocks.CipherType_CHACHA20_POLY1305 - case "none", "plain": - return shadowsocks.CipherType_NONE - default: - return shadowsocks.CipherType_UNKNOWN - } -} diff --git a/common/crypt/aes.go b/common/crypt/aes.go new file mode 100644 index 0000000..4ab5cea --- /dev/null +++ b/common/crypt/aes.go @@ -0,0 +1,30 @@ +package crypt + +import ( + "crypto/aes" + "encoding/base64" +) + +func AesEncrypt(data []byte, key []byte) (string, error) { + a, err := aes.NewCipher(key) + if err != nil { + return "", err + } + en := make([]byte, len(data)) + a.Encrypt(en, data) + return base64.StdEncoding.EncodeToString(en), nil +} + +func AesDecrypt(data string, key []byte) (string, error) { + d, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return "", err + } + a, err := aes.NewCipher(key) + if err != nil { + return "", err + } + de := make([]byte, len(data)) + a.Decrypt(de, d) + return string(de), nil +} diff --git a/common/crypt/sha.go b/common/crypt/sha.go new file mode 100644 index 0000000..05ddbeb --- /dev/null +++ b/common/crypt/sha.go @@ -0,0 +1,11 @@ +package crypt + +import ( + "crypto/sha256" + "encoding/hex" +) + +func GenShaHash(data []byte) string { + d := sha256.Sum256(data) + return hex.EncodeToString(d[:]) +} diff --git a/common/format/user.go b/common/format/user.go new file mode 100644 index 0000000..08cb9fb --- /dev/null +++ b/common/format/user.go @@ -0,0 +1,9 @@ +package format + +import ( + "fmt" +) + +func UserTag(tag string, uuid string) string { + return fmt.Sprintf("%s|%s", tag, uuid) +} diff --git a/common/builder/inbound.go b/core/xray/inbound.go similarity index 92% rename from common/builder/inbound.go rename to core/xray/inbound.go index 21e3c9f..c59c5f7 100644 --- a/common/builder/inbound.go +++ b/core/xray/inbound.go @@ -1,4 +1,4 @@ -package builder +package xray import ( "crypto/rand" @@ -6,7 +6,6 @@ import ( "encoding/hex" "errors" "fmt" - "github.com/Yuzuki616/V2bX/api/panel" "github.com/Yuzuki616/V2bX/conf" "github.com/goccy/go-json" @@ -16,7 +15,7 @@ import ( ) // BuildInbound build Inbound config for different protocol -func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag string) (*core.InboundHandlerConfig, error) { +func buildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag string) (*core.InboundHandlerConfig, error) { in := &coreConf.InboundDetourConfig{} // Set network protocol t := coreConf.TransportProtocol(nodeInfo.Network) @@ -102,24 +101,24 @@ func BuildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s 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, + // 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, + } } } // Support ProxyProtocol for any transport protocol @@ -194,6 +193,8 @@ func buildV2ray(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, inbound if err != nil { return fmt.Errorf("unmarshal grpc settings error: %s", err) } + default: + return errors.New("the network type is not vail") } return nil } diff --git a/core/xray/node.go b/core/xray/node.go index 8dabad1..a26204a 100644 --- a/core/xray/node.go +++ b/core/xray/node.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "github.com/Yuzuki616/V2bX/api/panel" - "github.com/Yuzuki616/V2bX/common/builder" "github.com/Yuzuki616/V2bX/conf" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/inbound" @@ -12,7 +11,7 @@ import ( ) func (c *Core) AddNode(tag string, info *panel.NodeInfo, config *conf.ControllerConfig) error { - inboundConfig, err := builder.BuildInbound(config, info, tag) + inboundConfig, err := buildInbound(config, info, tag) if err != nil { return fmt.Errorf("build inbound error: %s", err) } @@ -20,7 +19,7 @@ func (c *Core) AddNode(tag string, info *panel.NodeInfo, config *conf.Controller if err != nil { return fmt.Errorf("add inbound error: %s", err) } - outBoundConfig, err := builder.BuildOutbound(config, tag) + outBoundConfig, err := buildOutbound(config, tag) if err != nil { return fmt.Errorf("build outbound error: %s", err) } diff --git a/common/builder/outbound.go b/core/xray/outbound.go similarity index 93% rename from common/builder/outbound.go rename to core/xray/outbound.go index f3be9b9..ee09bab 100644 --- a/common/builder/outbound.go +++ b/core/xray/outbound.go @@ -1,4 +1,4 @@ -package builder +package xray import ( "fmt" @@ -10,7 +10,7 @@ import ( ) // BuildOutbound build freedom outbund config for addoutbound -func BuildOutbound(config *conf2.ControllerConfig, tag string) (*core.OutboundHandlerConfig, error) { +func buildOutbound(config *conf2.ControllerConfig, tag string) (*core.OutboundHandlerConfig, error) { outboundDetourConfig := &conf.OutboundDetourConfig{} outboundDetourConfig.Protocol = "freedom" outboundDetourConfig.Tag = tag diff --git a/core/xray/ss.go b/core/xray/ss.go new file mode 100644 index 0000000..299c2d7 --- /dev/null +++ b/core/xray/ss.go @@ -0,0 +1,65 @@ +package xray + +import ( + "encoding/base64" + "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/format" + "github.com/xtls/xray-core/common/protocol" + "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/proxy/shadowsocks" + "github.com/xtls/xray-core/proxy/shadowsocks_2022" + "strings" +) + +func buildSSUsers(tag string, userInfo []panel.UserInfo, cypher string, serverKey string) (users []*protocol.User) { + users = make([]*protocol.User, len(userInfo)) + for i := range userInfo { + users[i] = buildSSUser(tag, &userInfo[i], cypher, serverKey) + } + return users +} + +func buildSSUser(tag string, userInfo *panel.UserInfo, cypher string, serverKey string) (user *protocol.User) { + if serverKey == "" { + ssAccount := &shadowsocks.Account{ + Password: userInfo.Uuid, + CipherType: getCipherFromString(cypher), + } + return &protocol.User{ + Level: 0, + Email: format.UserTag(tag, userInfo.Uuid), + Account: serial.ToTypedMessage(ssAccount), + } + } else { + var keyLength int + switch cypher { + case "2022-blake3-aes-128-gcm": + keyLength = 16 + case "2022-blake3-aes-256-gcm": + keyLength = 32 + } + ssAccount := &shadowsocks_2022.User{ + Key: base64.StdEncoding.EncodeToString([]byte(userInfo.Uuid[:keyLength])), + } + return &protocol.User{ + Level: 0, + Email: format.UserTag(tag, userInfo.Uuid), + Account: serial.ToTypedMessage(ssAccount), + } + } +} + +func getCipherFromString(c string) shadowsocks.CipherType { + switch strings.ToLower(c) { + case "aes-128-gcm", "aead_aes_128_gcm": + return shadowsocks.CipherType_AES_128_GCM + case "aes-256-gcm", "aead_aes_256_gcm": + return shadowsocks.CipherType_AES_256_GCM + case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305": + return shadowsocks.CipherType_CHACHA20_POLY1305 + case "none", "plain": + return shadowsocks.CipherType_NONE + default: + return shadowsocks.CipherType_UNKNOWN + } +} diff --git a/core/xray/trojan.go b/core/xray/trojan.go new file mode 100644 index 0000000..cea6762 --- /dev/null +++ b/core/xray/trojan.go @@ -0,0 +1,28 @@ +package xray + +import ( + "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/format" + "github.com/xtls/xray-core/common/protocol" + "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/proxy/trojan" +) + +func buildTrojanUsers(tag string, userInfo []panel.UserInfo) (users []*protocol.User) { + users = make([]*protocol.User, len(userInfo)) + for i := range userInfo { + users[i] = buildTrojanUser(tag, &(userInfo)[i]) + } + return users +} + +func buildTrojanUser(tag string, userInfo *panel.UserInfo) (user *protocol.User) { + trojanAccount := &trojan.Account{ + Password: userInfo.Uuid, + } + return &protocol.User{ + Level: 0, + Email: format.UserTag(tag, userInfo.Uuid), + Account: serial.ToTypedMessage(trojanAccount), + } +} diff --git a/core/xray/user.go b/core/xray/user.go index b2a51e4..3eb9341 100644 --- a/core/xray/user.go +++ b/core/xray/user.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "github.com/Yuzuki616/V2bX/api/panel" - "github.com/Yuzuki616/V2bX/common/builder" + "github.com/Yuzuki616/V2bX/common/format" vCore "github.com/Yuzuki616/V2bX/core" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/proxy" @@ -33,7 +33,7 @@ func (c *Core) DelUsers(users []panel.UserInfo, tag string) error { } var up, down, user string for i := range users { - user = builder.BuildUserTag(tag, users[i].Uuid) + user = format.UserTag(tag, users[i].Uuid) err = userManager.RemoveUser(context.Background(), user) if err != nil { return err @@ -47,8 +47,8 @@ func (c *Core) DelUsers(users []panel.UserInfo, tag string) error { } func (c *Core) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) { - upName := "user>>>" + builder.BuildUserTag(tag, uuid) + ">>>traffic>>>uplink" - downName := "user>>>" + builder.BuildUserTag(tag, uuid) + ">>>traffic>>>downlink" + upName := "user>>>" + format.UserTag(tag, uuid) + ">>>traffic>>>uplink" + downName := "user>>>" + format.UserTag(tag, uuid) + ">>>traffic>>>downlink" upCounter := c.shm.GetCounter(upName) downCounter := c.shm.GetCounter(downName) if reset { @@ -77,22 +77,24 @@ func (c *Core) AddUsers(p *vCore.AddUsersParams) (added int, err error) { p.NodeInfo.ExtraConfig.EnableVless { if p.Config.XrayOptions.VlessFlow != "" { if p.Config.XrayOptions.VlessFlow == p.NodeInfo.ExtraConfig.VlessFlow { - users = builder.BuildVlessUsers(p.Tag, p.UserInfo, p.Config.XrayOptions.VlessFlow) + // local + users = buildVlessUsers(p.Tag, p.UserInfo, p.Config.XrayOptions.VlessFlow) } else { - users = builder.BuildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow) + // remote + users = buildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow) } - } else { - users = builder.BuildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow) + // remote + users = buildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow) } } else { - users = builder.BuildVmessUsers(p.Tag, p.UserInfo) + users = buildVmessUsers(p.Tag, p.UserInfo) } case "trojan": - users = builder.BuildTrojanUsers(p.Tag, p.UserInfo) + users = buildTrojanUsers(p.Tag, p.UserInfo) case "shadowsocks": - users = builder.BuildSSUsers(p.Tag, + users = buildSSUsers(p.Tag, p.UserInfo, p.NodeInfo.Cipher, p.NodeInfo.ServerKey) diff --git a/core/xray/vmess.go b/core/xray/vmess.go new file mode 100644 index 0000000..75f93b6 --- /dev/null +++ b/core/xray/vmess.go @@ -0,0 +1,51 @@ +package xray + +import ( + "github.com/Yuzuki616/V2bX/api/panel" + "github.com/Yuzuki616/V2bX/common/format" + "github.com/xtls/xray-core/common/protocol" + "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/infra/conf" + "github.com/xtls/xray-core/proxy/vless" +) + +func buildVmessUsers(tag string, userInfo []panel.UserInfo) (users []*protocol.User) { + users = make([]*protocol.User, len(userInfo)) + for i, user := range userInfo { + users[i] = buildVmessUser(tag, &user) + } + return users +} + +func buildVmessUser(tag string, userInfo *panel.UserInfo) (user *protocol.User) { + vmessAccount := &conf.VMessAccount{ + ID: userInfo.Uuid, + AlterIds: 0, + Security: "auto", + } + return &protocol.User{ + Level: 0, + Email: format.UserTag(tag, userInfo.Uuid), // Uid: InboundTag|email + Account: serial.ToTypedMessage(vmessAccount.Build()), + } +} + +func buildVlessUsers(tag string, userInfo []panel.UserInfo, flow string) (users []*protocol.User) { + users = make([]*protocol.User, len(userInfo)) + for i := range userInfo { + users[i] = buildVlessUser(tag, &(userInfo)[i], flow) + } + return users +} + +func buildVlessUser(tag string, userInfo *panel.UserInfo, flow string) (user *protocol.User) { + vlessAccount := &vless.Account{ + Id: userInfo.Uuid, + } + vlessAccount.Flow = flow + return &protocol.User{ + Level: 0, + Email: format.UserTag(tag, userInfo.Uuid), + Account: serial.ToTypedMessage(vlessAccount), + } +} diff --git a/limiter/dynamic.go b/limiter/dynamic.go index a74599e..b68a19d 100644 --- a/limiter/dynamic.go +++ b/limiter/dynamic.go @@ -2,7 +2,7 @@ package limiter import ( "github.com/Yuzuki616/V2bX/api/panel" - "github.com/Yuzuki616/V2bX/common/builder" + "github.com/Yuzuki616/V2bX/common/format" "time" ) @@ -11,7 +11,7 @@ func (l *Limiter) AddDynamicSpeedLimit(tag string, userInfo *panel.UserInfo, lim DynamicSpeedLimit: limitNum, ExpireTime: time.Now().Add(time.Duration(expire) * time.Second).Unix(), } - l.UserLimitInfo.Store(builder.BuildUserTag(tag, userInfo.Uuid), userLimit) + l.UserLimitInfo.Store(format.UserTag(tag, userInfo.Uuid), userLimit) return nil } diff --git a/limiter/limiter.go b/limiter/limiter.go index 45c4583..149538a 100644 --- a/limiter/limiter.go +++ b/limiter/limiter.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" "github.com/Yuzuki616/V2bX/api/panel" - "github.com/Yuzuki616/V2bX/common/builder" + "github.com/Yuzuki616/V2bX/common/format" "github.com/Yuzuki616/V2bX/conf" "github.com/juju/ratelimit" log "github.com/sirupsen/logrus" @@ -61,7 +61,7 @@ func AddLimiter(tag string, l *conf.LimitConfig, users []panel.UserInfo) *Limite SpeedLimit: users[i].SpeedLimit, ExpireTime: 0, } - info.UserLimitInfo.Store(builder.BuildUserTag(tag, users[i].Uuid), userLimit) + info.UserLimitInfo.Store(format.UserTag(tag, users[i].Uuid), userLimit) } } limitLock.Lock() @@ -86,7 +86,7 @@ func UpdateLimiter(tag string, added []panel.UserInfo, deleted []panel.UserInfo) return fmt.Errorf("get limit error: %s", err) } for i := range deleted { - l.UserLimitInfo.Delete(builder.BuildUserTag(tag, deleted[i].Uuid)) + l.UserLimitInfo.Delete(format.UserTag(tag, deleted[i].Uuid)) } for i := range added { if added[i].SpeedLimit != 0 { @@ -95,7 +95,7 @@ func UpdateLimiter(tag string, added []panel.UserInfo, deleted []panel.UserInfo) SpeedLimit: added[i].SpeedLimit, ExpireTime: 0, } - l.UserLimitInfo.Store(builder.BuildUserTag(tag, added[i].Uuid), userLimit) + l.UserLimitInfo.Store(format.UserTag(tag, added[i].Uuid), userLimit) } } return nil diff --git a/node/cert.go b/node/cert.go index 500c631..ed79016 100644 --- a/node/cert.go +++ b/node/cert.go @@ -21,13 +21,17 @@ func (c *Controller) renewCertTask() { } func (c *Controller) requestCert() error { - if c.CertConfig.CertFile == "" || c.CertConfig.KeyFile == "" { - return fmt.Errorf("cert file path or key file path not exist") - } switch c.CertConfig.CertMode { case "reality", "none", "": return nil + case "file": + if c.CertConfig.CertFile == "" || c.CertConfig.KeyFile == "" { + return fmt.Errorf("cert file path or key file path not exist") + } case "dns", "http": + if c.CertConfig.CertFile == "" || c.CertConfig.KeyFile == "" { + return fmt.Errorf("cert file path or key file path not exist") + } if file.IsExist(c.CertConfig.CertFile) && file.IsExist(c.CertConfig.KeyFile) { return nil }