mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-22 20:24:40 +07:00
feat: support must_xxx outbounds
This commit is contained in:
parent
3e55f85d91
commit
006b7fbfd2
@ -64,14 +64,13 @@ const (
|
||||
OutboundDirect OutboundIndex = iota
|
||||
OutboundBlock
|
||||
|
||||
OutboundMustDirect OutboundIndex = 0xFC
|
||||
OutboundControlPlaneRouting OutboundIndex = 0xFD
|
||||
OutboundLogicalOr OutboundIndex = 0xFE
|
||||
OutboundLogicalAnd OutboundIndex = 0xFF
|
||||
OutboundLogicalMask OutboundIndex = 0xFE
|
||||
|
||||
OutboundMax = OutboundLogicalAnd
|
||||
OutboundUserDefinedMax = OutboundMustDirect - 1
|
||||
OutboundUserDefinedMax = OutboundControlPlaneRouting - 1
|
||||
)
|
||||
|
||||
func (i OutboundIndex) String() string {
|
||||
@ -80,8 +79,6 @@ func (i OutboundIndex) String() string {
|
||||
return "direct"
|
||||
case OutboundBlock:
|
||||
return "block"
|
||||
case OutboundMustDirect:
|
||||
return "must_direct"
|
||||
case OutboundControlPlaneRouting:
|
||||
return "<Control Plane Routing>"
|
||||
case OutboundLogicalOr:
|
||||
|
@ -112,6 +112,12 @@ func (b *RequestMatcherBuilder) addFallback(fallbackOutbound config.FunctionOrSt
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if upstream.Must {
|
||||
return fmt.Errorf("unsupported param: must")
|
||||
}
|
||||
if upstream.Mark != 0 {
|
||||
return fmt.Errorf("unsupported param: mark")
|
||||
}
|
||||
upstreamId, err := b.upstreamToId(upstream.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -195,6 +195,12 @@ func (b *ResponseMatcherBuilder) addFallback(fallbackOutbound config.FunctionOrS
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if upstream.Must {
|
||||
return fmt.Errorf("unsupported param: must")
|
||||
}
|
||||
if upstream.Mark != 0 {
|
||||
return fmt.Errorf("unsupported param: mark")
|
||||
}
|
||||
upstreamId, err := b.upstreamToId(upstream.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -7,11 +7,11 @@ package domain_matcher
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/daeuniverse/dae/common/consts"
|
||||
"github.com/daeuniverse/dae/component/routing"
|
||||
"github.com/daeuniverse/dae/config"
|
||||
"github.com/daeuniverse/dae/pkg/config_parser"
|
||||
"github.com/sirupsen/logrus"
|
||||
"hash/fnv"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
@ -132,7 +132,7 @@ func getDomain() (simulatedDomainSet []routing.DomainSet, err error) {
|
||||
sections, err := config_parser.Parse(`
|
||||
routing {
|
||||
domain(geosite:bing)->us
|
||||
domain(full:dns.google) -> direct
|
||||
domain(full:dns.google.com) -> direct
|
||||
domain(geosite:category-ads-all) -> block
|
||||
domain(geosite:cn) -> direct
|
||||
}`)
|
||||
|
@ -7,9 +7,9 @@ package routing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/daeuniverse/dae/common/consts"
|
||||
"github.com/daeuniverse/dae/pkg/config_parser"
|
||||
"github.com/sirupsen/logrus"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@ -22,6 +22,7 @@ type DomainSet struct {
|
||||
type Outbound struct {
|
||||
Name string
|
||||
Mark uint32
|
||||
Must bool
|
||||
}
|
||||
|
||||
type RulesBuilder struct {
|
||||
@ -62,6 +63,7 @@ func (b *RulesBuilder) Apply(rules []*config_parser.RoutingRule) (err error) {
|
||||
overrideOutbound := &Outbound{
|
||||
Name: consts.OutboundLogicalOr.String(),
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
}
|
||||
if jMatchSet == len(keyOrder)-1 {
|
||||
overrideOutbound.Name = consts.OutboundLogicalAnd.String()
|
||||
@ -103,6 +105,7 @@ func ParseOutbound(rawOutbound *config_parser.Function) (outbound *Outbound, err
|
||||
outbound = &Outbound{
|
||||
Name: rawOutbound.Name,
|
||||
Mark: 0,
|
||||
Must: false,
|
||||
}
|
||||
for _, p := range rawOutbound.Params {
|
||||
switch p.Key {
|
||||
@ -113,8 +116,14 @@ func ParseOutbound(rawOutbound *config_parser.Function) (outbound *Outbound, err
|
||||
return nil, fmt.Errorf("failed to parse mark: %v", err)
|
||||
}
|
||||
outbound.Mark = uint32(_mark)
|
||||
case "":
|
||||
if p.Val == "must" {
|
||||
outbound.Must = true
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown outbound param: %v", p.Val)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown outbound param: %v", p.Key)
|
||||
return nil, fmt.Errorf("unknown outbound param key: %v", p.Key)
|
||||
}
|
||||
}
|
||||
return outbound, nil
|
||||
|
@ -18,7 +18,7 @@ type Global struct {
|
||||
// We use DirectTcpCheckUrl to check (tcp)*(ipv4/ipv6) connectivity for direct.
|
||||
//DirectTcpCheckUrl string `mapstructure:"direct_tcp_check_url" default:"http://www.qualcomm.cn/generate_204"`
|
||||
TcpCheckUrl string `mapstructure:"tcp_check_url" default:"http://keep-alv.google.com/generate_204"`
|
||||
UdpCheckDns string `mapstructure:"udp_check_dns" default:"dns.google:53"`
|
||||
UdpCheckDns string `mapstructure:"udp_check_dns" default:"dns.google.com:53"`
|
||||
CheckInterval time.Duration `mapstructure:"check_interval" default:"30s"`
|
||||
CheckTolerance time.Duration `mapstructure:"check_tolerance" default:"0"`
|
||||
LanInterface []string `mapstructure:"lan_interface"`
|
||||
|
@ -7,12 +7,15 @@ package config
|
||||
|
||||
import (
|
||||
"github.com/daeuniverse/dae/common/consts"
|
||||
"github.com/daeuniverse/dae/pkg/config_parser"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type patch func(params *Config) error
|
||||
|
||||
var patches = []patch{
|
||||
patchEmptyDns,
|
||||
patchMustOutbound,
|
||||
}
|
||||
|
||||
func patchEmptyDns(params *Config) error {
|
||||
@ -24,3 +27,22 @@ func patchEmptyDns(params *Config) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchMustOutbound(params *Config) error {
|
||||
for i := range params.Routing.Rules {
|
||||
if strings.HasPrefix(params.Routing.Rules[i].Outbound.Name, "must_") {
|
||||
params.Routing.Rules[i].Outbound.Name = strings.TrimPrefix(params.Routing.Rules[i].Outbound.Name, "must_")
|
||||
params.Routing.Rules[i].Outbound.Params = append(params.Routing.Rules[i].Outbound.Params, &config_parser.Param{
|
||||
Val: "must",
|
||||
})
|
||||
}
|
||||
}
|
||||
if f := FunctionOrStringToFunction(params.Routing.Fallback); strings.HasPrefix(f.Name, "must_") {
|
||||
f.Name = strings.TrimPrefix(f.Name, "must_")
|
||||
f.Params = append(f.Params, &config_parser.Param{
|
||||
Val: "must",
|
||||
})
|
||||
params.Routing.Fallback = f
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -757,10 +757,6 @@ func (c *ControlPlane) chooseBestDnsDialer(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Already "must direct".
|
||||
if outboundIndex == consts.OutboundMustDirect {
|
||||
outboundIndex = consts.OutboundDirect
|
||||
}
|
||||
if int(outboundIndex) >= len(c.outbounds) {
|
||||
return nil, fmt.Errorf("bad outbound index: %v", outboundIndex)
|
||||
}
|
||||
|
@ -60,7 +60,6 @@
|
||||
|
||||
#define OUTBOUND_DIRECT 0
|
||||
#define OUTBOUND_BLOCK 1
|
||||
#define OUTBOUND_MUST_DIRECT 0xFC
|
||||
#define OUTBOUND_CONTROL_PLANE_ROUTING 0xFD
|
||||
#define OUTBOUND_LOGICAL_OR 0xFE
|
||||
#define OUTBOUND_LOGICAL_AND 0xFF
|
||||
@ -135,6 +134,7 @@ struct ip_port {
|
||||
|
||||
struct routing_result {
|
||||
__u32 mark;
|
||||
__u8 must;
|
||||
__u8 mac[6];
|
||||
__u8 outbound;
|
||||
__u8 pname[TASK_COMM_LEN];
|
||||
@ -307,7 +307,7 @@ struct match_set {
|
||||
bool not ; // A subrule flag (this is not a match_set flag).
|
||||
enum MatchType type;
|
||||
__u8 outbound; // User-defined value range is [0, 252].
|
||||
__u8 unused;
|
||||
bool must;
|
||||
__u32 mark;
|
||||
};
|
||||
struct {
|
||||
@ -1133,11 +1133,13 @@ routing(const __u32 flag[6], const void *l4hdr, const __be32 saddr[4],
|
||||
|
||||
// DNS requests should routed by control plane if outbound is not
|
||||
// must_direct.
|
||||
if (match_set->outbound != OUTBOUND_MUST_DIRECT && h_dport == 53 &&
|
||||
if (!match_set->must && h_dport == 53 &&
|
||||
_l4proto_type == L4ProtoType_UDP) {
|
||||
return OUTBOUND_CONTROL_PLANE_ROUTING | (match_set->mark << 8);
|
||||
return (__s64)OUTBOUND_CONTROL_PLANE_ROUTING |
|
||||
((__s64)match_set->mark << 8) | ((__s64)match_set->must << 40);
|
||||
}
|
||||
return match_set->outbound | (match_set->mark << 8);
|
||||
return (__s64)match_set->outbound | ((__s64)match_set->mark << 8) |
|
||||
((__s64)match_set->must << 40);
|
||||
}
|
||||
bad_rule = false;
|
||||
}
|
||||
@ -1325,14 +1327,16 @@ new_connection:
|
||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||
};
|
||||
if ((ret = routing(flag, l4hdr, tuples.sip.u6_addr32, tuples.dip.u6_addr32,
|
||||
mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", ret);
|
||||
__s64 s64_ret;
|
||||
if ((s64_ret = routing(flag, l4hdr, tuples.sip.u6_addr32,
|
||||
tuples.dip.u6_addr32, mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", s64_ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
struct routing_result routing_result = {0};
|
||||
routing_result.outbound = ret;
|
||||
routing_result.mark = ret >> 8;
|
||||
routing_result.outbound = s64_ret;
|
||||
routing_result.mark = s64_ret >> 8;
|
||||
routing_result.must = (s64_ret >> 40) & 1;
|
||||
__builtin_memcpy(routing_result.mac, ethh.h_source,
|
||||
sizeof(routing_result.mac));
|
||||
/// NOTICE: No pid pname info for LAN packet.
|
||||
@ -1361,8 +1365,7 @@ new_connection:
|
||||
bpf_ntohs(tuples.dport));
|
||||
}
|
||||
#endif
|
||||
if (routing_result.outbound == OUTBOUND_DIRECT ||
|
||||
routing_result.outbound == OUTBOUND_MUST_DIRECT) {
|
||||
if (routing_result.outbound == OUTBOUND_DIRECT) {
|
||||
skb->mark = routing_result.mark;
|
||||
goto direct;
|
||||
} else if (unlikely(routing_result.outbound == OUTBOUND_BLOCK)) {
|
||||
@ -1593,6 +1596,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
__builtin_memcpy(&key_src.ip, &tuples.dip, IPV6_BYTE_LENGTH);
|
||||
key_src.port = tcph.source;
|
||||
__u8 outbound;
|
||||
bool must;
|
||||
__u32 mark;
|
||||
struct pid_pname *pid_pname = NULL;
|
||||
if (unlikely(tcp_state_syn)) {
|
||||
@ -1618,14 +1622,16 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||
};
|
||||
if ((ret = routing(flag, &tcph, tuples.sip.u6_addr32,
|
||||
tuples.dip.u6_addr32, mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", ret);
|
||||
__s64 s64_ret;
|
||||
if ((s64_ret = routing(flag, &tcph, tuples.sip.u6_addr32,
|
||||
tuples.dip.u6_addr32, mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", s64_ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
|
||||
outbound = ret;
|
||||
mark = ret >> 8;
|
||||
outbound = s64_ret;
|
||||
mark = s64_ret >> 8;
|
||||
must = (s64_ret >> 40) & 1;
|
||||
|
||||
#if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT)
|
||||
// Print only new connection.
|
||||
@ -1646,9 +1652,10 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
}
|
||||
outbound = dst->routing_result.outbound;
|
||||
mark = dst->routing_result.mark;
|
||||
must = dst->routing_result.must;
|
||||
}
|
||||
|
||||
if ((outbound == OUTBOUND_DIRECT || outbound == OUTBOUND_MUST_DIRECT) &&
|
||||
if (outbound == OUTBOUND_DIRECT &&
|
||||
mark == 0 // If mark is not zero, we should re-route it, so we send it
|
||||
// to control plane in WAN.
|
||||
) {
|
||||
@ -1678,6 +1685,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
routing_info.port = tcph.dest;
|
||||
routing_info.routing_result.outbound = outbound;
|
||||
routing_info.routing_result.mark = mark;
|
||||
routing_info.routing_result.must = must;
|
||||
__builtin_memcpy(routing_info.routing_result.mac, ethh.h_source,
|
||||
sizeof(ethh.h_source));
|
||||
if (pid_pname) {
|
||||
@ -1726,9 +1734,10 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
bpf_htonl((ethh.h_source[2] << 24) + (ethh.h_source[3] << 16) +
|
||||
(ethh.h_source[4] << 8) + (ethh.h_source[5])),
|
||||
};
|
||||
if ((ret = routing(flag, &udph, tuples.sip.u6_addr32,
|
||||
tuples.dip.u6_addr32, mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", ret);
|
||||
__s64 s64_ret;
|
||||
if ((s64_ret = routing(flag, &udph, tuples.sip.u6_addr32,
|
||||
tuples.dip.u6_addr32, mac)) < 0) {
|
||||
bpf_printk("shot routing: %d", s64_ret);
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
// Construct new hdr to encap.
|
||||
@ -1736,8 +1745,9 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
__builtin_memset(&new_hdr, 0, sizeof(new_hdr));
|
||||
__builtin_memcpy(new_hdr.ip, &tuples.dip, IPV6_BYTE_LENGTH);
|
||||
new_hdr.port = udph.dest;
|
||||
new_hdr.routing_result.outbound = ret;
|
||||
new_hdr.routing_result.mark = ret >> 8;
|
||||
new_hdr.routing_result.outbound = s64_ret;
|
||||
new_hdr.routing_result.mark = s64_ret >> 8;
|
||||
new_hdr.routing_result.must = (s64_ret >> 40) & 1;
|
||||
__builtin_memcpy(new_hdr.routing_result.mac, ethh.h_source,
|
||||
sizeof(ethh.h_source));
|
||||
if (pid_pname) {
|
||||
@ -1754,8 +1764,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
|
||||
bpf_ntohs(tuples.dport));
|
||||
#endif
|
||||
|
||||
if ((new_hdr.routing_result.outbound == OUTBOUND_DIRECT ||
|
||||
new_hdr.routing_result.outbound == OUTBOUND_MUST_DIRECT) &&
|
||||
if (new_hdr.routing_result.outbound == OUTBOUND_DIRECT &&
|
||||
new_hdr.routing_result.mark ==
|
||||
0 // If mark is not zero, we should re-route it, so we
|
||||
// send it to control plane in WAN.
|
||||
|
@ -56,8 +56,6 @@ func NewRoutingMatcherBuilder(log *logrus.Logger, rules []*config_parser.Routing
|
||||
func (b *RoutingMatcherBuilder) outboundToId(outbound string) (uint8, error) {
|
||||
var outboundId uint8
|
||||
switch outbound {
|
||||
case consts.OutboundMustDirect.String():
|
||||
outboundId = uint8(consts.OutboundMustDirect)
|
||||
case consts.OutboundLogicalOr.String():
|
||||
outboundId = uint8(consts.OutboundLogicalOr)
|
||||
case consts.OutboundLogicalAnd.String():
|
||||
@ -95,6 +93,7 @@ func (b *RoutingMatcherBuilder) addDomain(f *config_parser.Function, key string,
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@ -119,6 +118,7 @@ func (b *RoutingMatcherBuilder) addSourceMac(f *config_parser.Function, macAddrs
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
}
|
||||
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
||||
b.rules = append(b.rules, set)
|
||||
@ -138,6 +138,7 @@ func (b *RoutingMatcherBuilder) addIp(f *config_parser.Function, values []netip.
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
}
|
||||
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
||||
b.rules = append(b.rules, set)
|
||||
@ -163,6 +164,7 @@ func (b *RoutingMatcherBuilder) addPort(f *config_parser.Function, values [][2]u
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
@ -181,6 +183,7 @@ func (b *RoutingMatcherBuilder) addSourceIp(f *config_parser.Function, values []
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
}
|
||||
binary.LittleEndian.PutUint32(set.Value[:], uint32(lpmTrieIndex))
|
||||
b.rules = append(b.rules, set)
|
||||
@ -206,6 +209,7 @@ func (b *RoutingMatcherBuilder) addSourcePort(f *config_parser.Function, values
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
@ -222,6 +226,7 @@ func (b *RoutingMatcherBuilder) addL4Proto(f *config_parser.Function, values con
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@ -237,6 +242,7 @@ func (b *RoutingMatcherBuilder) addIpVersion(f *config_parser.Function, values c
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@ -256,6 +262,7 @@ func (b *RoutingMatcherBuilder) addProcessName(f *config_parser.Function, values
|
||||
Not: f.Not,
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
}
|
||||
copy(matchSet.Value[:], value[:])
|
||||
b.rules = append(b.rules, matchSet)
|
||||
@ -276,6 +283,7 @@ func (b *RoutingMatcherBuilder) addFallback(fallbackOutbound config.FunctionOrSt
|
||||
Type: uint8(consts.MatchType_Fallback),
|
||||
Outbound: outboundId,
|
||||
Mark: outbound.Mark,
|
||||
Must: outbound.Must,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
@ -70,8 +70,6 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) {
|
||||
|
||||
switch outboundIndex {
|
||||
case consts.OutboundDirect:
|
||||
case consts.OutboundMustDirect:
|
||||
outboundIndex = consts.OutboundDirect
|
||||
case consts.OutboundControlPlaneRouting:
|
||||
if outboundIndex, routingResult.Mark, err = c.Route(src, dst, domain, consts.L4ProtoType_TCP, routingResult); err != nil {
|
||||
return err
|
||||
|
@ -143,11 +143,11 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r
|
||||
outboundIndex = consts.OutboundControlPlaneRouting
|
||||
}
|
||||
|
||||
if routingResult.Must > 0 {
|
||||
isDns = false // Regard as plain traffic.
|
||||
}
|
||||
switch outboundIndex {
|
||||
case consts.OutboundDirect:
|
||||
case consts.OutboundMustDirect:
|
||||
outboundIndex = consts.OutboundDirect
|
||||
isDns = false // Regard as plain traffic.
|
||||
case consts.OutboundControlPlaneRouting:
|
||||
if isDns {
|
||||
// Routing of DNS packets are managed by DNS controller.
|
||||
|
@ -15,7 +15,7 @@ dns {
|
||||
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
||||
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
}
|
||||
# The routing format of 'request' and 'response' is similar with section 'routing'.
|
||||
# See https://github.com/daeuniverse/dae/blob/main/docs/routing.md
|
||||
@ -64,7 +64,7 @@ dns {
|
||||
# Use alidns for China mainland domains and googledns for others.
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
@ -84,7 +84,7 @@ dns {
|
||||
# Use alidns for all DNS queries and fallback to googledns if pollution result detected.
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
|
@ -137,7 +137,7 @@ subscription {
|
||||
# See https://github.com/daeuniverse/dae/blob/main/docs/dns.md for full examples.
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
|
@ -133,7 +133,7 @@ subscription {
|
||||
# 更多的 DNS 样例见 https://github.com/daeuniverse/dae/blob/main/docs/dns.md
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
@ -174,7 +174,7 @@ routing {
|
||||
```shell
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
|
@ -7,13 +7,13 @@ If you use a external DNS like AdguardHome, you could refer to the following gui
|
||||
|
||||
## External DNS on localhost
|
||||
|
||||
If you set up a external DNS on localhost, you may want to let the DNS queries to dns.google proxied. For example, if you have following configuration in AdguardHome:
|
||||
If you set up a external DNS on localhost, you may want to let the DNS queries to dns.google.com proxied. For example, if you have following configuration in AdguardHome:
|
||||
|
||||
```
|
||||
Listen on: the same machine with dae, port 53.
|
||||
|
||||
China mainland: udp://223.5.5.5:53
|
||||
Others: https://dns.google/dns-query
|
||||
Others: https://dns.google.com/dns-query
|
||||
```
|
||||
|
||||
You should configure dae as follows:
|
||||
@ -26,7 +26,7 @@ You should configure dae as follows:
|
||||
pname(AdGuardHome) && l4proto(udp) && dport(53) -> must_direct
|
||||
```
|
||||
|
||||
And make sure domain `dns.google` will be proxied in routing rules.
|
||||
And make sure domain `dns.google.com` will be proxied in routing rules.
|
||||
|
||||
3. Add upstream and request to section "dns".
|
||||
|
||||
@ -51,13 +51,13 @@ You should configure dae as follows:
|
||||
|
||||
## External DNS on another machine in LAN
|
||||
|
||||
If you set up a external DNS on another machine in LAN, you may want to let the DNS queries to dns.google proxied. For example, if you have following configuration in AdguardHome:
|
||||
If you set up a external DNS on another machine in LAN, you may want to let the DNS queries to dns.google.com proxied. For example, if you have following configuration in AdguardHome:
|
||||
|
||||
```
|
||||
Listen on: 192.168.30.3:53 (mac address: 8c:16:45:36:1c:5a)
|
||||
|
||||
China mainland: udp://223.5.5.5:53
|
||||
Others: https://dns.google/dns-query
|
||||
Others: https://dns.google.com/dns-query
|
||||
```
|
||||
|
||||
You should configure dae as follows:
|
||||
@ -72,7 +72,7 @@ You should configure dae as follows:
|
||||
# mac(8c:16:45:36:1c:5a) && l4proto(udp) && dport(53) -> must_direct
|
||||
```
|
||||
|
||||
And make sure domain `dns.google` will be proxied in routing rules.
|
||||
And make sure domain `dns.google.com` will be proxied in routing rules.
|
||||
|
||||
3. Add upstream and request to section "dns".
|
||||
|
||||
|
@ -3,9 +3,11 @@
|
||||
## Examples:
|
||||
|
||||
```shell
|
||||
### Built-in outbounds: block, direct, must_direct
|
||||
# The difference between "direct" and "must_direct" is that "direct" will intercept and process DNS request (for traffic
|
||||
### Built-in outbounds: block, direct
|
||||
# The difference between "direct" and "must_direct" is that "direct" will hijack and process DNS request (for traffic
|
||||
# split use), but "must_direct" will not. "must_direct" is useful when there are traffic loops of DNS requests.
|
||||
# "must_direct" can be written as "direct(must)".
|
||||
# Similarly, "must_groupname" is also supported to NOT hijack and process DNS traffic, which equals to "groupname(must)".
|
||||
|
||||
### fallback outbound
|
||||
# If no rule matches, traffic will go through the outbound defined by fallback.
|
||||
@ -14,7 +16,7 @@ fallback: my_group
|
||||
### Domain rule
|
||||
domain(suffix: v2raya.org) -> my_group
|
||||
# equals to domain(v2raya.org) -> my_group
|
||||
domain(full: dns.google) -> my_group
|
||||
domain(full: dns.google.com) -> my_group
|
||||
domain(keyword: facebook) -> my_group
|
||||
domain(regexp: '\.goo.*\.com$') -> my_group
|
||||
domain(geosite:category-ads) -> block
|
||||
|
@ -15,7 +15,7 @@ global {
|
||||
# This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check
|
||||
# TCP DNS connectivity of nodes.
|
||||
# This DNS should have both IPv4 and IPv6 if you have double stack in local.
|
||||
udp_check_dns: 'dns.google:53'
|
||||
udp_check_dns: 'dns.google.com:53'
|
||||
|
||||
check_interval: 30s
|
||||
|
||||
@ -87,7 +87,7 @@ dns {
|
||||
# If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended.
|
||||
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
googledns: 'tcp+udp://dns.google:53'
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
}
|
||||
routing {
|
||||
# According to the request of dns query, decide to use which DNS upstream.
|
||||
|
Loading…
Reference in New Issue
Block a user