mirror of
https://github.com/wyx2685/V2bX.git
synced 2025-02-02 06:48:14 -05:00
commit
9495913f26
@ -86,14 +86,14 @@ type V2rayExtraConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RealityConfig struct {
|
type RealityConfig struct {
|
||||||
Dest interface{} `yaml:"Dest" json:"Dest"`
|
Dest string `yaml:"Dest" json:"Dest"`
|
||||||
Xver string `yaml:"Xver" json:"Xver"`
|
Xver string `yaml:"Xver" json:"Xver"`
|
||||||
ServerNames []string `yaml:"ServerNames" json:"ServerNames"`
|
ServerNames []string `yaml:"ServerNames" json:"ServerNames"`
|
||||||
PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"`
|
PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"`
|
||||||
MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"`
|
MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"`
|
||||||
MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"`
|
MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"`
|
||||||
MaxTimeDiff string `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
|
MaxTimeDiff string `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
|
||||||
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
|
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSConfig struct {
|
type DNSConfig struct {
|
||||||
|
16
conf/cert.go
16
conf/cert.go
@ -13,12 +13,12 @@ type CertConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RealityConfig struct {
|
type RealityConfig struct {
|
||||||
Dest interface{} `yaml:"Dest" json:"Dest"`
|
Dest string `yaml:"Dest" json:"Dest"`
|
||||||
Xver uint64 `yaml:"Xver" json:"Xver"`
|
Xver uint64 `yaml:"Xver" json:"Xver"`
|
||||||
ServerNames []string `yaml:"ServerNames" json:"ServerNames"`
|
ServerNames []string `yaml:"ServerNames" json:"ServerNames"`
|
||||||
PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"`
|
PrivateKey string `yaml:"PrivateKey" json:"PrivateKey"`
|
||||||
MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"`
|
MinClientVer string `yaml:"MinClientVer" json:"MinClientVer"`
|
||||||
MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"`
|
MaxClientVer string `yaml:"MaxClientVer" json:"MaxClientVer"`
|
||||||
MaxTimeDiff uint64 `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
|
MaxTimeDiff uint64 `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
|
||||||
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
|
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,30 @@ type Options struct {
|
|||||||
CertConfig *CertConfig `yaml:"CertConfig"`
|
CertConfig *CertConfig `yaml:"CertConfig"`
|
||||||
XrayOptions XrayOptions `yaml:"XrayOptions"`
|
XrayOptions XrayOptions `yaml:"XrayOptions"`
|
||||||
HyOptions HyOptions `yaml:"HyOptions"`
|
HyOptions HyOptions `yaml:"HyOptions"`
|
||||||
|
SingOptions SingOptions `yaml:"SingOptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type XrayOptions struct {
|
type XrayOptions struct {
|
||||||
EnableProxyProtocol bool `yaml:"EnableProxyProtocol"`
|
EnableProxyProtocol bool `yaml:"EnableProxyProtocol"`
|
||||||
EnableDNS bool `yaml:"EnableDNS"`
|
EnableDNS bool `yaml:"EnableDNS"`
|
||||||
DNSType string `yaml:"DNSType"`
|
DNSType string `yaml:"DNSType"`
|
||||||
EnableUot bool `yaml:"EnableUot"`
|
EnableUot bool `yaml:"EnableUot"`
|
||||||
EnableTFO bool `yaml:"EnableTFO"`
|
EnableTFO bool `yaml:"EnableTFO"`
|
||||||
DisableIVCheck bool `yaml:"DisableIVCheck"`
|
DisableIVCheck bool `yaml:"DisableIVCheck"`
|
||||||
DisableSniffing bool `yaml:"DisableSniffing"`
|
DisableSniffing bool `yaml:"DisableSniffing"`
|
||||||
EnableFallback bool `yaml:"EnableFallback"`
|
EnableFallback bool `yaml:"EnableFallback"`
|
||||||
FallBackConfigs []FallBackConfig `yaml:"FallBackConfigs"`
|
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"`
|
SNI string `yaml:"SNI"`
|
||||||
Alpn string `yaml:"Alpn"`
|
Alpn string `yaml:"Alpn"`
|
||||||
Path string `yaml:"Path"`
|
Path string `yaml:"Path"`
|
||||||
@ -29,6 +38,16 @@ type FallBackConfig struct {
|
|||||||
ProxyProtocolVer uint64 `yaml:"ProxyProtocolVer"`
|
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 {
|
type HyOptions struct {
|
||||||
Resolver string `yaml:"Resolver"`
|
Resolver string `yaml:"Resolver"`
|
||||||
ResolvePreference string `yaml:"ResolvePreference"`
|
ResolvePreference string `yaml:"ResolvePreference"`
|
||||||
|
@ -5,10 +5,12 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/google/uuid"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/inazumav/sing-box/inbound"
|
"github.com/inazumav/sing-box/inbound"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
@ -30,15 +32,78 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
|
|||||||
return option.Inbound{}, fmt.Errorf("the listen ip not vail")
|
return option.Inbound{}, fmt.Errorf("the listen ip not vail")
|
||||||
}
|
}
|
||||||
listen := option.ListenOptions{
|
listen := option.ListenOptions{
|
||||||
//ProxyProtocol: true,
|
Listen: (*option.ListenAddress)(&addr),
|
||||||
Listen: (*option.ListenAddress)(&addr),
|
ListenPort: uint16(info.Port),
|
||||||
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{
|
var tls option.InboundTLSOptions
|
||||||
Enabled: info.Tls,
|
if info.Tls || info.Type == "hysteria" {
|
||||||
CertificatePath: c.CertConfig.CertFile,
|
if c.CertConfig == nil {
|
||||||
KeyPath: c.CertConfig.KeyFile,
|
return option.Inbound{}, fmt.Errorf("the CertConfig is not vail")
|
||||||
ServerName: info.ServerName,
|
}
|
||||||
|
tls.Enabled = true
|
||||||
|
tls.Insecure = true
|
||||||
|
tls.ServerName = info.ServerName
|
||||||
|
switch c.CertConfig.CertMode {
|
||||||
|
case "none", "":
|
||||||
|
break // disable
|
||||||
|
case "reality":
|
||||||
|
if c.CertConfig.RealityConfig == nil {
|
||||||
|
return option.Inbound{}, fmt.Errorf("RealityConfig is not valid")
|
||||||
|
}
|
||||||
|
rc := c.CertConfig.RealityConfig
|
||||||
|
tls.ServerName = rc.ServerNames[0]
|
||||||
|
if len(rc.ShortIds) == 0 {
|
||||||
|
rc.ShortIds = []string{""}
|
||||||
|
}
|
||||||
|
dest, _ := strconv.Atoi(rc.Dest)
|
||||||
|
mtd, _ := strconv.Atoi(strconv.FormatUint(rc.MaxTimeDiff, 10))
|
||||||
|
tls.Reality = &option.InboundRealityOptions{
|
||||||
|
Enabled: true,
|
||||||
|
ShortID: rc.ShortIds,
|
||||||
|
PrivateKey: rc.PrivateKey,
|
||||||
|
MaxTimeDifference: option.Duration(time.Duration(mtd) * time.Second),
|
||||||
|
Handshake: option.InboundRealityHandshakeOptions{
|
||||||
|
ServerOptions: option.ServerOptions{
|
||||||
|
Server: rc.ServerNames[0],
|
||||||
|
ServerPort: uint16(dest),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
case "remote":
|
||||||
|
if info.ExtraConfig.EnableReality == "true" {
|
||||||
|
if c.CertConfig.RealityConfig == nil {
|
||||||
|
return option.Inbound{}, fmt.Errorf("RealityConfig is not valid")
|
||||||
|
}
|
||||||
|
rc := info.ExtraConfig.RealityConfig
|
||||||
|
if len(rc.ShortIds) == 0 {
|
||||||
|
rc.ShortIds = []string{""}
|
||||||
|
}
|
||||||
|
dest, _ := strconv.Atoi(rc.Dest)
|
||||||
|
mtd, _ := strconv.Atoi(rc.MaxTimeDiff)
|
||||||
|
tls.Reality = &option.InboundRealityOptions{
|
||||||
|
Enabled: true,
|
||||||
|
ShortID: rc.ShortIds,
|
||||||
|
PrivateKey: rc.PrivateKey,
|
||||||
|
MaxTimeDifference: option.Duration(time.Duration(mtd) * time.Second),
|
||||||
|
Handshake: option.InboundRealityHandshakeOptions{
|
||||||
|
ServerOptions: option.ServerOptions{
|
||||||
|
Server: rc.ServerNames[0],
|
||||||
|
ServerPort: uint16(dest),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
tls.CertificatePath = c.CertConfig.CertFile
|
||||||
|
tls.KeyPath = c.CertConfig.KeyFile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
in := option.Inbound{
|
in := option.Inbound{
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
@ -121,6 +186,46 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
|
|||||||
in.ShadowsocksOptions.Users = []option.ShadowsocksUser{{
|
in.ShadowsocksOptions.Users = []option.ShadowsocksUser{{
|
||||||
Password: randomPasswd,
|
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
|
return in, nil
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,15 @@ func (b *Box) AddUsers(p *core.AddUsersParams) (added int, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = b.inbounds[p.Tag].(*inbound.ShadowsocksMulti).AddUsers(us)
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
19
core/sing/utils.go
Normal file
19
core/sing/utils.go
Normal file
@ -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
|
||||||
|
}
|
@ -274,7 +274,7 @@ func buildShadowsocks(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *c
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfig) ([]*coreConf.VLessInboundFallback, error) {
|
func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfigForXray) ([]*coreConf.VLessInboundFallback, error) {
|
||||||
if fallbackConfigs == nil {
|
if fallbackConfigs == nil {
|
||||||
return nil, fmt.Errorf("you must provide FallBackConfigs")
|
return nil, fmt.Errorf("you must provide FallBackConfigs")
|
||||||
}
|
}
|
||||||
@ -299,7 +299,7 @@ func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfig) ([]*coreConf.VLe
|
|||||||
return vlessFallBacks, nil
|
return vlessFallBacks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTrojanFallbacks(fallbackConfigs []conf.FallBackConfig) ([]*coreConf.TrojanInboundFallback, error) {
|
func buildTrojanFallbacks(fallbackConfigs []conf.FallBackConfigForXray) ([]*coreConf.TrojanInboundFallback, error) {
|
||||||
if fallbackConfigs == nil {
|
if fallbackConfigs == nil {
|
||||||
return nil, fmt.Errorf("you must provide FallBackConfigs")
|
return nil, fmt.Errorf("you must provide FallBackConfigs")
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,19 @@ Nodes:
|
|||||||
Path: # HTTP PATH, Empty for any
|
Path: # HTTP PATH, Empty for any
|
||||||
Dest: 80 # Required, Destination of fallback, check https://xtls.github.io/config/features/fallback.html for details.
|
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
|
ProxyProtocolVer: 0 # Send PROXY protocol version, 0 for disable
|
||||||
|
SingOptions:
|
||||||
|
EnableTFO: true
|
||||||
|
SniffEnabled: true
|
||||||
|
SniffOverrideDestination: true
|
||||||
|
EnableProxyProtocol: false
|
||||||
|
FallBackConfigs:
|
||||||
|
FallBack:
|
||||||
|
Server: 127.0.0.1
|
||||||
|
ServerPort: 8080
|
||||||
|
FallBackForALPN:
|
||||||
|
http/1.1:
|
||||||
|
Server: 127.0.0.1
|
||||||
|
ServerPort: 8081
|
||||||
HyOptions:
|
HyOptions:
|
||||||
Resolver: "udp://1.1.1.1:53" # DNS resolver address
|
Resolver: "udp://1.1.1.1:53" # DNS resolver address
|
||||||
ResolvePreference: 64 # DNS IPv4/IPv6 preference. Available options: "64" (IPv6 first, fallback to IPv4), "46" (IPv4 first, fallback to IPv6), "6" (IPv6 only), "4" (IPv4 only)
|
ResolvePreference: 64 # DNS IPv4/IPv6 preference. Available options: "64" (IPv6 first, fallback to IPv4), "46" (IPv4 first, fallback to IPv6), "6" (IPv6 only), "4" (IPv4 only)
|
||||||
|
Loading…
Reference in New Issue
Block a user