dae手动编译安装与配置

安装

编译依赖要求

1
2
3
4
5
6
# clang >= 10
llvm >= 10 (optional)
golang >= 1.18
make
# 安装(如果是及以上ubunut22.04,对应版本都满足)
$ sudo apt install clang llvm golang make -y

编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 将dae源码clone到本地
$ git clone https://github.com/daeuniverse/dae.git
# 进入dae文件夹
$ cd dae
# 初始化并更新子模块
$ git submodule update --init

# 最小依赖编译,这里的"\",是换行输入符号,目的是将指令换行书写便于查看
$ make GOFLAGS="-buildvcs=false" \
CC=clang

# 常规编译
make

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
# 编译后可在当前文件夹得到可二进制文件dae
# 给予可执行权限
sudo chmod +x ./dae

# 将文件添加到/usr/bin
sudo install -Dm755 dae /usr/bin/

# dae的帮助信息
dae [-h,--help]

# 版本信息查看
dae version

配置

运行使得依赖安装

  • 安装分流规则依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建dae文件夹
$ mkdir -p /usr/local/share/dae/

# pushd是暂时切换到指定路径,在pushd /your/directory/ 和 popd之间的指令都会
# 使用/your/directory的文件路径
$ pushd /usr/local/share/dae/

# 下载geoip.dat和geosite.dat文件,若由于网络问题下载报错,可以到相应的github地址下载,并解压到该目录下
$ curl -L -o geoip.dat https://github.com/v2fly/geoip/releases/latest/download/geoip.dat
$ curl -L -o geosite.dat https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat

# 回到之前的文件路径
$ popd
  • 下载dea配置文件
1
2
3
# 创建dae配置文件夹,并进入该路径,将配置文件放到这里,dae会默认先加载该配置文件
$ sudo mkdir -p /etc/dae && cd /etc/dae/
$ curl -L -o config.dae https://github.com/daeuniverse/dae/raw/main/example.dae
  • 配置文件内容
    个人配置只需要配置订阅地址或节点配置信息,其他配置默认就可以正常使用了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
global {
##### Software options.

# tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.
# In normal case, you do not need to use it.
tproxy_port: 12345

# Set it true to protect tproxy port from unsolicited traffic. Set it false to allow users to use self-managed
# iptables tproxy rules.
tproxy_port_protect: true

# If not zero, traffic sent from dae will be set SO_MARK. It is useful to avoid traffic loop with iptables tproxy
# rules.
so_mark_from_dae: 0

# Log level: error, warn, info, debug, trace.
log_level: info

# Disable waiting for network before pulling subscriptions.
disable_waiting_network: false


##### Interface and kernel options.

# The LAN interface to bind. Use it if you want to proxy LAN.
# Multiple interfaces split by ",".
#lan_interface: docker0

# The WAN interface to bind. Use it if you want to proxy localhost.
# Multiple interfaces split by ",". Use "auto" to auto detect.
wan_interface: auto

# Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out
# https://github.com/daeuniverse/dae/blob/main/docs/en/user-guide/kernel-parameters.md to see what will dae do.
auto_config_kernel_parameter: true

##### Node connectivity check.

# Host of URL should have both IPv4 and IPv6 if you have double stack in local.
# First is URL, others are IP addresses if given.
# Considering traffic consumption, it is recommended to choose a site with anycast IP and less response.
#tcp_check_url: 'http://cp.cloudflare.com'
tcp_check_url: 'http://cp.cloudflare.com,1.1.1.1,2606:4700:4700::1111'

# The HTTP request method to `tcp_check_url`. Use 'HEAD' by default because some server implementations bypass
# accounting for this kind of traffic.
tcp_check_http_method: HEAD

# 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.
# First is URL, others are IP addresses if given.
# This DNS should have both IPv4 and IPv6 if you have double stack in local.
#udp_check_dns: 'dns.google.com:53'
udp_check_dns: 'dns.google.com:53,8.8.8.8,2001:4860:4860::8888'

check_interval: 30s

# Group will switch node only when new_latency <= old_latency - tolerance.
check_tolerance: 50ms


##### Connecting options.

# Optional values of dial_mode are:
# 1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path
# respectively, and makes the IP version requested by the application meet expectations. For example, if you
# use curl -4 ip.sb, you will request IPv4 via proxy and get a IPv4 echo. And curl -6 ip.sb will request IPv6.
# This may solve some wierd full-cone problem if your are be your node support that. Sniffing will be disabled
# in this mode.
# 2. "domain". Dial proxy using the domain from sniffing. This will relieve DNS pollution problem to a great extent
# if have impure DNS environment. Generally, this mode brings faster proxy response time because proxy will
# re-resolve the domain in remote, thus get better IP result to connect. This policy does not impact routing.
# That is to say, domain rewrite will be after traffic split of routing and dae will not re-route it.
# 3. "domain+". Based on domain mode but do not check the reality of sniffed domain. It is useful for users whose
# DNS requests do not go through dae but want faster proxy response time. Notice that, if DNS requests do not
# go through dae, dae cannot split traffic by domain.
# 4. "domain++". Based on domain+ mode but force to re-route traffic using sniffed domain to partially recover
# domain based traffic split ability. It doesn't work for direct traffic and consumes more CPU resources.
dial_mode: domain

# Allow insecure TLS certificates. It is not recommended to turn it on unless you have to.
allow_insecure: false

# Timeout to waiting for first data sending for sniffing. It is always 0 if dial_mode is ip. Set it higher is useful
# in high latency LAN network.
sniffing_timeout: 100ms

# TLS implementation. tls is to use Go's crypto/tls. utls is to use uTLS, which can imitate browser's Client Hello.
tls_implementation: tls

# The Client Hello ID for uTLS to imitate. This takes effect only if tls_implementation is utls.
# See more: https://github.com/daeuniverse/dae/blob/331fa23c16/component/outbound/transport/tls/utls.go#L17
utls_imitate: chrome_auto
}

