mirror of
https://github.com/wyx2685/V2bX.git
synced 2025-02-02 06:48:14 -05:00
commit
99ad3a3f13
@ -1,8 +1,12 @@
|
|||||||
package panel
|
package panel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
coreConf "github.com/xtls/xray-core/infra/conf"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -72,20 +76,20 @@ type NodeInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type V2rayExtraConfig struct {
|
type V2rayExtraConfig struct {
|
||||||
EnableVless bool `json:"EnableVless"`
|
EnableVless string `json:"EnableVless"`
|
||||||
VlessFlow string `json:"VlessFlow"`
|
VlessFlow string `json:"VlessFlow"`
|
||||||
EnableReality bool `json:"EnableReality"`
|
EnableReality string `json:"EnableReality"`
|
||||||
RealityConfig *RealityConfig `json:"RealityConfig"`
|
RealityConfig *RealityConfig `json:"RealityConfig"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RealityConfig struct {
|
type RealityConfig struct {
|
||||||
Dest interface{} `yaml:"Dest" json:"Dest"`
|
Dest interface{} `yaml:"Dest" json:"Dest"`
|
||||||
Xver uint64 `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 uint64 `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
|
MaxTimeDiff string `yaml:"MaxTimeDiff" json:"MaxTimeDiff"`
|
||||||
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
|
ShortIds []string `yaml:"ShortIds" json:"ShortIds"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +134,36 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) {
|
|||||||
node.Rules = append(node.Rules, regexp.MustCompile(v))
|
node.Rules = append(node.Rules, regexp.MustCompile(v))
|
||||||
}
|
}
|
||||||
case "dns":
|
case "dns":
|
||||||
|
if matchs[0] != "main" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dnsPath := os.Getenv("XRAY_DNS_PATH")
|
||||||
|
if dnsPath == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dns := []byte(strings.Join(matchs[1:], ""))
|
||||||
|
currentData, err := os.ReadFile(dnsPath)
|
||||||
|
if err != nil {
|
||||||
|
log.WithField("err", err).Panic("Failed to read XRAY_DNS_PATH")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !bytes.Equal(currentData, dns) {
|
||||||
|
coreDnsConfig := &coreConf.DNSConfig{}
|
||||||
|
if err = json.NewDecoder(bytes.NewReader(dns)).Decode(coreDnsConfig); err != nil {
|
||||||
|
log.WithField("err", err).Panic("Failed to unmarshal DNS config")
|
||||||
|
}
|
||||||
|
_, err := coreDnsConfig.Build()
|
||||||
|
if err != nil {
|
||||||
|
log.WithField("err", err).Panic("Failed to understand DNS config, Please check: https://xtls.github.io/config/dns.html for help")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err = os.Truncate(dnsPath, 0); err != nil {
|
||||||
|
log.WithField("err", err).Panic("Failed to clear XRAY DNS PATH file")
|
||||||
|
}
|
||||||
|
if err = os.WriteFile(dnsPath, dns, 0644); err != nil {
|
||||||
|
log.WithField("err", err).Panic("Failed to write DNS to XRAY DNS PATH file")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.ServerName = common.ServerName
|
node.ServerName = common.ServerName
|
||||||
@ -155,9 +189,9 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("decode v2ray extra error: %s", err)
|
return nil, fmt.Errorf("decode v2ray extra error: %s", err)
|
||||||
}
|
}
|
||||||
if node.ExtraConfig.EnableReality {
|
if node.ExtraConfig.EnableReality == "true" {
|
||||||
if node.ExtraConfig.RealityConfig == nil {
|
if node.ExtraConfig.RealityConfig == nil {
|
||||||
node.ExtraConfig.EnableReality = false
|
node.ExtraConfig.EnableReality = "false"
|
||||||
} else {
|
} else {
|
||||||
key := crypt.GenX25519Private([]byte(strconv.Itoa(c.NodeId) + c.NodeType + c.Token +
|
key := crypt.GenX25519Private([]byte(strconv.Itoa(c.NodeId) + c.NodeType + c.Token +
|
||||||
node.ExtraConfig.RealityConfig.PrivateKey))
|
node.ExtraConfig.RealityConfig.PrivateKey))
|
||||||
@ -173,6 +207,7 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) {
|
|||||||
node.ServerKey = rsp.ServerKey
|
node.ServerKey = rsp.ServerKey
|
||||||
node.Cipher = rsp.Cipher
|
node.Cipher = rsp.Cipher
|
||||||
case "trojan":
|
case "trojan":
|
||||||
|
node.Tls = true
|
||||||
case "hysteria":
|
case "hysteria":
|
||||||
rsp := HysteriaNodeRsp{}
|
rsp := HysteriaNodeRsp{}
|
||||||
err = json.Unmarshal(r.Body(), &rsp)
|
err = json.Unmarshal(r.Body(), &rsp)
|
||||||
|
@ -64,8 +64,9 @@ func serverHandle(_ *cobra.Command, _ []string) {
|
|||||||
log.WithField("err", err).Error("Run nodes failed")
|
log.WithField("err", err).Error("Run nodes failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
dns := os.Getenv("XRAY_DNS_PATH")
|
||||||
if watch {
|
if watch {
|
||||||
err = c.Watch(config, func() {
|
err = c.Watch(config, dns, func() {
|
||||||
nodes.Close()
|
nodes.Close()
|
||||||
err = vc.Close()
|
err = vc.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
12
conf/node.go
12
conf/node.go
@ -23,6 +23,17 @@ type ControllerConfig struct {
|
|||||||
CertConfig *CertConfig `yaml:"CertConfig"`
|
CertConfig *CertConfig `yaml:"CertConfig"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
type XrayOptions struct {
|
type XrayOptions struct {
|
||||||
EnableProxyProtocol bool `yaml:"EnableProxyProtocol"`
|
EnableProxyProtocol bool `yaml:"EnableProxyProtocol"`
|
||||||
EnableDNS bool `yaml:"EnableDNS"`
|
EnableDNS bool `yaml:"EnableDNS"`
|
||||||
@ -97,4 +108,5 @@ type CertConfig struct {
|
|||||||
Provider string `yaml:"Provider"` // alidns, cloudflare, gandi, godaddy....
|
Provider string `yaml:"Provider"` // alidns, cloudflare, gandi, godaddy....
|
||||||
Email string `yaml:"Email"`
|
Email string `yaml:"Email"`
|
||||||
DNSEnv map[string]string `yaml:"DNSEnv"`
|
DNSEnv map[string]string `yaml:"DNSEnv"`
|
||||||
|
RealityConfig *RealityConfig `yaml:"RealityConfig"`
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Conf) Watch(filePath string, reload func()) error {
|
func (p *Conf) Watch(filePath, dnsPath string, reload func()) error {
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("new watcher error: %s", err)
|
return fmt.Errorf("new watcher error: %s", err)
|
||||||
@ -28,7 +28,11 @@ func (p *Conf) Watch(filePath string, reload func()) error {
|
|||||||
pre = time.Now()
|
pre = time.Now()
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
log.Println("config dir changed, reloading...")
|
if e.Name == dnsPath {
|
||||||
|
log.Println("DNS file changed, reloading...")
|
||||||
|
} else {
|
||||||
|
log.Println("config dir changed, reloading...")
|
||||||
|
}
|
||||||
*p = *New()
|
*p = *New()
|
||||||
err := p.LoadFromPath(filePath)
|
err := p.LoadFromPath(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -48,5 +52,11 @@ func (p *Conf) Watch(filePath string, reload func()) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("watch file error: %s", err)
|
return fmt.Errorf("watch file error: %s", err)
|
||||||
}
|
}
|
||||||
|
if dnsPath != "" {
|
||||||
|
err = watcher.Add(path.Dir(dnsPath))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("watch dns file error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/Yuzuki616/V2bX/api/panel"
|
"github.com/Yuzuki616/V2bX/api/panel"
|
||||||
"github.com/Yuzuki616/V2bX/conf"
|
"github.com/Yuzuki616/V2bX/conf"
|
||||||
@ -70,26 +71,50 @@ func buildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s
|
|||||||
return nil, errors.New("the CertConfig is not vail")
|
return nil, errors.New("the CertConfig is not vail")
|
||||||
}
|
}
|
||||||
switch config.CertConfig.CertMode {
|
switch config.CertConfig.CertMode {
|
||||||
case "none", "": // disable
|
case "none", "":
|
||||||
default:
|
break // disable
|
||||||
if nodeInfo.ExtraConfig.EnableReality {
|
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,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "remote":
|
||||||
|
if nodeInfo.ExtraConfig.EnableReality == "true" {
|
||||||
rc := nodeInfo.ExtraConfig.RealityConfig
|
rc := nodeInfo.ExtraConfig.RealityConfig
|
||||||
in.StreamSetting.Security = "reality"
|
in.StreamSetting.Security = "reality"
|
||||||
d, err := json.Marshal(rc.Dest)
|
d, err := json.Marshal(rc.Dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("marshal reality dest error: %s", err)
|
return nil, fmt.Errorf("marshal reality dest error: %s", err)
|
||||||
}
|
}
|
||||||
|
Xver, _ := strconv.ParseUint(rc.Xver, 10, 64)
|
||||||
|
MaxTimeDiff, _ := strconv.ParseUint(rc.Xver, 10, 64)
|
||||||
in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{
|
in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{
|
||||||
Dest: d,
|
Dest: d,
|
||||||
Xver: rc.Xver,
|
Xver: Xver,
|
||||||
ServerNames: rc.ServerNames,
|
ServerNames: rc.ServerNames,
|
||||||
PrivateKey: rc.PrivateKey,
|
PrivateKey: rc.PrivateKey,
|
||||||
MinClientVer: rc.MinClientVer,
|
MinClientVer: rc.MinClientVer,
|
||||||
MaxClientVer: rc.MaxClientVer,
|
MaxClientVer: rc.MaxClientVer,
|
||||||
MaxTimeDiff: rc.MaxTimeDiff,
|
MaxTimeDiff: MaxTimeDiff,
|
||||||
ShortIds: rc.ShortIds,
|
ShortIds: rc.ShortIds,
|
||||||
}
|
}
|
||||||
} else {
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
// Normal tls
|
// Normal tls
|
||||||
in.StreamSetting.Security = "tls"
|
in.StreamSetting.Security = "tls"
|
||||||
in.StreamSetting.TLSSettings = &coreConf.TLSConfig{
|
in.StreamSetting.TLSSettings = &coreConf.TLSConfig{
|
||||||
@ -120,7 +145,7 @@ func buildInbound(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, tag s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildV2ray(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error {
|
func buildV2ray(config *conf.ControllerConfig, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error {
|
||||||
if nodeInfo.ExtraConfig.EnableVless {
|
if nodeInfo.ExtraConfig.EnableVless == "true" {
|
||||||
//Set vless
|
//Set vless
|
||||||
inbound.Protocol = "vless"
|
inbound.Protocol = "vless"
|
||||||
if config.XrayOptions.EnableFallback {
|
if config.XrayOptions.EnableFallback {
|
||||||
|
@ -74,7 +74,7 @@ func (c *Core) AddUsers(p *vCore.AddUsersParams) (added int, err error) {
|
|||||||
users := make([]*protocol.User, 0, len(p.UserInfo))
|
users := make([]*protocol.User, 0, len(p.UserInfo))
|
||||||
switch p.NodeInfo.Type {
|
switch p.NodeInfo.Type {
|
||||||
case "v2ray":
|
case "v2ray":
|
||||||
if p.NodeInfo.ExtraConfig.EnableVless {
|
if p.NodeInfo.ExtraConfig.EnableVless == "true" {
|
||||||
users = buildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow)
|
users = buildVlessUsers(p.Tag, p.UserInfo, p.NodeInfo.ExtraConfig.VlessFlow)
|
||||||
} else {
|
} else {
|
||||||
users = buildVmessUsers(p.Tag, p.UserInfo)
|
users = buildVmessUsers(p.Tag, p.UserInfo)
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package xray
|
package xray
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/Yuzuki616/V2bX/conf"
|
"github.com/Yuzuki616/V2bX/conf"
|
||||||
vCore "github.com/Yuzuki616/V2bX/core"
|
vCore "github.com/Yuzuki616/V2bX/core"
|
||||||
"github.com/Yuzuki616/V2bX/core/xray/app/dispatcher"
|
"github.com/Yuzuki616/V2bX/core/xray/app/dispatcher"
|
||||||
@ -19,6 +16,8 @@ import (
|
|||||||
"github.com/xtls/xray-core/features/routing"
|
"github.com/xtls/xray-core/features/routing"
|
||||||
statsFeature "github.com/xtls/xray-core/features/stats"
|
statsFeature "github.com/xtls/xray-core/features/stats"
|
||||||
coreConf "github.com/xtls/xray-core/infra/conf"
|
coreConf "github.com/xtls/xray-core/infra/conf"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -61,6 +60,7 @@ func getCore(c *conf.XrayConfig) *core.Instance {
|
|||||||
coreLogConfig.ErrorLog = c.LogConfig.ErrorPath
|
coreLogConfig.ErrorLog = c.LogConfig.ErrorPath
|
||||||
// DNS config
|
// DNS config
|
||||||
coreDnsConfig := &coreConf.DNSConfig{}
|
coreDnsConfig := &coreConf.DNSConfig{}
|
||||||
|
os.Setenv("XRAY_DNS_PATH", "")
|
||||||
if c.DnsConfigPath != "" {
|
if c.DnsConfigPath != "" {
|
||||||
if f, err := os.Open(c.DnsConfigPath); err != nil {
|
if f, err := os.Open(c.DnsConfigPath); err != nil {
|
||||||
log.WithField("err", err).Panic("Failed to read DNS config file")
|
log.WithField("err", err).Panic("Failed to read DNS config file")
|
||||||
@ -69,6 +69,7 @@ func getCore(c *conf.XrayConfig) *core.Instance {
|
|||||||
log.WithField("err", err).Panic("Failed to unmarshal DNS config")
|
log.WithField("err", err).Panic("Failed to unmarshal DNS config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
os.Setenv("XRAY_DNS_PATH", c.DnsConfigPath)
|
||||||
}
|
}
|
||||||
dnsConfig, err := coreDnsConfig.Build()
|
dnsConfig, err := coreDnsConfig.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -30,8 +30,6 @@ Nodes:
|
|||||||
EnableDNS: false # Use custom DNS config, Please ensure that you set the dns.json well
|
EnableDNS: false # Use custom DNS config, Please ensure that you set the dns.json well
|
||||||
DNSType: AsIs # AsIs, UseIP, UseIPv4, UseIPv6, DNS strategy
|
DNSType: AsIs # AsIs, UseIP, UseIPv4, UseIPv6, DNS strategy
|
||||||
EnableTFO: false # Enable TCP Fast Open
|
EnableTFO: false # Enable TCP Fast Open
|
||||||
EnableVless: false # Enable Vless for V2ray Type
|
|
||||||
VlessFlow: "xtls-rprx-vision" # flow for vless, "xtls-rprx-vision" or "none" or ""
|
|
||||||
EnableProxyProtocol: false # Only works for WebSocket and TCP
|
EnableProxyProtocol: false # Only works for WebSocket and TCP
|
||||||
EnableFallback: false # Only support for Trojan and Vless
|
EnableFallback: false # Only support for Trojan and Vless
|
||||||
FallBackConfigs: # Support multiple fallbacks
|
FallBackConfigs: # Support multiple fallbacks
|
||||||
@ -70,7 +68,7 @@ Nodes:
|
|||||||
SpeedLimit: 0 # Speed limit, Mbps
|
SpeedLimit: 0 # Speed limit, Mbps
|
||||||
ExpireTime: 0 # Time limit, sec.
|
ExpireTime: 0 # Time limit, sec.
|
||||||
CertConfig:
|
CertConfig:
|
||||||
CertMode: dns # Option about how to get certificate: none, file, http, dns, reality. Choose "none" will forcedly disable the tls config.
|
CertMode: dns # Option about how to get certificate: none, file, http, dns, reality, remote. Choose "none" will forcedly disable the tls config.
|
||||||
CertDomain: "node1.test.com" # Domain to cert
|
CertDomain: "node1.test.com" # Domain to cert
|
||||||
CertFile: /etc/XrayR/cert/node1.test.com.cert # Provided if the CertMode is file
|
CertFile: /etc/XrayR/cert/node1.test.com.cert # Provided if the CertMode is file
|
||||||
KeyFile: /etc/XrayR/cert/node1.test.com.key
|
KeyFile: /etc/XrayR/cert/node1.test.com.key
|
||||||
|
Loading…
Reference in New Issue
Block a user