diff --git a/docs/configuration/template.md b/docs/configuration/template.md index 5bed45d..2176bfa 100644 --- a/docs/configuration/template.md +++ b/docs/configuration/template.md @@ -8,12 +8,13 @@ "log": {}, "domain_strategy": "", + "domain_strategy_local": "", "disable_traffic_bypass": false, "disable_rule_set": false, "remote_resolve": false, // DNS - "dns_default": "", + "dns": "", "dns_local": "", "enable_fakeip": false, "pre_dns_rules": [], @@ -47,7 +48,6 @@ "custom_urltest": {}, // Route - "disable_default_rules": false, "pre_rules": [], "custom_rules": [], "enable_jsdelivr": false, @@ -96,6 +96,15 @@ If `*_only` enabled, TUN and DNS will be configured to disable the other network Note that if want `prefer_*` to take effect on transparent proxy requests, set `enable_fakeip`. +`ipv4_only` is used by default when `enable_fakeip` disabled, +`prefer_ipv4` is used by default when `enable_fakeip` enabled. + +#### domain_strategy_local + +Local sing-box domain strategy. + +`prefer_ipv4` is used by default. + #### disable_rule_set Use `geoip` and `geosite` for traffic bypassing instead of rule sets. @@ -108,7 +117,7 @@ Disable traffic bypass for Chinese DNS queries and connections. Don't generate `doamin_strategy` options for inbounds. -#### dns_default +#### dns Default DNS server. @@ -222,10 +231,6 @@ Custom [Selector](https://sing-box.sagernet.org/configuration/outbound/selector/ Custom [URLTest](https://sing-box.sagernet.org/configuration/outbound/urltest/) outbound template. -#### disable_default_rules - -Don't generate some useful rules. - #### pre_rules List of [Rule](https://sing-box.sagernet.org/configuration/route/rule/). diff --git a/option/template.go b/option/template.go index 4904f7f..2bc872c 100644 --- a/option/template.go +++ b/option/template.go @@ -16,12 +16,13 @@ type _Template struct { Log *option.LogOptions `json:"log,omitempty"` DomainStrategy option.DomainStrategy `json:"domain_strategy,omitempty"` + DomainStrategyLocal option.DomainStrategy `json:"domain_strategy_local,omitempty"` DisableTrafficBypass bool `json:"disable_traffic_bypass,omitempty"` DisableRuleSet bool `json:"disable_rule_set,omitempty"` RemoteResolve bool `json:"remote_resolve,omitempty"` // DNS - DNSDefault string `json:"dns_default,omitempty"` + DNS string `json:"dns,omitempty"` DNSLocal string `json:"dns_local,omitempty"` EnableFakeIP bool `json:"enable_fakeip,omitempty"` DisableDNSLeak bool `json:"disable_dns_leak,omitempty"` @@ -124,7 +125,7 @@ type GitHubRuleSetOptions struct { } func (t Template) DisableIPv6() bool { - return t.DomainStrategy == option.DomainStrategy(dns.DomainStrategyUseIPv4) + return t.DomainStrategy == option.DomainStrategy(dns.DomainStrategyUseIPv4) && t.DomainStrategyLocal == option.DomainStrategy(dns.DomainStrategyUseIPv4) } type ExtraGroup struct { diff --git a/template/filter/filter_1100.go b/template/filter/filter_1100.go index 22f1811..4c4d1d9 100644 --- a/template/filter/filter_1100.go +++ b/template/filter/filter_1100.go @@ -1,10 +1,13 @@ package filter import ( + "net/netip" + "github.com/sagernet/serenity/common/metadata" "github.com/sagernet/serenity/common/semver" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing/common" ) func init() { @@ -21,6 +24,36 @@ func filter1100(metadata metadata.Metadata, options *option.Options) { inbound.TunOptions.AutoRedirect = false inbound.TunOptions.RouteAddressSet = nil inbound.TunOptions.RouteExcludeAddressSet = nil + //nolint:staticcheck + //goland:noinspection GoDeprecation + if len(inbound.TunOptions.Address) > 0 { + inbound.TunOptions.Inet4Address = append(inbound.TunOptions.Inet4Address, common.Filter(inbound.TunOptions.Address, func(it netip.Prefix) bool { + return it.Addr().Is4() + })...) + inbound.TunOptions.Inet6Address = append(inbound.TunOptions.Inet6Address, common.Filter(inbound.TunOptions.Address, func(it netip.Prefix) bool { + return it.Addr().Is6() + })...) + } + //nolint:staticcheck + //goland:noinspection GoDeprecation + if len(inbound.TunOptions.RouteAddress) > 0 { + inbound.TunOptions.Inet4RouteAddress = append(inbound.TunOptions.Inet4RouteAddress, common.Filter(inbound.TunOptions.RouteAddress, func(it netip.Prefix) bool { + return it.Addr().Is4() + })...) + inbound.TunOptions.Inet6RouteAddress = append(inbound.TunOptions.Inet6RouteAddress, common.Filter(inbound.TunOptions.RouteAddress, func(it netip.Prefix) bool { + return it.Addr().Is6() + })...) + } + //nolint:staticcheck + //goland:noinspection GoDeprecation + if len(inbound.TunOptions.RouteExcludeAddress) > 0 { + inbound.TunOptions.Inet4RouteExcludeAddress = append(inbound.TunOptions.Inet4RouteExcludeAddress, common.Filter(inbound.TunOptions.RouteExcludeAddress, func(it netip.Prefix) bool { + return it.Addr().Is4() + })...) + inbound.TunOptions.Inet6RouteExcludeAddress = append(inbound.TunOptions.Inet6RouteExcludeAddress, common.Filter(inbound.TunOptions.RouteExcludeAddress, func(it netip.Prefix) bool { + return it.Addr().Is6() + })...) + } } newInbounds = append(newInbounds, inbound) } diff --git a/template/filter/filter_170.go b/template/filter/filter_170.go index 9b7ece1..46fdd07 100644 --- a/template/filter/filter_170.go +++ b/template/filter/filter_170.go @@ -70,6 +70,8 @@ func filter170(metadata metadata.Metadata, options *option.Options) { } } +//nolint:staticcheck +//goland:noinspection GoDeprecation func filter170Tun(options option.TunInboundOptions) option.TunInboundOptions { options.Inet4RouteExcludeAddress = nil options.Inet6RouteExcludeAddress = nil diff --git a/template/render_dns.go b/template/render_dns.go index 671267c..cf6d9aa 100644 --- a/template/render_dns.go +++ b/template/render_dns.go @@ -16,11 +16,24 @@ import ( ) func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error { - var domainStrategy option.DomainStrategy + var ( + domainStrategy option.DomainStrategy + domainStrategyLocal option.DomainStrategy + ) if t.DomainStrategy != option.DomainStrategy(dns.DomainStrategyAsIS) { domainStrategy = t.DomainStrategy - } else { + } else if t.EnableFakeIP { domainStrategy = option.DomainStrategy(dns.DomainStrategyPreferIPv4) + } else { + domainStrategy = option.DomainStrategy(dns.DomainStrategyUseIPv4) + } + if t.DomainStrategyLocal != option.DomainStrategy(dns.DomainStrategyAsIS) { + domainStrategyLocal = t.DomainStrategyLocal + } else { + domainStrategyLocal = option.DomainStrategy(dns.DomainStrategyPreferIPv4) + } + if domainStrategyLocal == domainStrategy { + domainStrategyLocal = 0 } options.DNS = &option.DNSOptions{ ReverseMapping: !t.DisableTrafficBypass && metadata.Platform != M.PlatformUnknown && !metadata.Platform.IsApple(), @@ -29,7 +42,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error IndependentCache: t.EnableFakeIP, }, } - dnsDefault := t.DNSDefault + dnsDefault := t.DNS if dnsDefault == "" { dnsDefault = DefaultDNS } @@ -55,14 +68,16 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error ) if t.DisableTrafficBypass { localDNSOptions = option.DNSServerOptions{ - Tag: DNSLocalTag, - Address: "local", + Tag: DNSLocalTag, + Address: "local", + Strategy: domainStrategyLocal, } } else { localDNSOptions = option.DNSServerOptions{ - Tag: DNSLocalTag, - Address: dnsLocal, - Detour: directTag, + Tag: DNSLocalTag, + Address: dnsLocal, + Detour: directTag, + Strategy: domainStrategyLocal, } if dnsLocalUrl, err := url.Parse(dnsLocal); err == nil && BM.IsDomainName(dnsLocalUrl.Hostname()) { localDNSOptions.AddressResolver = DNSLocalSetupTag @@ -72,8 +87,9 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error options.DNS.Servers = append(options.DNS.Servers, localDNSOptions) if localDNSIsDomain { options.DNS.Servers = append(options.DNS.Servers, option.DNSServerOptions{ - Tag: DNSLocalSetupTag, - Address: "local", + Tag: DNSLocalSetupTag, + Address: "local", + Strategy: domainStrategyLocal, }) } if t.EnableFakeIP { diff --git a/template/render_inbounds.go b/template/render_inbounds.go index 634159f..7933b5b 100644 --- a/template/render_inbounds.go +++ b/template/render_inbounds.go @@ -32,17 +32,15 @@ func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options) disableTun := t.DisableTUN && !metadata.Platform.TunOnly() if !disableTun { options.Route.AutoDetectInterface = true - - var inet6Address []netip.Prefix + address := []netip.Prefix{netip.MustParsePrefix("172.19.0.1/30")} if !t.DisableIPv6() { - inet6Address = []netip.Prefix{netip.MustParsePrefix("fdfe:dcba:9876::1/126")} + address = append(address, netip.MustParsePrefix("fdfe:dcba:9876::1/126")) } tunInbound := option.Inbound{ Type: C.TypeTun, TunOptions: option.TunInboundOptions{ - Inet4Address: []netip.Prefix{netip.MustParsePrefix("172.19.0.1/30")}, - Inet6Address: inet6Address, - AutoRoute: true, + AutoRoute: true, + Address: address, InboundOptions: option.InboundOptions{ SniffEnabled: needSniff, }, @@ -50,7 +48,7 @@ func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options) } if autoRedirect { tunInbound.TunOptions.AutoRedirect = true - if !t.DisableTrafficBypass { + if !t.DisableTrafficBypass && metadata.Platform == "" { tunInbound.TunOptions.RouteExcludeAddressSet = []string{"geoip-cn"} } }