mirror of
https://github.com/XrayR-project/XrayR.git
synced 2025-06-08 13:29:54 +00:00

The commit increases the version number from 0.9.1 to 0.9.2 in version.go. Additionally, an error check has been added in x25519.go to validate the private key size. Also, panel.go has been modified to accept both "NewV2board" and "V2board" as valid panel types.
252 lines
7.8 KiB
Go
252 lines
7.8 KiB
Go
package panel
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
"sync"
|
|
|
|
"github.com/XrayR-project/XrayR/api/gov2panel"
|
|
"github.com/XrayR-project/XrayR/api/newV2board"
|
|
"github.com/XrayR-project/XrayR/app/mydispatcher"
|
|
|
|
"dario.cat/mergo"
|
|
"github.com/r3labs/diff/v2"
|
|
"github.com/xtls/xray-core/app/proxyman"
|
|
"github.com/xtls/xray-core/app/stats"
|
|
"github.com/xtls/xray-core/common/serial"
|
|
"github.com/xtls/xray-core/core"
|
|
"github.com/xtls/xray-core/infra/conf"
|
|
|
|
"github.com/XrayR-project/XrayR/api"
|
|
"github.com/XrayR-project/XrayR/api/pmpanel"
|
|
"github.com/XrayR-project/XrayR/api/proxypanel"
|
|
"github.com/XrayR-project/XrayR/api/sspanel"
|
|
"github.com/XrayR-project/XrayR/api/v2raysocks"
|
|
_ "github.com/XrayR-project/XrayR/cmd/distro/all"
|
|
"github.com/XrayR-project/XrayR/service"
|
|
"github.com/XrayR-project/XrayR/service/controller"
|
|
)
|
|
|
|
// Panel Structure
|
|
type Panel struct {
|
|
access sync.Mutex
|
|
panelConfig *Config
|
|
Server *core.Instance
|
|
Service []service.Service
|
|
Running bool
|
|
}
|
|
|
|
func New(panelConfig *Config) *Panel {
|
|
p := &Panel{panelConfig: panelConfig}
|
|
return p
|
|
}
|
|
|
|
func (p *Panel) loadCore(panelConfig *Config) *core.Instance {
|
|
// Log Config
|
|
coreLogConfig := &conf.LogConfig{}
|
|
logConfig := getDefaultLogConfig()
|
|
if panelConfig.LogConfig != nil {
|
|
if _, err := diff.Merge(logConfig, panelConfig.LogConfig, logConfig); err != nil {
|
|
log.Panicf("Read Log config failed: %s", err)
|
|
}
|
|
}
|
|
coreLogConfig.LogLevel = logConfig.Level
|
|
coreLogConfig.AccessLog = logConfig.AccessPath
|
|
coreLogConfig.ErrorLog = logConfig.ErrorPath
|
|
|
|
// DNS config
|
|
coreDnsConfig := &conf.DNSConfig{}
|
|
if panelConfig.DnsConfigPath != "" {
|
|
if data, err := os.ReadFile(panelConfig.DnsConfigPath); err != nil {
|
|
log.Panicf("Failed to read DNS config file at: %s", panelConfig.DnsConfigPath)
|
|
} else {
|
|
if err = json.Unmarshal(data, coreDnsConfig); err != nil {
|
|
log.Panicf("Failed to unmarshal DNS config: %s", panelConfig.DnsConfigPath)
|
|
}
|
|
}
|
|
}
|
|
|
|
// init controller's DNS config
|
|
// for _, config := range p.panelConfig.NodesConfig {
|
|
// config.ControllerConfig.DNSConfig = coreDnsConfig
|
|
// }
|
|
|
|
dnsConfig, err := coreDnsConfig.Build()
|
|
if err != nil {
|
|
log.Panicf("Failed to understand DNS config, Please check: https://xtls.github.io/config/dns.html for help: %s", err)
|
|
}
|
|
|
|
// Routing config
|
|
coreRouterConfig := &conf.RouterConfig{}
|
|
if panelConfig.RouteConfigPath != "" {
|
|
if data, err := os.ReadFile(panelConfig.RouteConfigPath); err != nil {
|
|
log.Panicf("Failed to read Routing config file at: %s", panelConfig.RouteConfigPath)
|
|
} else {
|
|
if err = json.Unmarshal(data, coreRouterConfig); err != nil {
|
|
log.Panicf("Failed to unmarshal Routing config: %s", panelConfig.RouteConfigPath)
|
|
}
|
|
}
|
|
}
|
|
routeConfig, err := coreRouterConfig.Build()
|
|
if err != nil {
|
|
log.Panicf("Failed to understand Routing config Please check: https://xtls.github.io/config/routing.html for help: %s", err)
|
|
}
|
|
// Custom Inbound config
|
|
var coreCustomInboundConfig []conf.InboundDetourConfig
|
|
if panelConfig.InboundConfigPath != "" {
|
|
if data, err := os.ReadFile(panelConfig.InboundConfigPath); err != nil {
|
|
log.Panicf("Failed to read Custom Inbound config file at: %s", panelConfig.OutboundConfigPath)
|
|
} else {
|
|
if err = json.Unmarshal(data, &coreCustomInboundConfig); err != nil {
|
|
log.Panicf("Failed to unmarshal Custom Inbound config: %s", panelConfig.OutboundConfigPath)
|
|
}
|
|
}
|
|
}
|
|
var inBoundConfig []*core.InboundHandlerConfig
|
|
for _, config := range coreCustomInboundConfig {
|
|
oc, err := config.Build()
|
|
if err != nil {
|
|
log.Panicf("Failed to understand Inbound config, Please check: https://xtls.github.io/config/inbound.html for help: %s", err)
|
|
}
|
|
inBoundConfig = append(inBoundConfig, oc)
|
|
}
|
|
// Custom Outbound config
|
|
var coreCustomOutboundConfig []conf.OutboundDetourConfig
|
|
if panelConfig.OutboundConfigPath != "" {
|
|
if data, err := os.ReadFile(panelConfig.OutboundConfigPath); err != nil {
|
|
log.Panicf("Failed to read Custom Outbound config file at: %s", panelConfig.OutboundConfigPath)
|
|
} else {
|
|
if err = json.Unmarshal(data, &coreCustomOutboundConfig); err != nil {
|
|
log.Panicf("Failed to unmarshal Custom Outbound config: %s", panelConfig.OutboundConfigPath)
|
|
}
|
|
}
|
|
}
|
|
var outBoundConfig []*core.OutboundHandlerConfig
|
|
for _, config := range coreCustomOutboundConfig {
|
|
oc, err := config.Build()
|
|
if err != nil {
|
|
log.Panicf("Failed to understand Outbound config, Please check: https://xtls.github.io/config/outbound.html for help: %s", err)
|
|
}
|
|
outBoundConfig = append(outBoundConfig, oc)
|
|
}
|
|
// Policy config
|
|
levelPolicyConfig := parseConnectionConfig(panelConfig.ConnectionConfig)
|
|
corePolicyConfig := &conf.PolicyConfig{}
|
|
corePolicyConfig.Levels = map[uint32]*conf.Policy{0: levelPolicyConfig}
|
|
policyConfig, _ := corePolicyConfig.Build()
|
|
// Build Core Config
|
|
config := &core.Config{
|
|
App: []*serial.TypedMessage{
|
|
serial.ToTypedMessage(coreLogConfig.Build()),
|
|
serial.ToTypedMessage(&mydispatcher.Config{}),
|
|
serial.ToTypedMessage(&stats.Config{}),
|
|
serial.ToTypedMessage(&proxyman.InboundConfig{}),
|
|
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
|
|
serial.ToTypedMessage(policyConfig),
|
|
serial.ToTypedMessage(dnsConfig),
|
|
serial.ToTypedMessage(routeConfig),
|
|
},
|
|
Inbound: inBoundConfig,
|
|
Outbound: outBoundConfig,
|
|
}
|
|
server, err := core.New(config)
|
|
if err != nil {
|
|
log.Panicf("failed to create instance: %s", err)
|
|
}
|
|
log.Printf("Xray Core Version: %s", core.Version())
|
|
|
|
return server
|
|
}
|
|
|
|
// Start the panel
|
|
func (p *Panel) Start() {
|
|
p.access.Lock()
|
|
defer p.access.Unlock()
|
|
log.Print("Start the panel..")
|
|
// Load Core
|
|
server := p.loadCore(p.panelConfig)
|
|
if err := server.Start(); err != nil {
|
|
log.Panicf("Failed to start instance: %s", err)
|
|
}
|
|
p.Server = server
|
|
|
|
// Load Nodes config
|
|
for _, nodeConfig := range p.panelConfig.NodesConfig {
|
|
var apiClient api.API
|
|
switch nodeConfig.PanelType {
|
|
case "SSpanel":
|
|
apiClient = sspanel.New(nodeConfig.ApiConfig)
|
|
case "NewV2board", "V2board":
|
|
apiClient = newV2board.New(nodeConfig.ApiConfig)
|
|
case "PMpanel":
|
|
apiClient = pmpanel.New(nodeConfig.ApiConfig)
|
|
case "Proxypanel":
|
|
apiClient = proxypanel.New(nodeConfig.ApiConfig)
|
|
case "V2RaySocks":
|
|
apiClient = v2raysocks.New(nodeConfig.ApiConfig)
|
|
case "GoV2Panel":
|
|
apiClient = gov2panel.New(nodeConfig.ApiConfig)
|
|
default:
|
|
log.Panicf("Unsupport panel type: %s", nodeConfig.PanelType)
|
|
}
|
|
var controllerService service.Service
|
|
// Register controller service
|
|
controllerConfig := getDefaultControllerConfig()
|
|
if nodeConfig.ControllerConfig != nil {
|
|
if err := mergo.Merge(controllerConfig, nodeConfig.ControllerConfig, mergo.WithOverride); err != nil {
|
|
log.Panicf("Read Controller Config Failed")
|
|
}
|
|
}
|
|
controllerService = controller.New(server, apiClient, controllerConfig, nodeConfig.PanelType)
|
|
p.Service = append(p.Service, controllerService)
|
|
|
|
}
|
|
|
|
// Start all the service
|
|
for _, s := range p.Service {
|
|
err := s.Start()
|
|
if err != nil {
|
|
log.Panicf("Panel Start fialed: %s", err)
|
|
}
|
|
}
|
|
p.Running = true
|
|
return
|
|
}
|
|
|
|
// Close the panel
|
|
func (p *Panel) Close() {
|
|
p.access.Lock()
|
|
defer p.access.Unlock()
|
|
for _, s := range p.Service {
|
|
err := s.Close()
|
|
if err != nil {
|
|
log.Panicf("Panel Close fialed: %s", err)
|
|
}
|
|
}
|
|
p.Service = nil
|
|
p.Server.Close()
|
|
p.Running = false
|
|
return
|
|
}
|
|
|
|
func parseConnectionConfig(c *ConnectionConfig) (policy *conf.Policy) {
|
|
connectionConfig := getDefaultConnectionConfig()
|
|
if c != nil {
|
|
if _, err := diff.Merge(connectionConfig, c, connectionConfig); err != nil {
|
|
log.Panicf("Read ConnectionConfig failed: %s", err)
|
|
}
|
|
}
|
|
policy = &conf.Policy{
|
|
StatsUserUplink: true,
|
|
StatsUserDownlink: true,
|
|
Handshake: &connectionConfig.Handshake,
|
|
ConnectionIdle: &connectionConfig.ConnIdle,
|
|
UplinkOnly: &connectionConfig.UplinkOnly,
|
|
DownlinkOnly: &connectionConfig.DownlinkOnly,
|
|
BufferSize: &connectionConfig.BufferSize,
|
|
}
|
|
|
|
return
|
|
}
|