mirror of
https://github.com/wyx2685/V2bX.git
synced 2026-02-04 04:30:08 +00:00
feat: remote dns for sing
This commit is contained in:
81
core/sing/dns.go
Normal file
81
core/sing/dns.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package sing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/InazumaV/V2bX/api/panel"
|
||||
"github.com/goccy/go-json"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func updateDNSConfig(node *panel.NodeInfo) (err error) {
|
||||
dnsPath := os.Getenv("SING_DNS_PATH")
|
||||
if len(node.RawDNS.DNSJson) != 0 {
|
||||
err = saveDnsConfig(node.RawDNS.DNSJson, dnsPath)
|
||||
} else if len(node.RawDNS.DNSMap) != 0 {
|
||||
dnsConfig := DNSConfig{
|
||||
Servers: []map[string]interface{}{
|
||||
{
|
||||
"tag": "default",
|
||||
"address": "https://8.8.8.8/dns-query",
|
||||
"detour": "direct",
|
||||
},
|
||||
},
|
||||
}
|
||||
for id, value := range node.RawDNS.DNSMap {
|
||||
dnsConfig.Servers = append(dnsConfig.Servers,
|
||||
map[string]interface{}{
|
||||
"tag": id,
|
||||
"address": value["address"],
|
||||
"address_resolver": "default",
|
||||
"detour": "direct",
|
||||
},
|
||||
)
|
||||
rule := map[string]interface{}{
|
||||
"server": id,
|
||||
"disable_cache": true,
|
||||
}
|
||||
for _, ruleType := range []string{"domain_suffix", "domain_keyword", "domain_regex", "geosite"} {
|
||||
var domains []string
|
||||
for _, v := range value["domains"].([]string) {
|
||||
split := strings.SplitN(v, ":", 2)
|
||||
prefix := strings.ToLower(split[0])
|
||||
if prefix == ruleType || (prefix == "domain" && ruleType == "domain_suffix") {
|
||||
if len(split) > 1 {
|
||||
domains = append(domains, split[1])
|
||||
}
|
||||
if len(domains) > 0 {
|
||||
rule[ruleType] = domains
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dnsConfig.Rules = append(dnsConfig.Rules, rule)
|
||||
}
|
||||
dnsConfigJSON, err := json.MarshalIndent(dnsConfig, "", " ")
|
||||
if err != nil {
|
||||
log.WithField("err", err).Error("Error marshaling dnsConfig to JSON")
|
||||
return err
|
||||
}
|
||||
err = saveDnsConfig(dnsConfigJSON, dnsPath)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func saveDnsConfig(dns []byte, dnsPath string) (err error) {
|
||||
currentData, err := os.ReadFile(dnsPath)
|
||||
if err != nil {
|
||||
log.WithField("err", err).Error("Failed to read SING_DNS_PATH")
|
||||
return err
|
||||
}
|
||||
if !bytes.Equal(currentData, dns) {
|
||||
if err = os.Truncate(dnsPath, 0); err != nil {
|
||||
log.WithField("err", err).Error("Failed to clear SING DNS PATH file")
|
||||
}
|
||||
if err = os.WriteFile(dnsPath, dns, 0644); err != nil {
|
||||
log.WithField("err", err).Error("Failed to write DNS to SING DNS PATH file")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -30,6 +30,10 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
|
||||
if err != nil {
|
||||
return option.Inbound{}, fmt.Errorf("the listen ip not vail")
|
||||
}
|
||||
var domainStrategy option.DomainStrategy
|
||||
if c.SingOptions.EnableDNS {
|
||||
domainStrategy = c.SingOptions.DomainStrategy
|
||||
}
|
||||
listen := option.ListenOptions{
|
||||
Listen: (*option.ListenAddress)(&addr),
|
||||
ListenPort: uint16(info.Common.ServerPort),
|
||||
@@ -38,7 +42,7 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
|
||||
InboundOptions: option.InboundOptions{
|
||||
SniffEnabled: c.SingOptions.SniffEnabled,
|
||||
SniffOverrideDestination: c.SingOptions.SniffOverrideDestination,
|
||||
DomainStrategy: c.SingOptions.DomainStrategy,
|
||||
DomainStrategy: domainStrategy,
|
||||
},
|
||||
}
|
||||
var tls option.InboundTLSOptions
|
||||
@@ -203,6 +207,10 @@ func getInboundOptions(tag string, info *panel.NodeInfo, c *conf.Options) (optio
|
||||
}
|
||||
|
||||
func (b *Box) AddNode(tag string, info *panel.NodeInfo, config *conf.Options) error {
|
||||
err := updateDNSConfig(info)
|
||||
if err != nil {
|
||||
return fmt.Errorf("build dns error: %s", err)
|
||||
}
|
||||
c, err := getInboundOptions(tag, info, config)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -26,6 +26,11 @@ import (
|
||||
|
||||
var _ adapter.Service = (*Box)(nil)
|
||||
|
||||
type DNSConfig struct {
|
||||
Servers []map[string]interface{} `json:"servers"`
|
||||
Rules []map[string]interface{} `json:"rules"`
|
||||
}
|
||||
|
||||
type Box struct {
|
||||
createdAt time.Time
|
||||
router adapter.Router
|
||||
@@ -68,6 +73,17 @@ func New(c *conf.CoreConfig) (vCore.Core, error) {
|
||||
ServerPort: c.SingConfig.NtpConfig.ServerPort,
|
||||
},
|
||||
}
|
||||
os.Setenv("SING_DNS_PATH", "")
|
||||
if c.SingConfig.DnsConfigPath != "" {
|
||||
if f, err := os.Open(c.SingConfig.DnsConfigPath); err != nil {
|
||||
log.Error("Failed to read DNS config file")
|
||||
} else {
|
||||
if err = json.NewDecoder(f).Decode(&option.DNSOptions{}); err != nil {
|
||||
log.Error("Failed to unmarshal DNS config")
|
||||
}
|
||||
}
|
||||
os.Setenv("SING_DNS_PATH", c.SingConfig.DnsConfigPath)
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx = service.ContextWithDefaultRegistry(ctx)
|
||||
ctx = pause.ContextWithDefaultManager(ctx)
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
coreConf "github.com/xtls/xray-core/infra/conf"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func updateDNSConfig(node *panel.NodeInfo) (err error) {
|
||||
@@ -57,7 +56,5 @@ func saveDnsConfig(dns []byte, dnsPath string) (err error) {
|
||||
log.WithField("err", err).Error("Failed to write DNS to XRAY DNS PATH file")
|
||||
}
|
||||
}
|
||||
log.Println("reloading config")
|
||||
time.Sleep(5 * time.Second)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user