From 73bc37cb516fbf74734484984deb7c6783460a78 Mon Sep 17 00:00:00 2001 From: Senis John Date: Wed, 4 Oct 2023 21:49:17 +0800 Subject: [PATCH] Add EnableREALITY field and update REALITYConfig parsing Enabled the REALITY feature on both model.go and sspanel.go for the api and service assemblies and updated the inboundbuilder to switch the REALITY feature based on the new field and condition statements. This enhancement allows finer control and visibility of the REALITY feature's activation. In addition, the REALITYConfig in config.go was updated to remove the DisableLocal field and add the DisableLocalREALITYConfig field. The main/config.yml.example file has also been updated to reflect these changes and provide users with a clearer understanding of the config setup. --- api/apimodel.go | 13 +++++++++ api/sspanel/model.go | 13 +++++++++ api/sspanel/sspanel.go | 18 ++++++++++++ go.mod | 2 +- go.sum | 9 ++++++ main/config.yml.example | 2 ++ service/controller/config.go | 35 ++++++++++++----------- service/controller/inboundbuilder.go | 31 ++++++++++++++++---- service/controller/inboundbuilder_test.go | 3 -- 9 files changed, 99 insertions(+), 27 deletions(-) diff --git a/api/apimodel.go b/api/apimodel.go index aa8650a..58104be 100644 --- a/api/apimodel.go +++ b/api/apimodel.go @@ -54,6 +54,8 @@ type NodeInfo struct { ServiceName string Header json.RawMessage NameServerConfig []*conf.NameServerConfig + EnableREALITY bool + REALITYConfig *REALITYConfig } type UserInfo struct { @@ -96,3 +98,14 @@ type DetectResult struct { UID int RuleID int } + +type REALITYConfig struct { + Dest string + ProxyProtocolVer uint64 + ServerNames []string + PrivateKey string + MinClientVer string + MaxClientVer string + MaxTimeDiff uint64 + ShortIds []string +} diff --git a/api/sspanel/model.go b/api/sspanel/model.go index d723956..f088d29 100644 --- a/api/sspanel/model.go +++ b/api/sspanel/model.go @@ -31,6 +31,8 @@ type CustomConfig struct { Servicename string `json:"servicename"` EnableXtls string `json:"enable_xtls"` Flow string `json:"flow"` + EnableREALITY bool `json:"enable_reality"` + RealityOpts *REALITYConfig `json:"reality-opts"` } // UserResponse is the response of user @@ -84,3 +86,14 @@ type IllegalItem struct { ID int `json:"list_id"` UID int `json:"user_id"` } + +type REALITYConfig struct { + Dest string `json:"dest,omitempty"` + ProxyProtocolVer uint64 `json:"proxy_protocol_ver,omitempty"` + ServerNames []string `json:"server_names,omitempty"` + PrivateKey string `json:"private_key,omitempty"` + MinClientVer string `json:"min_client_ver,omitempty"` + MaxClientVer string `json:"max_client_ver,omitempty"` + MaxTimeDiff uint64 `json:"max_time_diff,omitempty"` + ShortIds []string `json:"short_ids,omitempty"` +} diff --git a/api/sspanel/sspanel.go b/api/sspanel/sspanel.go index fc31957..dd0f591 100644 --- a/api/sspanel/sspanel.go +++ b/api/sspanel/sspanel.go @@ -792,6 +792,22 @@ func (c *APIClient) ParseSSPanelNodeInfo(nodeInfoResponse *NodeInfoResponse) (*a } } + // parse reality config + realityConfig := new(api.REALITYConfig) + if nodeConfig.RealityOpts != nil { + r := nodeConfig.RealityOpts + realityConfig = &api.REALITYConfig{ + Dest: r.Dest, + ProxyProtocolVer: r.ProxyProtocolVer, + ServerNames: r.ServerNames, + PrivateKey: r.PrivateKey, + MinClientVer: r.MinClientVer, + MaxClientVer: r.MaxClientVer, + MaxTimeDiff: r.MaxTimeDiff, + ShortIds: r.ShortIds, + } + } + // Create GeneralNodeInfo nodeInfo := &api.NodeInfo{ NodeType: c.NodeType, @@ -808,6 +824,8 @@ func (c *APIClient) ParseSSPanelNodeInfo(nodeInfoResponse *NodeInfoResponse) (*a CypherMethod: nodeConfig.Method, ServiceName: nodeConfig.Servicename, Header: nodeConfig.Header, + EnableREALITY: nodeConfig.EnableREALITY, + REALITYConfig: realityConfig, } return nodeInfo, nil diff --git a/go.mod b/go.mod index e0e825a..632339b 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.24 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect diff --git a/go.sum b/go.sum index 624cbdd..b0688a4 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/Azure/go-autorest/autorest v0.11.24 h1:1fIGgHKqVm54KIPT+q8Zmd1QlVsmHq github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 h1:0W/yGmFdTIT77fvdlGZ0LMISoLHFJ7Tx4U0yeB+uFs4= @@ -300,6 +302,8 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -322,6 +326,7 @@ github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= @@ -434,6 +439,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -1002,6 +1008,7 @@ golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1030,6 +1037,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1438,6 +1446,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0= diff --git a/main/config.yml.example b/main/config.yml.example index 120d7c0..c82848a 100644 --- a/main/config.yml.example +++ b/main/config.yml.example @@ -25,6 +25,7 @@ Nodes: SpeedLimit: 0 # Mbps, Local settings will replace remote settings, 0 means disable DeviceLimit: 0 # Local settings will replace remote settings, 0 means disable RuleListPath: # /etc/XrayR/rulelist Path to local rulelist file + DisableCustomConfig: false # disable custom config for sspanel ControllerConfig: ListenIP: 0.0.0.0 # IP address you want to listen SendIP: 0.0.0.0 # IP address you want to send pacakage @@ -51,6 +52,7 @@ Nodes: Path: # HTTP PATH, Empty for any Dest: 80 # Required, Destination of fallback, check https://xtls.github.io/config/features/fallback.html for details. ProxyProtocolVer: 0 # Send PROXY protocol version, 0 for disable + DisableLocalREALITYConfig: false # disable local reality config EnableREALITY: true # Enable REALITY REALITYConfigs: Show: true # Show REALITY debug diff --git a/service/controller/config.go b/service/controller/config.go index fe8d2e0..eb59eb0 100644 --- a/service/controller/config.go +++ b/service/controller/config.go @@ -6,23 +6,24 @@ import ( ) type Config struct { - ListenIP string `mapstructure:"ListenIP"` - SendIP string `mapstructure:"SendIP"` - UpdatePeriodic int `mapstructure:"UpdatePeriodic"` - CertConfig *mylego.CertConfig `mapstructure:"CertConfig"` - EnableDNS bool `mapstructure:"EnableDNS"` - DNSType string `mapstructure:"DNSType"` - DisableUploadTraffic bool `mapstructure:"DisableUploadTraffic"` - DisableGetRule bool `mapstructure:"DisableGetRule"` - EnableProxyProtocol bool `mapstructure:"EnableProxyProtocol"` - EnableFallback bool `mapstructure:"EnableFallback"` - DisableIVCheck bool `mapstructure:"DisableIVCheck"` - DisableSniffing bool `mapstructure:"DisableSniffing"` - AutoSpeedLimitConfig *AutoSpeedLimitConfig `mapstructure:"AutoSpeedLimitConfig"` - GlobalDeviceLimitConfig *limiter.GlobalDeviceLimitConfig `mapstructure:"GlobalDeviceLimitConfig"` - FallBackConfigs []*FallBackConfig `mapstructure:"FallBackConfigs"` - EnableREALITY bool `mapstructure:"EnableREALITY"` - REALITYConfigs *REALITYConfig `mapstructure:"REALITYConfigs"` + ListenIP string `mapstructure:"ListenIP"` + SendIP string `mapstructure:"SendIP"` + UpdatePeriodic int `mapstructure:"UpdatePeriodic"` + CertConfig *mylego.CertConfig `mapstructure:"CertConfig"` + EnableDNS bool `mapstructure:"EnableDNS"` + DNSType string `mapstructure:"DNSType"` + DisableUploadTraffic bool `mapstructure:"DisableUploadTraffic"` + DisableGetRule bool `mapstructure:"DisableGetRule"` + EnableProxyProtocol bool `mapstructure:"EnableProxyProtocol"` + EnableFallback bool `mapstructure:"EnableFallback"` + DisableIVCheck bool `mapstructure:"DisableIVCheck"` + DisableSniffing bool `mapstructure:"DisableSniffing"` + AutoSpeedLimitConfig *AutoSpeedLimitConfig `mapstructure:"AutoSpeedLimitConfig"` + GlobalDeviceLimitConfig *limiter.GlobalDeviceLimitConfig `mapstructure:"GlobalDeviceLimitConfig"` + FallBackConfigs []*FallBackConfig `mapstructure:"FallBackConfigs"` + DisableLocalREALITYConfig bool `mapstructure:"DisableLocalREALITYConfig"` + EnableREALITY bool `mapstructure:"EnableREALITY"` + REALITYConfigs *REALITYConfig `mapstructure:"REALITYConfigs"` } type AutoSpeedLimitConfig struct { diff --git a/service/controller/inboundbuilder.go b/service/controller/inboundbuilder.go index c531fea..fcea7ef 100644 --- a/service/controller/inboundbuilder.go +++ b/service/controller/inboundbuilder.go @@ -185,15 +185,32 @@ func InboundBuilder(config *Config, nodeInfo *api.NodeInfo, tag string) (*core.I streamSetting.Network = &transportProtocol // Build TLS and REALITY settings - if config.EnableREALITY { - dest, err := json.Marshal(config.REALITYConfigs.Dest) - if err != nil { - return nil, fmt.Errorf("marshal dest %s config fialed: %s", dest, err) + var isREALITY bool + if config.DisableLocalREALITYConfig { + if nodeInfo.REALITYConfig != nil && nodeInfo.EnableREALITY { + isREALITY = true + streamSetting.Security = "reality" + + r := nodeInfo.REALITYConfig + streamSetting.REALITYSettings = &conf.REALITYConfig{ + Show: config.REALITYConfigs.Show, + Dest: []byte(`"` + r.Dest + `"`), + Xver: r.ProxyProtocolVer, + ServerNames: r.ServerNames, + PrivateKey: r.PrivateKey, + MinClientVer: r.MinClientVer, + MaxClientVer: r.MaxClientVer, + MaxTimeDiff: r.MaxTimeDiff, + ShortIds: r.ShortIds, + } } + } else if config.EnableREALITY && config.REALITYConfigs != nil { + isREALITY = true streamSetting.Security = "reality" + streamSetting.REALITYSettings = &conf.REALITYConfig{ Show: config.REALITYConfigs.Show, - Dest: dest, + Dest: []byte(`"` + config.REALITYConfigs.Dest + `"`), Xver: config.REALITYConfigs.ProxyProtocolVer, ServerNames: config.REALITYConfigs.ServerNames, PrivateKey: config.REALITYConfigs.PrivateKey, @@ -202,7 +219,9 @@ func InboundBuilder(config *Config, nodeInfo *api.NodeInfo, tag string) (*core.I MaxTimeDiff: config.REALITYConfigs.MaxTimeDiff, ShortIds: config.REALITYConfigs.ShortIds, } - } else if nodeInfo.EnableTLS && config.CertConfig.CertMode != "none" { + } + + if !isREALITY && nodeInfo.EnableTLS && config.CertConfig.CertMode != "none" { streamSetting.Security = "tls" certFile, keyFile, err := getCertFile(config.CertConfig) if err != nil { diff --git a/service/controller/inboundbuilder_test.go b/service/controller/inboundbuilder_test.go index a6bc372..a96bc3a 100644 --- a/service/controller/inboundbuilder_test.go +++ b/service/controller/inboundbuilder_test.go @@ -19,7 +19,6 @@ func TestBuildV2ray(t *testing.T) { Host: "test.test.tk", Path: "v2ray", EnableTLS: false, - TLSType: "tls", } certConfig := &mylego.CertConfig{ CertMode: "http", @@ -47,7 +46,6 @@ func TestBuildTrojan(t *testing.T) { Host: "trojan.test.tk", Path: "v2ray", EnableTLS: false, - TLSType: "tls", } DNSEnv := make(map[string]string) DNSEnv["ALICLOUD_ACCESS_KEY"] = "aaa" @@ -79,7 +77,6 @@ func TestBuildSS(t *testing.T) { Host: "test.test.tk", Path: "v2ray", EnableTLS: false, - TLSType: "tls", } DNSEnv := make(map[string]string) DNSEnv["ALICLOUD_ACCESS_KEY"] = "aaa"