diff --git a/conf/option.go b/conf/option.go index 7073f25..5e0a9fc 100644 --- a/conf/option.go +++ b/conf/option.go @@ -7,21 +7,30 @@ type Options struct { CertConfig *CertConfig `yaml:"CertConfig"` XrayOptions XrayOptions `yaml:"XrayOptions"` HyOptions HyOptions `yaml:"HyOptions"` + SingOptions SingOptions `yaml:"SingOptions"` } type XrayOptions struct { - EnableProxyProtocol bool `yaml:"EnableProxyProtocol"` - EnableDNS bool `yaml:"EnableDNS"` - DNSType string `yaml:"DNSType"` - EnableUot bool `yaml:"EnableUot"` - EnableTFO bool `yaml:"EnableTFO"` - DisableIVCheck bool `yaml:"DisableIVCheck"` - DisableSniffing bool `yaml:"DisableSniffing"` - EnableFallback bool `yaml:"EnableFallback"` - FallBackConfigs []FallBackConfig `yaml:"FallBackConfigs"` + EnableProxyProtocol bool `yaml:"EnableProxyProtocol"` + EnableDNS bool `yaml:"EnableDNS"` + DNSType string `yaml:"DNSType"` + EnableUot bool `yaml:"EnableUot"` + EnableTFO bool `yaml:"EnableTFO"` + DisableIVCheck bool `yaml:"DisableIVCheck"` + DisableSniffing bool `yaml:"DisableSniffing"` + EnableFallback bool `yaml:"EnableFallback"` + FallBackConfigs []FallBackConfigForXray `yaml:"FallBackConfigs"` } -type FallBackConfig struct { +type SingOptions struct { + EnableProxyProtocol bool `yaml:"EnableProxyProtocol"` + TCPFastOpen bool `yaml:"EnableTFO"` + SniffEnabled bool `yaml:"EnableSniff"` + SniffOverrideDestination bool `yaml:"SniffOverrideDestination"` + FallBackConfigs *FallBackConfigForSing `yaml:"FallBackConfigs"` +} + +type FallBackConfigForXray struct { SNI string `yaml:"SNI"` Alpn string `yaml:"Alpn"` Path string `yaml:"Path"` @@ -29,6 +38,16 @@ type FallBackConfig struct { ProxyProtocolVer uint64 `yaml:"ProxyProtocolVer"` } +type FallBackConfigForSing struct { + // sing-box + FallBack FallBack `yaml:"FallBack"` + FallBackForALPN map[string]FallBack `yaml:"FallBackForALPN"` +} +type FallBack struct { + Server string `yaml:"Server"` + ServerPort string `yaml:"ServerPort"` +} + type HyOptions struct { Resolver string `yaml:"Resolver"` ResolvePreference string `yaml:"ResolvePreference"` diff --git a/core/sing/node.go b/core/sing/node.go index e6f202f..51cba83 100644 --- a/core/sing/node.go +++ b/core/sing/node.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/base64" "fmt" + "github.com/google/uuid" "net/netip" "net/url" "strconv" @@ -30,9 +31,14 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio return option.Inbound{}, fmt.Errorf("the listen ip not vail") } listen := option.ListenOptions{ - //ProxyProtocol: true, - Listen: (*option.ListenAddress)(&addr), - ListenPort: uint16(info.Port), + Listen: (*option.ListenAddress)(&addr), + ListenPort: uint16(info.Port), + ProxyProtocol: c.SingOptions.EnableProxyProtocol, + TCPFastOpen: c.SingOptions.TCPFastOpen, + InboundOptions: option.InboundOptions{ + SniffEnabled: c.SingOptions.SniffEnabled, + SniffOverrideDestination: c.SingOptions.SniffOverrideDestination, + }, } tls := option.InboundTLSOptions{ Enabled: info.Tls, @@ -121,6 +127,46 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio in.ShadowsocksOptions.Users = []option.ShadowsocksUser{{ Password: randomPasswd, }} + case "trojan": + in.Type = "trojan" + t := option.V2RayTransportOptions{ + Type: info.Network, + } + switch info.Network { + case "tcp": + t.Type = "" + case "grpc": + err := json.Unmarshal(info.NetworkSettings, &t.GRPCOptions) + if err != nil { + return option.Inbound{}, fmt.Errorf("decode NetworkSettings error: %s", err) + } + } + randomPasswd := uuid.New().String() + in.TrojanOptions = option.TrojanInboundOptions{ + ListenOptions: listen, + Users: []option.TrojanUser{{ + Name: randomPasswd, + Password: randomPasswd, + }}, + TLS: &tls, + Transport: &t, + } + if c.SingOptions.FallBackConfigs != nil { + // fallback handling + fallback := c.SingOptions.FallBackConfigs.FallBack + fallbackPort, err := strconv.Atoi(fallback.ServerPort) + if err == nil { + in.TrojanOptions.Fallback = &option.ServerOptions{ + Server: fallback.Server, + ServerPort: uint16(fallbackPort), + } + } + fallbackForALPNMap := c.SingOptions.FallBackConfigs.FallBackForALPN + fallbackForALPN := make(map[string]*option.ServerOptions, len(fallbackForALPNMap)) + if err := processFallback(c, fallbackForALPN); err == nil { + in.TrojanOptions.FallbackForALPN = fallbackForALPN + } + } } return in, nil } diff --git a/core/sing/user.go b/core/sing/user.go index 775f720..ee7f1cb 100644 --- a/core/sing/user.go +++ b/core/sing/user.go @@ -50,6 +50,15 @@ func (b *Box) AddUsers(p *core.AddUsersParams) (added int, err error) { } } err = b.inbounds[p.Tag].(*inbound.ShadowsocksMulti).AddUsers(us) + case "trojan": + us := make([]option.TrojanUser, len(p.UserInfo)) + for i := range p.UserInfo { + us[i] = option.TrojanUser{ + Name: p.UserInfo[i].Uuid, + Password: p.UserInfo[i].Uuid, + } + } + err = b.inbounds[p.Tag].(*inbound.Trojan).AddUsers(us) } if err != nil { return 0, err diff --git a/core/sing/utils.go b/core/sing/utils.go new file mode 100644 index 0000000..2db7ebf --- /dev/null +++ b/core/sing/utils.go @@ -0,0 +1,19 @@ +package sing + +import ( + "fmt" + "github.com/InazumaV/V2bX/conf" + "github.com/inazumav/sing-box/option" + "strconv" +) + +func processFallback(c *conf.Options, fallbackForALPN map[string]*option.ServerOptions) error { + for k, v := range c.SingOptions.FallBackConfigs.FallBackForALPN { + fallbackPort, err := strconv.Atoi(v.ServerPort) + if err != nil { + return fmt.Errorf("unable to parse fallbackForALPN server port error: %s", err) + } + fallbackForALPN[k] = &option.ServerOptions{Server: v.Server, ServerPort: uint16(fallbackPort)} + } + return nil +} diff --git a/core/xray/inbound.go b/core/xray/inbound.go index fb2ae4d..44320bb 100644 --- a/core/xray/inbound.go +++ b/core/xray/inbound.go @@ -274,7 +274,7 @@ func buildShadowsocks(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *c return nil } -func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfig) ([]*coreConf.VLessInboundFallback, error) { +func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfigForXray) ([]*coreConf.VLessInboundFallback, error) { if fallbackConfigs == nil { return nil, fmt.Errorf("you must provide FallBackConfigs") } @@ -299,7 +299,7 @@ func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfig) ([]*coreConf.VLe return vlessFallBacks, nil } -func buildTrojanFallbacks(fallbackConfigs []conf.FallBackConfig) ([]*coreConf.TrojanInboundFallback, error) { +func buildTrojanFallbacks(fallbackConfigs []conf.FallBackConfigForXray) ([]*coreConf.TrojanInboundFallback, error) { if fallbackConfigs == nil { return nil, fmt.Errorf("you must provide FallBackConfigs") }