Files
umbrix-libcore/config/config.go

797 lines
21 KiB
Go
Raw Normal View History

2024-01-15 17:17:05 +03:30
package config
2023-09-01 14:52:30 +03:30
import (
2023-11-12 12:50:14 +03:30
"bytes"
2024-03-18 20:44:23 +01:00
"encoding/base64"
2023-10-19 19:56:50 +03:30
"encoding/json"
2023-09-01 14:52:30 +03:30
"fmt"
2024-03-18 20:44:23 +01:00
"math/rand"
2023-10-19 19:56:50 +03:30
"net"
2023-09-01 14:52:30 +03:30
"net/netip"
2023-10-19 19:56:50 +03:30
"net/url"
"strings"
"time"
2023-09-01 14:52:30 +03:30
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
dns "github.com/sagernet/sing-dns"
)
const (
DNSRemoteTag = "dns-remote"
DNSLocalTag = "dns-local"
DNSDirectTag = "dns-direct"
DNSBlockTag = "dns-block"
DNSFakeTag = "dns-fake"
DNSTricksDirectTag = "dns-trick-direct"
OutboundDirectTag = "direct"
OutboundBypassTag = "bypass"
OutboundBlockTag = "block"
OutboundSelectTag = "select"
OutboundURLTestTag = "auto"
OutboundDNSTag = "dns-out"
OutboundDirectFragmentTag = "direct-fragment"
InboundTUNTag = "tun-in"
InboundMixedTag = "mixed-in"
InboundDNSTag = "dns-in"
)
var OutboundMainProxyTag = OutboundSelectTag
2023-11-12 12:50:14 +03:30
func BuildConfigJson(configOpt ConfigOptions, input option.Options) (string, error) {
2024-01-19 17:55:58 +03:30
options, err := BuildConfig(configOpt, input)
if err != nil {
return "", err
}
2023-11-12 12:50:14 +03:30
var buffer bytes.Buffer
json.NewEncoder(&buffer)
encoder := json.NewEncoder(&buffer)
encoder.SetIndent("", " ")
2024-01-19 17:55:58 +03:30
err = encoder.Encode(options)
2023-11-12 12:50:14 +03:30
if err != nil {
return "", err
}
return buffer.String(), nil
}
2023-10-19 19:56:50 +03:30
// TODO include selectors
2024-02-03 23:12:04 +03:30
func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, error) {
fmt.Printf("config options: %+v\n", opt)
2023-09-01 14:52:30 +03:30
2023-10-19 19:56:50 +03:30
var options option.Options
2024-05-29 18:47:04 +02:00
if opt.EnableFullConfig {
options.Inbounds = input.Inbounds
options.DNS = input.DNS
options.Route = input.Route
}
directDNSDomains := make(map[string]bool)
2023-10-20 18:57:23 +03:30
dnsRules := []option.DefaultDNSRule{}
2023-09-01 14:52:30 +03:30
2024-01-01 19:11:08 +03:30
var bind string
2024-02-03 23:12:04 +03:30
if opt.AllowConnectionFromLAN {
2024-01-01 19:11:08 +03:30
bind = "0.0.0.0"
} else {
bind = "127.0.0.1"
}
2024-02-03 23:12:04 +03:30
if opt.EnableClashApi {
2024-03-18 20:44:23 +01:00
if opt.ClashApiSecret == "" {
opt.ClashApiSecret = generateRandomString(16)
}
2023-09-01 14:52:30 +03:30
options.Experimental = &option.ExperimentalOptions{
ClashAPI: &option.ClashAPIOptions{
2024-02-03 23:12:04 +03:30
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", opt.ClashApiPort),
2024-03-18 20:38:09 +01:00
Secret: opt.ClashApiSecret,
},
2024-03-18 20:38:09 +01:00
CacheFile: &option.CacheFileOptions{
Enabled: true,
Path: "clash.db",
},
2023-09-01 14:52:30 +03:30
}
}
options.Log = &option.LogOptions{
Level: opt.LogLevel,
Output: "box.log",
2023-09-01 14:52:30 +03:30
Disabled: false,
2023-10-23 19:22:07 +03:30
Timestamp: true,
2023-09-01 14:52:30 +03:30
DisableColor: true,
}
options.DNS = &option.DNSOptions{
2024-01-30 13:18:47 +01:00
StaticIPs: map[string][]string{
2024-07-16 12:52:53 +02:00
"sky.rethinkdns.com": getIPs([]string{"www.speedtest.net", "sky.rethinkdns.com"}),
2024-01-30 13:18:47 +01:00
},
2023-09-01 14:52:30 +03:30
DNSClientOptions: option.DNSClientOptions{
2024-02-03 23:12:04 +03:30
IndependentCache: opt.IndependentDNSCache,
2023-09-01 14:52:30 +03:30
},
Final: DNSRemoteTag,
2023-09-01 14:52:30 +03:30
Servers: []option.DNSServerOptions{
{
Tag: DNSRemoteTag,
2024-02-03 23:12:04 +03:30
Address: opt.RemoteDnsAddress,
AddressResolver: DNSDirectTag,
2024-02-03 23:12:04 +03:30
Strategy: opt.RemoteDnsDomainStrategy,
},
{
Tag: DNSTricksDirectTag,
Address: "https://sky.rethinkdns.com/",
// AddressResolver: "dns-local",
2024-02-03 23:12:04 +03:30
Strategy: opt.DirectDnsDomainStrategy,
Detour: OutboundDirectFragmentTag,
2023-09-01 14:52:30 +03:30
},
{
Tag: DNSDirectTag,
2024-02-03 23:12:04 +03:30
Address: opt.DirectDnsAddress,
AddressResolver: DNSLocalTag,
2024-02-03 23:12:04 +03:30
Strategy: opt.DirectDnsDomainStrategy,
Detour: OutboundDirectTag,
2023-09-01 14:52:30 +03:30
},
{
Tag: DNSLocalTag,
2023-09-01 14:52:30 +03:30
Address: "local",
Detour: OutboundDirectTag,
2023-09-01 14:52:30 +03:30
},
{
Tag: DNSBlockTag,
2023-09-01 14:52:30 +03:30
Address: "rcode://success",
},
},
}
var inboundDomainStrategy option.DomainStrategy
2024-02-03 23:12:04 +03:30
if !opt.ResolveDestination {
2023-09-01 14:52:30 +03:30
inboundDomainStrategy = option.DomainStrategy(dns.DomainStrategyAsIS)
} else {
2024-02-03 23:12:04 +03:30
inboundDomainStrategy = opt.IPv6Mode
2023-09-01 14:52:30 +03:30
}
if opt.EnableTunService {
ActivateTunnelService(opt)
} else if opt.EnableTun {
tunInbound := option.Inbound{
Type: C.TypeTun,
Tag: InboundTUNTag,
TunOptions: option.TunInboundOptions{
Stack: opt.TUNStack,
MTU: opt.MTU,
AutoRoute: true,
StrictRoute: opt.StrictRoute,
EndpointIndependentNat: true,
2024-03-10 18:46:40 +01:00
// GSO: runtime.GOOS != "windows",
InboundOptions: option.InboundOptions{
SniffEnabled: true,
SniffOverrideDestination: true,
DomainStrategy: inboundDomainStrategy,
2023-09-01 14:52:30 +03:30
},
},
}
switch opt.IPv6Mode {
case option.DomainStrategy(dns.DomainStrategyUseIPv4):
tunInbound.TunOptions.Inet4Address = []netip.Prefix{
netip.MustParsePrefix("172.19.0.1/28"),
}
case option.DomainStrategy(dns.DomainStrategyUseIPv6):
tunInbound.TunOptions.Inet6Address = []netip.Prefix{
netip.MustParsePrefix("fdfe:dcba:9876::1/126"),
2023-09-01 14:52:30 +03:30
}
default:
tunInbound.TunOptions.Inet4Address = []netip.Prefix{
netip.MustParsePrefix("172.19.0.1/28"),
}
tunInbound.TunOptions.Inet6Address = []netip.Prefix{
netip.MustParsePrefix("fdfe:dcba:9876::1/126"),
2023-09-01 14:52:30 +03:30
}
}
options.Inbounds = append(options.Inbounds, tunInbound)
2023-09-01 14:52:30 +03:30
}
options.Inbounds = append(
options.Inbounds,
option.Inbound{
Type: C.TypeMixed,
Tag: InboundMixedTag,
2023-09-01 14:52:30 +03:30
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
2024-01-01 19:11:08 +03:30
Listen: option.NewListenAddress(netip.MustParseAddr(bind)),
2024-02-03 23:12:04 +03:30
ListenPort: opt.MixedPort,
2023-09-01 14:52:30 +03:30
InboundOptions: option.InboundOptions{
SniffEnabled: true,
SniffOverrideDestination: true,
DomainStrategy: inboundDomainStrategy,
},
},
2024-02-03 23:12:04 +03:30
SetSystemProxy: opt.SetSystemProxy,
2023-09-01 14:52:30 +03:30
},
},
)
2023-10-19 19:56:50 +03:30
options.Inbounds = append(
options.Inbounds,
2023-09-01 14:52:30 +03:30
option.Inbound{
Type: C.TypeDirect,
Tag: InboundDNSTag,
2023-09-01 14:52:30 +03:30
DirectOptions: option.DirectInboundOptions{
ListenOptions: option.ListenOptions{
2024-01-01 19:11:08 +03:30
Listen: option.NewListenAddress(netip.MustParseAddr(bind)),
2024-02-03 23:12:04 +03:30
ListenPort: opt.LocalDnsPort,
2023-09-01 14:52:30 +03:30
},
// OverrideAddress: "1.1.1.1",
// OverridePort: 53,
2023-09-01 14:52:30 +03:30
},
},
)
2024-02-03 23:12:04 +03:30
remoteDNSAddress := opt.RemoteDnsAddress
2023-10-19 19:56:50 +03:30
if strings.Contains(remoteDNSAddress, "://") {
remoteDNSAddress = strings.SplitAfter(remoteDNSAddress, "://")[1]
}
parsedUrl, err := url.Parse(fmt.Sprintf("https://%s", remoteDNSAddress))
if err == nil && net.ParseIP(parsedUrl.Host) == nil {
directDNSDomains["full:"+parsedUrl.Host] = true
//TODO: IS it really needed
2023-10-19 19:56:50 +03:30
}
routeRules := []option.Rule{
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
Inbound: []string{InboundDNSTag},
Outbound: OutboundDNSTag,
2023-09-01 14:52:30 +03:30
},
2023-10-19 19:56:50 +03:30
},
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
Port: []uint16{53},
Outbound: OutboundDNSTag,
2023-09-01 14:52:30 +03:30
},
2023-10-19 19:56:50 +03:30
},
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
ClashMode: "Direct",
Outbound: OutboundDirectTag,
2023-09-01 14:52:30 +03:30
},
2023-10-19 19:56:50 +03:30
},
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
ClashMode: "Global",
Outbound: OutboundMainProxyTag,
2023-09-01 14:52:30 +03:30
},
2023-10-19 19:56:50 +03:30
},
}
2024-02-03 23:12:04 +03:30
if opt.BypassLAN {
2023-10-19 19:56:50 +03:30
routeRules = append(
routeRules,
option.Rule{
2023-09-01 14:52:30 +03:30
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
2024-02-16 09:45:52 +01:00
GeoIP: []string{"private"},
2024-02-20 07:56:47 +01:00
Outbound: OutboundBypassTag,
2023-10-20 18:57:23 +03:30
},
},
)
}
2024-02-03 23:12:04 +03:30
if opt.EnableFakeDNS {
2023-10-26 14:31:25 +03:30
inet4Range := netip.MustParsePrefix("198.18.0.0/15")
inet6Range := netip.MustParsePrefix("fc00::/18")
2023-10-20 18:57:23 +03:30
options.DNS.FakeIP = &option.DNSFakeIPOptions{
Enabled: true,
Inet4Range: &inet4Range,
Inet6Range: &inet6Range,
}
options.DNS.Servers = append(
options.DNS.Servers,
option.DNSServerOptions{
Tag: DNSFakeTag,
2023-10-20 18:57:23 +03:30
Address: "fakeip",
Strategy: option.DomainStrategy(dns.DomainStrategyUseIPv4),
},
)
options.DNS.Rules = append(
options.DNS.Rules,
option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
Inbound: []string{InboundTUNTag},
Server: DNSFakeTag,
2023-10-20 18:57:23 +03:30
DisableCache: true,
2023-09-01 14:52:30 +03:30
},
},
2023-10-19 19:56:50 +03:30
)
2024-01-25 23:59:07 +01:00
2023-10-19 19:56:50 +03:30
}
2024-02-03 23:12:04 +03:30
for _, rule := range opt.Rules {
2023-10-19 19:56:50 +03:30
routeRule := rule.MakeRule()
switch rule.Outbound {
case "bypass":
routeRule.Outbound = OutboundBypassTag
2023-10-19 19:56:50 +03:30
case "block":
routeRule.Outbound = OutboundBlockTag
2023-10-19 19:56:50 +03:30
case "proxy":
routeRule.Outbound = OutboundDNSTag
2023-10-19 19:56:50 +03:30
}
if routeRule.IsValid() {
routeRules = append(
routeRules,
option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: routeRule,
2023-09-01 14:52:30 +03:30
},
2023-10-19 19:56:50 +03:30
)
}
dnsRule := rule.MakeDNSRule()
switch rule.Outbound {
case "bypass":
dnsRule.Server = DNSDirectTag
2023-10-19 19:56:50 +03:30
case "block":
dnsRule.Server = DNSBlockTag
2023-10-19 19:56:50 +03:30
dnsRule.DisableCache = true
case "proxy":
2024-02-03 23:12:04 +03:30
if opt.EnableFakeDNS {
2023-10-20 18:57:23 +03:30
fakeDnsRule := dnsRule
fakeDnsRule.Server = DNSFakeTag
fakeDnsRule.Inbound = []string{InboundTUNTag}
2023-10-20 18:57:23 +03:30
dnsRules = append(dnsRules, fakeDnsRule)
}
dnsRule.Server = DNSRemoteTag
2023-10-19 19:56:50 +03:30
}
2023-10-20 18:57:23 +03:30
dnsRules = append(dnsRules, dnsRule)
}
2023-10-19 19:56:50 +03:30
2024-02-03 23:12:04 +03:30
if opt.EnableDNSRouting {
2024-01-01 18:52:00 +03:30
for _, dnsRule := range dnsRules {
if dnsRule.IsValid() {
options.DNS.Rules = append(
options.DNS.Rules,
option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: dnsRule,
},
)
}
2023-10-19 19:56:50 +03:30
}
}
2024-01-26 00:24:24 +01:00
if options.DNS.Rules == nil {
options.DNS.Rules = []option.DNSRule{}
}
var dnsCPttl uint32 = 3000
options.DNS.Rules = append(
options.DNS.Rules,
option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
Domain: []string{"cp.cloudflare.com"},
Server: DNSRemoteTag,
2024-01-26 00:24:24 +01:00
RewriteTTL: &dnsCPttl,
DisableCache: false,
},
},
)
2023-10-19 19:56:50 +03:30
options.Route = &option.RouteOptions{
Rules: routeRules,
2023-09-01 14:52:30 +03:30
AutoDetectInterface: true,
OverrideAndroidVPN: true,
// RuleSet: []option.RuleSet{},
// GeoIP: &option.GeoIPOptions{
// Path: opt.GeoIPPath,
// },
// Geosite: &option.GeositeOptions{
// Path: opt.GeoSitePath,
// },
2023-09-01 14:52:30 +03:30
}
fmt.Println("Region==========================", opt.Region)
if opt.Region != "other" {
options.DNS.Rules = append(
options.DNS.Rules,
option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
RuleSet: []string{
"geoip-" + opt.Region,
"geosite-" + opt.Region,
},
Server: DNSDirectTag,
},
},
)
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
2024-07-05 00:14:22 +02:00
Type: C.RuleSetTypeRemote,
Tag: "geoip-" + opt.Region,
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/country/geoip-" + opt.Region + ".srs",
2024-07-05 00:14:22 +02:00
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
2024-07-05 00:14:22 +02:00
Type: C.RuleSetTypeRemote,
Tag: "geosite-" + opt.Region,
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/country/geosite-" + opt.Region + ".srs",
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
2023-09-01 14:52:30 +03:30
routeRuleIp := option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
2024-07-05 00:14:22 +02:00
RuleSet: []string{
"geoip-" + opt.Region,
"geosite-" + opt.Region,
},
Outbound: OutboundDirectTag,
},
}
2024-07-05 00:14:22 +02:00
options.Route.Rules = append([]option.Rule{routeRuleIp}, options.Route.Rules...)
}
if opt.BlockAds {
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
2024-07-05 00:14:22 +02:00
Type: C.RuleSetTypeRemote,
Tag: "geosite-ads",
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-category-ads-all.srs",
2024-07-05 00:14:22 +02:00
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
Type: C.RuleSetTypeRemote,
Tag: "geosite-malware",
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-malware.srs",
2024-07-05 00:14:22 +02:00
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
Type: C.RuleSetTypeRemote,
Tag: "geosite-phishing",
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-phishing.srs",
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
2024-07-05 00:14:22 +02:00
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
Type: C.RuleSetTypeRemote,
Tag: "geosite-cryptominers",
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geosite-cryptominers.srs",
2024-07-05 00:14:22 +02:00
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
Type: C.RuleSetTypeRemote,
Tag: "geoip-phishing",
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geoip-phishing.srs",
2024-07-05 00:14:22 +02:00
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
options.Route.RuleSet = append(options.Route.RuleSet, option.RuleSet{
Type: C.RuleSetTypeRemote,
Tag: "geoip-malware",
Format: C.RuleSetFormatBinary,
RemoteOptions: option.RemoteRuleSet{
URL: "https://raw.githubusercontent.com/hiddify/hiddify-geo/rule-set/block/geoip-malware.srs",
2024-07-05 00:14:22 +02:00
UpdateInterval: option.Duration(5 * time.Hour * 24),
},
})
routeRule := option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
2024-07-05 00:14:22 +02:00
RuleSet: []string{
"geosite-ads",
"geosite-malware",
"geosite-phishing",
"geosite-cryptominers",
"geoip-malware",
"geoip-phishing",
},
Outbound: OutboundBlockTag,
},
}
options.Route.Rules = append([]option.Rule{routeRule}, options.Route.Rules...)
}
2023-09-01 14:52:30 +03:30
var outbounds []option.Outbound
var tags []string
OutboundMainProxyTag = OutboundSelectTag
2024-03-09 21:07:15 +01:00
//inbound==warp over proxies
//outbound==proxies over warp
if opt.Warp.EnableWarp {
for _, out := range input.Outbounds {
if out.Type == C.TypeCustom {
if warp, ok := out.CustomOptions["warp"].(map[string]interface{}); ok {
key, _ := warp["key"].(string)
if key == "p1" {
opt.Warp.EnableWarp = false
break
}
}
}
if out.Type == C.TypeWireGuard && (out.WireGuardOptions.PrivateKey == opt.Warp.WireguardConfig.PrivateKey || out.WireGuardOptions.PrivateKey == "p1") {
opt.Warp.EnableWarp = false
break
}
}
}
2024-03-10 18:46:40 +01:00
if opt.Warp.EnableWarp && (opt.Warp.Mode == "warp_over_proxy" || opt.Warp.Mode == "proxy_over_warp") {
2024-07-18 00:55:37 +02:00
out, err := GenerateWarpSingbox(opt.Warp.WireguardConfig, opt.Warp.CleanIP, opt.Warp.CleanPort, opt.Warp.FakePackets, opt.Warp.FakePacketSize, opt.Warp.FakePacketDelay, opt.Warp.FakePacketMode)
2024-02-20 07:56:47 +01:00
if err != nil {
return nil, fmt.Errorf("failed to generate warp config: %v", err)
}
out.Tag = "Hiddify Warp ✅"
2024-03-10 18:46:40 +01:00
if opt.Warp.Mode == "warp_over_proxy" {
2024-07-25 04:32:27 +02:00
out.WireGuardOptions.Detour = OutboundSelectTag
OutboundMainProxyTag = out.Tag
} else {
out.WireGuardOptions.Detour = OutboundDirectTag
2024-02-20 07:56:47 +01:00
}
2024-07-25 04:32:27 +02:00
patchWarp(out, &opt, true, nil)
2024-02-20 07:56:47 +01:00
outbounds = append(outbounds, *out)
// tags = append(tags, out.Tag)
2024-02-20 07:56:47 +01:00
}
2023-09-01 14:52:30 +03:30
for _, out := range input.Outbounds {
2024-07-18 00:55:37 +02:00
outbound, serverDomain, err := patchOutbound(out, opt, options.DNS.StaticIPs)
2024-01-19 17:55:58 +03:30
if err != nil {
return nil, err
}
if serverDomain != "" {
directDNSDomains[serverDomain] = true
2023-10-19 19:56:50 +03:30
}
out = *outbound
2023-10-19 19:56:50 +03:30
2023-09-01 14:52:30 +03:30
switch out.Type {
case C.TypeDirect, C.TypeBlock, C.TypeDNS:
continue
case C.TypeSelector, C.TypeURLTest:
continue
2024-01-25 18:37:08 +00:00
case C.TypeCustom:
continue
2023-09-01 14:52:30 +03:30
default:
if !strings.Contains(out.Tag, "§hide§") {
tags = append(tags, out.Tag)
}
2024-02-20 07:56:47 +01:00
out = patchHiddifyWarpFromConfig(out, opt)
2023-09-01 14:52:30 +03:30
outbounds = append(outbounds, out)
}
}
urlTest := option.Outbound{
Type: C.TypeURLTest,
Tag: OutboundURLTestTag,
2023-09-01 14:52:30 +03:30
URLTestOptions: option.URLTestOutboundOptions{
2024-03-19 12:25:51 +01:00
Outbounds: tags,
URL: opt.ConnectionTestUrl,
Interval: option.Duration(opt.URLTestInterval.Duration()),
// IdleTimeout: option.Duration(opt.URLTestIdleTimeout.Duration()),
IdleTimeout: option.Duration(opt.URLTestInterval.Duration().Nanoseconds() * 10),
2023-09-01 14:52:30 +03:30
},
}
2024-06-01 16:44:31 +02:00
defaultSelect := urlTest.Tag
2023-09-01 14:52:30 +03:30
2024-06-01 16:44:31 +02:00
for _, tag := range tags {
if strings.Contains(tag, "§default§") {
defaultSelect = "§default§"
}
}
2023-09-01 14:52:30 +03:30
selector := option.Outbound{
Type: C.TypeSelector,
Tag: OutboundSelectTag,
2023-09-01 14:52:30 +03:30
SelectorOptions: option.SelectorOutboundOptions{
Outbounds: append([]string{urlTest.Tag}, tags...),
2024-06-01 16:44:31 +02:00
Default: defaultSelect,
2023-09-01 14:52:30 +03:30
},
}
outbounds = append([]option.Outbound{selector, urlTest}, outbounds...)
options.Outbounds = append(
outbounds,
[]option.Outbound{
{
Tag: OutboundDNSTag,
2023-09-01 14:52:30 +03:30
Type: C.TypeDNS,
},
{
Tag: OutboundDirectTag,
2023-09-01 14:52:30 +03:30
Type: C.TypeDirect,
},
{
Tag: OutboundDirectFragmentTag,
Type: C.TypeDirect,
DirectOptions: option.DirectOutboundOptions{
DialerOptions: option.DialerOptions{
TCPFastOpen: false,
TLSFragment: &option.TLSFragmentOptions{
Enabled: true,
2024-02-03 23:12:04 +03:30
Size: opt.TLSTricks.FragmentSize,
Sleep: opt.TLSTricks.FragmentSleep,
},
},
},
},
2023-10-20 18:57:23 +03:30
{
Tag: OutboundBypassTag,
2023-10-20 18:57:23 +03:30
Type: C.TypeDirect,
},
2023-09-01 14:52:30 +03:30
{
Tag: OutboundBlockTag,
2023-09-01 14:52:30 +03:30
Type: C.TypeBlock,
},
}...,
)
2023-10-19 19:56:50 +03:30
if len(directDNSDomains) > 0 {
// trickDnsDomains := []string{}
// directDNSDomains = removeDuplicateStr(directDNSDomains)
// b, _ := batch.New(context.Background(), batch.WithConcurrencyNum[bool](10))
// for _, d := range directDNSDomains {
// b.Go(d, func() (bool, error) {
// return isBlockedDomain(d), nil
// })
// }
// b.Wait()
// for domain, isBlock := range b.Result() {
// if isBlock.Value {
// trickDnsDomains = append(trickDnsDomains, domain)
// }
// }
// trickDomains := strings.Join(trickDnsDomains, ",")
// trickRule := Rule{Domains: trickDomains, Outbound: OutboundBypassTag}
// trickDnsRule := trickRule.MakeDNSRule()
// trickDnsRule.Server = DNSTricksDirectTag
// options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: trickDnsRule}}, options.DNS.Rules...)
directDNSDomainskeys := make([]string, 0, len(directDNSDomains))
for key := range directDNSDomains {
directDNSDomainskeys = append(directDNSDomainskeys, key)
}
domains := strings.Join(directDNSDomainskeys, ",")
directRule := Rule{Domains: domains, Outbound: OutboundBypassTag}
2023-10-19 19:56:50 +03:30
dnsRule := directRule.MakeDNSRule()
dnsRule.Server = DNSDirectTag
2023-10-19 19:56:50 +03:30
options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: dnsRule}}, options.DNS.Rules...)
}
options.Route.Final = OutboundMainProxyTag
2024-01-19 17:55:58 +03:30
return &options, nil
2023-09-01 14:52:30 +03:30
}
2024-01-30 13:18:47 +01:00
2024-02-20 07:56:47 +01:00
func patchHiddifyWarpFromConfig(out option.Outbound, opt ConfigOptions) option.Outbound {
2024-03-10 18:46:40 +01:00
if opt.Warp.EnableWarp && opt.Warp.Mode == "proxy_over_warp" {
if out.DirectOptions.Detour == "" {
out.DirectOptions.Detour = "Hiddify Warp ✅"
}
if out.HTTPOptions.Detour == "" {
out.HTTPOptions.Detour = "Hiddify Warp ✅"
}
if out.Hysteria2Options.Detour == "" {
out.Hysteria2Options.Detour = "Hiddify Warp ✅"
}
if out.HysteriaOptions.Detour == "" {
out.HysteriaOptions.Detour = "Hiddify Warp ✅"
}
if out.SSHOptions.Detour == "" {
out.SSHOptions.Detour = "Hiddify Warp ✅"
}
if out.ShadowTLSOptions.Detour == "" {
out.ShadowTLSOptions.Detour = "Hiddify Warp ✅"
}
if out.ShadowsocksOptions.Detour == "" {
out.ShadowsocksOptions.Detour = "Hiddify Warp ✅"
}
if out.ShadowsocksROptions.Detour == "" {
out.ShadowsocksROptions.Detour = "Hiddify Warp ✅"
}
if out.SocksOptions.Detour == "" {
out.SocksOptions.Detour = "Hiddify Warp ✅"
}
if out.TUICOptions.Detour == "" {
out.TUICOptions.Detour = "Hiddify Warp ✅"
}
if out.TorOptions.Detour == "" {
out.TorOptions.Detour = "Hiddify Warp ✅"
}
if out.TrojanOptions.Detour == "" {
out.TrojanOptions.Detour = "Hiddify Warp ✅"
}
if out.VLESSOptions.Detour == "" {
out.VLESSOptions.Detour = "Hiddify Warp ✅"
}
if out.VMessOptions.Detour == "" {
out.VMessOptions.Detour = "Hiddify Warp ✅"
}
if out.WireGuardOptions.Detour == "" {
out.WireGuardOptions.Detour = "Hiddify Warp ✅"
}
2024-02-20 07:56:47 +01:00
}
return out
}
2024-01-30 13:18:47 +01:00
func getIPs(domains []string) []string {
res := []string{}
for _, d := range domains {
ips, err := net.LookupHost(d)
if err != nil {
continue
}
for _, ip := range ips {
if !strings.HasPrefix(ip, "10.") {
res = append(res, ip)
}
}
}
return res
}
func isBlockedDomain(domain string) bool {
if strings.HasPrefix("full:", domain) {
return false
}
ips, err := net.LookupHost(domain)
if err != nil {
// fmt.Println(err)
return true
}
// Print the IP addresses associated with the domain
fmt.Printf("IP addresses for %s:\n", domain)
for _, ip := range ips {
if strings.HasPrefix(ip, "10.") {
return true
}
}
return false
}
2023-09-01 14:52:30 +03:30
2023-10-19 19:56:50 +03:30
func removeDuplicateStr(strSlice []string) []string {
allKeys := make(map[string]bool)
list := []string{}
for _, item := range strSlice {
if _, value := allKeys[item]; !value {
allKeys[item] = true
list = append(list, item)
}
}
return list
}
2024-03-18 20:44:23 +01:00
func generateRandomString(length int) string {
// Determine the number of bytes needed
bytesNeeded := (length*6 + 7) / 8
// Generate random bytes
randomBytes := make([]byte, bytesNeeded)
_, err := rand.Read(randomBytes)
if err != nil {
return "hiddify"
}
// Encode random bytes to base64
randomString := base64.URLEncoding.EncodeToString(randomBytes)
// Trim padding characters and return the string
return randomString[:length]
}