2023-07-12 13:44:15 -04:00
|
|
|
package xray
|
2022-06-01 13:35:41 -04:00
|
|
|
|
|
|
|
import (
|
2022-12-18 10:31:06 -05:00
|
|
|
"crypto/rand"
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/hex"
|
2023-06-02 10:55:53 -04:00
|
|
|
"errors"
|
2022-06-01 13:35:41 -04:00
|
|
|
"fmt"
|
2023-08-23 10:06:36 -04:00
|
|
|
"time"
|
|
|
|
|
2023-07-29 07:27:15 -04:00
|
|
|
"github.com/InazumaV/V2bX/api/panel"
|
|
|
|
"github.com/InazumaV/V2bX/conf"
|
2022-10-11 04:05:19 -04:00
|
|
|
"github.com/goccy/go-json"
|
2022-06-01 13:35:41 -04:00
|
|
|
"github.com/xtls/xray-core/common/net"
|
|
|
|
"github.com/xtls/xray-core/core"
|
2022-07-28 11:00:05 -04:00
|
|
|
coreConf "github.com/xtls/xray-core/infra/conf"
|
2022-06-01 13:35:41 -04:00
|
|
|
)
|
|
|
|
|
2023-05-21 22:36:10 -04:00
|
|
|
// BuildInbound build Inbound config for different protocol
|
2023-08-19 08:06:42 -04:00
|
|
|
func buildInbound(option *conf.Options, nodeInfo *panel.NodeInfo, tag string) (*core.InboundHandlerConfig, error) {
|
2023-05-22 09:01:31 -04:00
|
|
|
in := &coreConf.InboundDetourConfig{}
|
2022-12-18 10:31:06 -05:00
|
|
|
var err error
|
2023-08-19 08:06:42 -04:00
|
|
|
var network string
|
2023-06-08 10:46:33 -04:00
|
|
|
switch nodeInfo.Type {
|
2023-08-29 23:26:05 -04:00
|
|
|
case "vmess", "vless":
|
2023-08-19 08:06:42 -04:00
|
|
|
err = buildV2ray(option, nodeInfo, in)
|
|
|
|
network = nodeInfo.VAllss.Network
|
2023-05-18 23:27:08 -04:00
|
|
|
case "trojan":
|
2023-08-19 08:06:42 -04:00
|
|
|
err = buildTrojan(option, in)
|
2023-08-30 03:34:37 -04:00
|
|
|
network = "tcp"
|
2023-05-18 23:27:08 -04:00
|
|
|
case "shadowsocks":
|
2023-08-19 08:06:42 -04:00
|
|
|
err = buildShadowsocks(option, nodeInfo, in)
|
2023-08-30 03:34:37 -04:00
|
|
|
network = "tcp"
|
2022-12-18 10:31:06 -05:00
|
|
|
default:
|
2023-06-08 10:46:33 -04:00
|
|
|
return nil, fmt.Errorf("unsupported node type: %s, Only support: V2ray, Trojan, Shadowsocks", nodeInfo.Type)
|
2022-10-09 20:59:00 -04:00
|
|
|
}
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-08-19 08:06:42 -04:00
|
|
|
// Set network protocol
|
2022-12-18 10:31:06 -05:00
|
|
|
// Set server port
|
2023-05-22 09:01:31 -04:00
|
|
|
in.PortList = &coreConf.PortList{
|
2023-08-19 08:06:42 -04:00
|
|
|
Range: []coreConf.PortRange{
|
|
|
|
{
|
|
|
|
From: uint32(nodeInfo.Common.ServerPort),
|
|
|
|
To: uint32(nodeInfo.Common.ServerPort),
|
|
|
|
}},
|
2022-12-18 10:31:06 -05:00
|
|
|
}
|
|
|
|
// Set Listen IP address
|
2023-08-19 08:06:42 -04:00
|
|
|
ipAddress := net.ParseAddress(option.ListenIP)
|
2023-05-22 09:01:31 -04:00
|
|
|
in.ListenOn = &coreConf.Address{Address: ipAddress}
|
2022-12-18 10:31:06 -05:00
|
|
|
// Set SniffingConfig
|
2022-07-28 11:00:05 -04:00
|
|
|
sniffingConfig := &coreConf.SniffingConfig{
|
2022-06-01 13:35:41 -04:00
|
|
|
Enabled: true,
|
2022-07-28 11:00:05 -04:00
|
|
|
DestOverride: &coreConf.StringList{"http", "tls"},
|
2022-06-01 13:35:41 -04:00
|
|
|
}
|
2023-08-19 08:06:42 -04:00
|
|
|
if option.XrayOptions.DisableSniffing {
|
2022-06-01 13:35:41 -04:00
|
|
|
sniffingConfig.Enabled = false
|
|
|
|
}
|
2023-05-22 09:01:31 -04:00
|
|
|
in.SniffingConfig = sniffingConfig
|
2023-08-19 08:06:42 -04:00
|
|
|
switch network {
|
|
|
|
case "tcp":
|
2023-05-22 09:01:31 -04:00
|
|
|
if in.StreamSetting.TCPSettings != nil {
|
2023-08-19 08:06:42 -04:00
|
|
|
in.StreamSetting.TCPSettings.AcceptProxyProtocol = option.XrayOptions.EnableProxyProtocol
|
2022-06-02 13:22:56 -04:00
|
|
|
} else {
|
2022-07-28 11:00:05 -04:00
|
|
|
tcpSetting := &coreConf.TCPConfig{
|
2023-08-19 08:06:42 -04:00
|
|
|
AcceptProxyProtocol: option.XrayOptions.EnableProxyProtocol,
|
2022-10-09 20:59:00 -04:00
|
|
|
} //Enable proxy protocol
|
2023-05-22 09:01:31 -04:00
|
|
|
in.StreamSetting.TCPSettings = tcpSetting
|
2022-06-01 13:35:41 -04:00
|
|
|
}
|
2023-08-19 08:06:42 -04:00
|
|
|
case "ws":
|
2023-05-22 09:01:31 -04:00
|
|
|
in.StreamSetting.WSSettings = &coreConf.WebSocketConfig{
|
2023-08-19 08:06:42 -04:00
|
|
|
AcceptProxyProtocol: option.XrayOptions.EnableProxyProtocol} //Enable proxy protocol
|
|
|
|
default:
|
|
|
|
socketConfig := &coreConf.SocketConfig{
|
|
|
|
AcceptProxyProtocol: option.XrayOptions.EnableProxyProtocol,
|
|
|
|
TFO: option.XrayOptions.EnableTFO,
|
|
|
|
} //Enable proxy protocol
|
|
|
|
in.StreamSetting.SocketSettings = socketConfig
|
2022-06-01 13:35:41 -04:00
|
|
|
}
|
2023-06-02 10:55:53 -04:00
|
|
|
// Set TLS or Reality settings
|
2023-08-19 08:06:42 -04:00
|
|
|
switch nodeInfo.Security {
|
|
|
|
case panel.Tls:
|
|
|
|
// Normal tls
|
|
|
|
if option.CertConfig == nil {
|
2023-06-02 10:55:53 -04:00
|
|
|
return nil, errors.New("the CertConfig is not vail")
|
|
|
|
}
|
2023-08-19 08:06:42 -04:00
|
|
|
switch option.CertConfig.CertMode {
|
2023-07-20 04:52:46 -04:00
|
|
|
case "none", "":
|
|
|
|
break // disable
|
|
|
|
default:
|
2023-08-19 08:06:42 -04:00
|
|
|
in.StreamSetting.Security = "tls"
|
|
|
|
in.StreamSetting.TLSSettings = &coreConf.TLSConfig{
|
|
|
|
Certs: []*coreConf.TLSCertConfig{
|
|
|
|
{
|
|
|
|
CertFile: option.CertConfig.CertFile,
|
|
|
|
KeyFile: option.CertConfig.KeyFile,
|
|
|
|
OcspStapling: 3600,
|
2023-05-21 22:36:10 -04:00
|
|
|
},
|
2023-08-19 08:06:42 -04:00
|
|
|
},
|
|
|
|
RejectUnknownSNI: option.CertConfig.RejectUnknownSni,
|
2023-07-13 02:16:21 -04:00
|
|
|
}
|
2023-06-24 20:22:05 -04:00
|
|
|
}
|
2023-08-19 08:06:42 -04:00
|
|
|
case panel.Reality:
|
|
|
|
// Reality
|
|
|
|
in.StreamSetting.Security = "reality"
|
|
|
|
v := nodeInfo.VAllss
|
2023-08-30 04:08:27 -04:00
|
|
|
d, err := json.Marshal(fmt.Sprintf(
|
|
|
|
"%s:%s",
|
|
|
|
v.TlsSettings.ServerName,
|
|
|
|
v.TlsSettings.ServerPort))
|
2023-08-19 08:06:42 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("marshal reality dest error: %s", err)
|
|
|
|
}
|
2023-08-23 10:06:36 -04:00
|
|
|
mtd, _ := time.ParseDuration(v.RealityConfig.MaxTimeDiff)
|
2023-08-19 08:06:42 -04:00
|
|
|
in.StreamSetting.REALITYSettings = &coreConf.REALITYConfig{
|
|
|
|
Dest: d,
|
|
|
|
Xver: v.RealityConfig.Xver,
|
2023-08-23 10:06:36 -04:00
|
|
|
ServerNames: []string{v.TlsSettings.ServerName},
|
2023-08-19 08:06:42 -04:00
|
|
|
PrivateKey: v.TlsSettings.PrivateKey,
|
|
|
|
MinClientVer: v.RealityConfig.MinClientVer,
|
|
|
|
MaxClientVer: v.RealityConfig.MaxClientVer,
|
2023-08-23 10:06:36 -04:00
|
|
|
MaxTimeDiff: uint64(mtd.Microseconds()),
|
|
|
|
ShortIds: []string{v.TlsSettings.ShortId},
|
2023-08-19 08:06:42 -04:00
|
|
|
}
|
|
|
|
break
|
2022-12-18 10:31:06 -05:00
|
|
|
}
|
2023-05-22 09:01:31 -04:00
|
|
|
in.Tag = tag
|
|
|
|
return in.Build()
|
2022-12-18 10:31:06 -05:00
|
|
|
}
|
|
|
|
|
2023-07-29 06:47:47 -04:00
|
|
|
func buildV2ray(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error {
|
2023-08-19 08:06:42 -04:00
|
|
|
v := nodeInfo.VAllss
|
|
|
|
if nodeInfo.Type == "vless" {
|
2022-12-18 10:31:06 -05:00
|
|
|
//Set vless
|
|
|
|
inbound.Protocol = "vless"
|
2023-06-08 10:46:33 -04:00
|
|
|
if config.XrayOptions.EnableFallback {
|
2022-12-18 10:31:06 -05:00
|
|
|
// Set fallback
|
2023-06-08 10:46:33 -04:00
|
|
|
fallbackConfigs, err := buildVlessFallbacks(config.XrayOptions.FallBackConfigs)
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
s, err := json.Marshal(&coreConf.VLessInboundConfig{
|
|
|
|
Decryption: "none",
|
|
|
|
Fallbacks: fallbackConfigs,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("marshal vless fallback config error: %s", err)
|
|
|
|
}
|
|
|
|
inbound.Settings = (*json.RawMessage)(&s)
|
|
|
|
} else {
|
|
|
|
var err error
|
|
|
|
s, err := json.Marshal(&coreConf.VLessInboundConfig{
|
|
|
|
Decryption: "none",
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("marshal vless config error: %s", err)
|
|
|
|
}
|
|
|
|
inbound.Settings = (*json.RawMessage)(&s)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Set vmess
|
|
|
|
inbound.Protocol = "vmess"
|
|
|
|
var err error
|
|
|
|
s, err := json.Marshal(&coreConf.VMessInboundConfig{})
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("marshal vmess settings error: %s", err)
|
|
|
|
}
|
|
|
|
inbound.Settings = (*json.RawMessage)(&s)
|
|
|
|
}
|
2023-08-19 08:06:42 -04:00
|
|
|
if len(v.NetworkSettings) == 0 {
|
2023-05-21 22:36:10 -04:00
|
|
|
return nil
|
|
|
|
}
|
2023-08-30 03:48:40 -04:00
|
|
|
|
|
|
|
t := coreConf.TransportProtocol(nodeInfo.VAllss.Network)
|
|
|
|
inbound.StreamSetting = &coreConf.StreamConfig{Network: &t}
|
2023-08-19 08:06:42 -04:00
|
|
|
switch v.Network {
|
2022-12-18 10:31:06 -05:00
|
|
|
case "tcp":
|
2023-08-19 08:06:42 -04:00
|
|
|
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.TCPSettings)
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unmarshal tcp settings error: %s", err)
|
|
|
|
}
|
|
|
|
case "ws":
|
2023-08-19 08:06:42 -04:00
|
|
|
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.WSSettings)
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unmarshal ws settings error: %s", err)
|
|
|
|
}
|
|
|
|
case "grpc":
|
2023-08-19 08:06:42 -04:00
|
|
|
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.GRPCConfig)
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unmarshal grpc settings error: %s", err)
|
|
|
|
}
|
2023-07-13 02:16:21 -04:00
|
|
|
default:
|
|
|
|
return errors.New("the network type is not vail")
|
2022-12-18 10:31:06 -05:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-29 06:47:47 -04:00
|
|
|
func buildTrojan(config *conf.Options, inbound *coreConf.InboundDetourConfig) error {
|
2022-12-18 10:31:06 -05:00
|
|
|
inbound.Protocol = "trojan"
|
2023-06-08 10:46:33 -04:00
|
|
|
if config.XrayOptions.EnableFallback {
|
2022-12-18 10:31:06 -05:00
|
|
|
// Set fallback
|
2023-06-08 10:46:33 -04:00
|
|
|
fallbackConfigs, err := buildTrojanFallbacks(config.XrayOptions.FallBackConfigs)
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
s, err := json.Marshal(&coreConf.TrojanServerConfig{
|
|
|
|
Fallbacks: fallbackConfigs,
|
|
|
|
})
|
|
|
|
inbound.Settings = (*json.RawMessage)(&s)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("marshal trojan fallback config error: %s", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
s := []byte("{}")
|
|
|
|
inbound.Settings = (*json.RawMessage)(&s)
|
2022-06-01 13:35:41 -04:00
|
|
|
}
|
2023-06-09 00:36:49 -04:00
|
|
|
t := coreConf.TransportProtocol("tcp")
|
2022-12-18 10:31:06 -05:00
|
|
|
inbound.StreamSetting = &coreConf.StreamConfig{Network: &t}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-29 06:47:47 -04:00
|
|
|
func buildShadowsocks(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreConf.InboundDetourConfig) error {
|
2022-12-18 10:31:06 -05:00
|
|
|
inbound.Protocol = "shadowsocks"
|
2023-08-19 08:06:42 -04:00
|
|
|
s := nodeInfo.Shadowsocks
|
2022-12-18 10:31:06 -05:00
|
|
|
settings := &coreConf.ShadowsocksServerConfig{
|
2023-08-19 08:06:42 -04:00
|
|
|
Cipher: s.Cipher,
|
2022-12-18 10:31:06 -05:00
|
|
|
}
|
|
|
|
p := make([]byte, 32)
|
|
|
|
_, err := rand.Read(p)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("generate random password error: %s", err)
|
|
|
|
}
|
|
|
|
randomPasswd := hex.EncodeToString(p)
|
2023-08-19 08:06:42 -04:00
|
|
|
cipher := s.Cipher
|
|
|
|
if s.ServerKey != "" {
|
|
|
|
settings.Password = s.ServerKey
|
2022-12-18 10:31:06 -05:00
|
|
|
randomPasswd = base64.StdEncoding.EncodeToString([]byte(randomPasswd))
|
|
|
|
cipher = ""
|
|
|
|
}
|
|
|
|
defaultSSuser := &coreConf.ShadowsocksUserConfig{
|
|
|
|
Cipher: cipher,
|
|
|
|
Password: randomPasswd,
|
|
|
|
}
|
|
|
|
settings.Users = append(settings.Users, defaultSSuser)
|
|
|
|
settings.NetworkList = &coreConf.NetworkList{"tcp", "udp"}
|
|
|
|
settings.IVCheck = true
|
2023-06-08 10:46:33 -04:00
|
|
|
if config.XrayOptions.DisableIVCheck {
|
2022-12-18 10:31:06 -05:00
|
|
|
settings.IVCheck = false
|
|
|
|
}
|
|
|
|
t := coreConf.TransportProtocol("tcp")
|
|
|
|
inbound.StreamSetting = &coreConf.StreamConfig{Network: &t}
|
2023-08-19 08:06:42 -04:00
|
|
|
sets, err := json.Marshal(settings)
|
|
|
|
inbound.Settings = (*json.RawMessage)(&sets)
|
2022-12-18 10:31:06 -05:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("marshal shadowsocks settings error: %s", err)
|
|
|
|
}
|
|
|
|
return nil
|
2022-06-01 13:35:41 -04:00
|
|
|
}
|
|
|
|
|
2023-08-07 00:23:34 -04:00
|
|
|
func buildVlessFallbacks(fallbackConfigs []conf.FallBackConfigForXray) ([]*coreConf.VLessInboundFallback, error) {
|
2022-06-01 13:35:41 -04:00
|
|
|
if fallbackConfigs == nil {
|
|
|
|
return nil, fmt.Errorf("you must provide FallBackConfigs")
|
|
|
|
}
|
2022-07-28 11:00:05 -04:00
|
|
|
vlessFallBacks := make([]*coreConf.VLessInboundFallback, len(fallbackConfigs))
|
2022-06-01 13:35:41 -04:00
|
|
|
for i, c := range fallbackConfigs {
|
|
|
|
if c.Dest == "" {
|
|
|
|
return nil, fmt.Errorf("dest is required for fallback fialed")
|
|
|
|
}
|
|
|
|
var dest json.RawMessage
|
|
|
|
dest, err := json.Marshal(c.Dest)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("marshal dest %s config fialed: %s", dest, err)
|
|
|
|
}
|
2022-07-28 11:00:05 -04:00
|
|
|
vlessFallBacks[i] = &coreConf.VLessInboundFallback{
|
2022-06-01 13:35:41 -04:00
|
|
|
Name: c.SNI,
|
|
|
|
Alpn: c.Alpn,
|
|
|
|
Path: c.Path,
|
|
|
|
Dest: dest,
|
|
|
|
Xver: c.ProxyProtocolVer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return vlessFallBacks, nil
|
|
|
|
}
|
|
|
|
|
2023-08-07 00:23:34 -04:00
|
|
|
func buildTrojanFallbacks(fallbackConfigs []conf.FallBackConfigForXray) ([]*coreConf.TrojanInboundFallback, error) {
|
2022-06-01 13:35:41 -04:00
|
|
|
if fallbackConfigs == nil {
|
|
|
|
return nil, fmt.Errorf("you must provide FallBackConfigs")
|
|
|
|
}
|
|
|
|
|
2022-07-28 11:00:05 -04:00
|
|
|
trojanFallBacks := make([]*coreConf.TrojanInboundFallback, len(fallbackConfigs))
|
2022-06-01 13:35:41 -04:00
|
|
|
for i, c := range fallbackConfigs {
|
|
|
|
|
|
|
|
if c.Dest == "" {
|
|
|
|
return nil, fmt.Errorf("dest is required for fallback fialed")
|
|
|
|
}
|
|
|
|
|
|
|
|
var dest json.RawMessage
|
|
|
|
dest, err := json.Marshal(c.Dest)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("marshal dest %s config fialed: %s", dest, err)
|
|
|
|
}
|
2022-07-28 11:00:05 -04:00
|
|
|
trojanFallBacks[i] = &coreConf.TrojanInboundFallback{
|
2022-06-01 13:35:41 -04:00
|
|
|
Name: c.SNI,
|
|
|
|
Alpn: c.Alpn,
|
|
|
|
Path: c.Path,
|
|
|
|
Dest: dest,
|
|
|
|
Xver: c.ProxyProtocolVer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return trojanFallBacks, nil
|
|
|
|
}
|