# Subscriptions defined here will be resolved as nodes and merged as a part of the global node pool.
# Support to give the subscription a tag, and filter nodes from a given subscription in the group section.
subscription {
# Add your subscription links here.
# 添加个人订阅
my_sub: 'https://www.example.com/subscription/link'
# another_sub: 'https://example.com/another_sub'
'https://example.com/no_tag_link'
'file://relative/path/to/mysub.sub' # Put subscription content in /etc/dae/relative/path/to/mysub.sub
}

# Nodes defined here will be merged as a part of the global node pool.
node {
# Add your node links here.
# 添加个人节点信息
# Support socks5, http, https, ss, ssr, vmess, vless, trojan, tuic, juicity, etc.
# Full support list: https://github.com/daeuniverse/dae/blob/main/docs/en/proxy-protocols.md
'socks5://localhost:1080'
mylink: 'ss://LINK'
node1: 'vmess://LINK'
node2: 'vless://LINK'
chains: 'tuic://LINK -> vmess://LINK'
}

# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/dns.md for full examples.
dns {
# For example, if ipversion_prefer is 4 and the domain name has both type A and type AAAA records, the dae will only
# respond to type A queries and response empty answer to type AAAA queries.
#ipversion_prefer: 4

# Give a fixed ttl for domains. Zero means that dae will request to upstream every time and not cache DNS results
# for these domains.
#fixed_domain_ttl {
# ddns.example.org: 10
# test.example.org: 3600
#}

upstream {
# Value can be scheme://host:port, where the scheme can be tcp/udp/tcp+udp.
# If host is a domain and has both IPv4 and IPv6 record, dae will automatically choose
# IPv4 or IPv6 to use according to group policy (such as min latency policy).
# Please make sure DNS traffic will go through and be forwarded by dae, which is REQUIRED for domain routing.
# 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.com:53'
}
routing {
# According to the request of dns query, decide to use which DNS upstream.
# Match rules from top to bottom.
request {
# Lookup China mainland domains using alidns, otherwise googledns.
qname(geosite:cn) -> alidns
# fallback is also called default.
fallback: googledns
}
}
# routing {
# # According to the request of dns query, decide to use which DNS upstream.
# # Match rules from top to bottom.
# request {
# # fallback is also called default.
# fallback: alidns
# }
# # According to the response of dns query, decide to accept or re-lookup using another DNS upstream.
# # Match rules from top to bottom.
# response {
# # Trusted upstream. Always accept its result.
# upstream(googledns) -> accept
# # Possibly polluted, re-lookup using googledns.
# ip(geoip:private) && !qname(geosite:cn) -> googledns
# # fallback is also called default.
# fallback: accept
# }
# }
}

# Node group (outbound).
group {
my_group {
# No filter. Use all nodes.

# Randomly select a node from the group for every connection.
#policy: random

# Select the first node from the group for every connection.
#policy: fixed(0)

# Select the node with min last latency from the group for every connection.
#policy: min

# Select the node with min moving average of latencies from the group for every connection.
policy: min_moving_avg
}

group2 {
# Filter nodes from the global node pool defined by the subscription and node section above.
#filter: subtag(my_sub) && !name(keyword: 'ExpireAt:')
# Multiple filters indicate 'or' logic.
#filter: subtag(regex: '^my_', another_sub) && !name(keyword: 'ExpireAt:')

# Filter nodes from the global node pool defined by tag.
#filter: name(node1, node2)

# Filter nodes and give a fixed latency offset to archive latency-based failover.
# In this example, there is bigger possibility to choose US node even if original latency of US node is higher.
filter: name(HK_node)
filter: name(US_node) [add_latency: -500ms]

# Select the node with min average of the last 10 latencies from the group for every connection.
policy: min_avg10
}
}

# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md for full examples.
routing {
### Preset rules.

# Network managers in localhost should be direct to avoid false negative network connectivity check when binding to
# WAN.
pname(NetworkManager) -> direct

# Put it in the front to prevent broadcast, multicast and other packets that should be sent to the LAN from being
# forwarded by the proxy.
# "dip" means destination IP.
dip(224.0.0.0/3, 'ff00::/8') -> direct

# This line allows you to access private addresses directly instead of via your proxy. If you really want to access
# private addresses in your proxy host network, modify the below line.
dip(geoip:private) -> direct

### Write your rules below.

# Disable h3 because it usually consumes too much cpu/mem resources.
l4proto(udp) && dport(443) -> block
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct

fallback: my_group
}

运行

  • 将dae以守护服务的方式运行,即使用systemd
1
2
3
4
5
6
7
8
9
10
11
# 下载范例的systemd.service
$ sudo curl -L -o /etc/systemd/system/dae.service https://github.com/daeuniverse/dae/raw/main/install/dae.service

# 重新加载守护进程,使得dae.service被识别
$ sudo systemctl daemon-reload

# 设置开机自启动,--now使其现在就开启服务
$ sudo systemctl enable dae --now

# 查看dae的状态
$ sudo systemctl status dae
  • 查看日志
1
$ sudo journalctl -xefu dae
  • 常用指令
1
2
3
4
5
# 暂停运行
$ dae suspend

# 重新加载配置
$ dae reload

Ref