mirror of
https://github.com/daeuniverse/dae.git
synced 2025-07-18 03:39:43 +07:00
refactor(/docs): rework documentation structure layout (#179)
* refactor(/docs): rework documentation structure layout * refactor(/docs): update file reference paths * feat(/docs): add English version of other-proxy-protocol.md * refacotr: move docs/templates/ docs/sync/ to hack/ * fix(example.dae|readme): update ref link to adopt new file structure * refactor: rename other-proxy-protocol.md -> proxy-protocols.md * docs(readme): add ref to proxy-protocols.md * feat(/docs): add English version of how-it-works.md * refactor: rename how-it-works; add nav links * fix: fix linting errors * fix: fix linting errors --------- Co-authored-by: earrmouth <43926351+earrmouth@users.noreply.github.com>
This commit is contained in:
227
docs/zh/README.md
Normal file
227
docs/zh/README.md
Normal file
@ -0,0 +1,227 @@
|
||||
# 吃鹅直通手册
|
||||
|
||||
## Linux 内核要求
|
||||
|
||||
### 内核版本
|
||||
|
||||
使用 `uname -r` 来查看内核版本。
|
||||
|
||||
> **注意**
|
||||
> 如果你的内核版本低于 `5.8`,可以参考 [**Upgrade Guide**](../en/user-guide/kernel-upgrade.md) 升级你的内核。
|
||||
|
||||
`绑定到 LAN 接口: >= 5.8`
|
||||
|
||||
如果你想作为路由器、网桥等中间设备,为其他设备提供代理服务,需要把 dae 绑定到 LAN 接口上。
|
||||
|
||||
该特性要求 dae 所在的设备的内核版本 >= 5.8。
|
||||
|
||||
如果你只在 `lan_interface` 中填写了接口,而未在 `wan_interface` 中填写内容,那么本地程序将无法被代理。如果你期望代理本地程序,需要在 `wan_interface` 中填写 `auto` 或是手动输入 WAN 接口。
|
||||
|
||||
`绑定到 WAN 接口: >= 5.8`
|
||||
|
||||
如果你想为本地程序提供代理服务,需要把 dae 绑定到 WAN 接口上。
|
||||
|
||||
该特性要求 dae 所在的设备的内核版本 >= 5.8。
|
||||
|
||||
如果你只在 `wan_interface` 中填写了接口或 `auto`,而未在 `lan_interface` 中填写内容,那么从局域网中传来的流量将无法被代理。如果你想同时代理本机和局域网流量,请同时填写 `wan_interface` 和 `lan_interface`。
|
||||
|
||||
## 内核配置选项
|
||||
|
||||
通常,主流桌面发行版都会打开这些选项。但是为了减小内核大小,在嵌入式设备发行版(如 OpenWRT、Armbian 等)上这些选项可能处于关闭状态。使用以下命令在你的设备上显示内核配置选项:
|
||||
|
||||
```shell
|
||||
zcat /proc/config.gz || cat /boot/{config,config-$(uname -r)}
|
||||
```
|
||||
|
||||
dae 需要以下内核选项:
|
||||
|
||||
```
|
||||
CONFIG_BPF=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
CONFIG_NET_EGRESS=y
|
||||
CONFIG_NET_SCH_INGRESS=m
|
||||
CONFIG_NET_CLS_BPF=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_BPF_STREAM_PARSER=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_DEBUG_INFO_REDUCED is not set
|
||||
CONFIG_DEBUG_INFO_BTF=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
CONFIG_BPF_EVENTS=y
|
||||
```
|
||||
|
||||
你可以通过以下命令检查他们:
|
||||
|
||||
```shell
|
||||
(zcat /proc/config.gz || cat /boot/{config,config-$(uname -r)}) | grep -E 'CONFIG_(DEBUG_INFO|DEBUG_INFO_BTF|KPROBES|KPROBE_EVENTS|BPF|BPF_SYSCALL|BPF_JIT|BPF_STREAM_PARSER|NET_CLS_ACT|NET_SCH_INGRESS|NET_INGRESS|NET_EGRESS|NET_CLS_BPF|BPF_EVENTS|CGROUPS)=|# CONFIG_DEBUG_INFO_REDUCED is not set'
|
||||
```
|
||||
|
||||
> **注意**: `Armbian` 用户可以参考 [**Upgrade Guide**](../en/user-guide/kernel-upgrade.md) 升级到支持的内核。
|
||||
|
||||
## 安装
|
||||
|
||||
### Archlinux/Manjaro
|
||||
|
||||
dae 已发布于 [AUR](https://aur.archlinux.org/packages/dae),使用下述命令安装:
|
||||
|
||||
```shell
|
||||
# yay -S dae
|
||||
pacman -S --needed git base-devel
|
||||
git clone https://aur.archlinux.org/dae.git
|
||||
cd dae
|
||||
makepkg -si
|
||||
```
|
||||
|
||||
安装后,使用 systemctl 对服务进行控制:
|
||||
|
||||
```shell
|
||||
# 启动 dae
|
||||
sudo systemctl start dae
|
||||
|
||||
# 开机自动启动 dae
|
||||
sudo systemctl enable dae
|
||||
```
|
||||
|
||||
### Gentoo Linux
|
||||
|
||||
dae 已发布于 [gentoo-zh](https://github.com/microcai/gentoo-zh),可以使用 `app-eselect/eselect-repository` 启用此 overlay:
|
||||
|
||||
```shell
|
||||
eselect repository enable gentoo-zh
|
||||
emaint sync -r gentoo-zh
|
||||
emerge -a net-proxy/dae
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
我们提供了一种比较 hacky 的方式在 macOS 上运行 dae,见 [run on macOS](../en/tutorials/run-on-macos.md)。
|
||||
|
||||
### Docker
|
||||
|
||||
预编译镜像可相关文档请查阅:<https://hub.docker.com/r/daeuniverse/dae>。
|
||||
|
||||
作为替代,你也可以使用 `docker compose`:
|
||||
|
||||
```shell
|
||||
git clone --depth=1 https://github.com/daeuniverse/dae
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
### 手动安装
|
||||
|
||||
> **Note**: 这种方法仅建议高级用户使用。采用这种方法,用户可以灵活地测试各个版本的 dae。请注意,新引入的功能有时可能存在 bug,因此请自行承担风险。
|
||||
|
||||
dae 可以以守护进程(systemd)的形式运行,见 [run as daemon](../en/user-guide/run-as-daemon.md)。
|
||||
|
||||
### 安装脚本
|
||||
|
||||
见 [daeuniverse/dae-installer](https://github.com/daeuniverse/dae-installer)(或使用 [镜像站](https://hubmirror.v2raya.org/daeuniverse/dae-installer))。
|
||||
|
||||
### 手动构建
|
||||
|
||||
见 [Build Guide](../en/user-guide/build-by-yourself.md)。
|
||||
|
||||
## 最小 dae 配置
|
||||
|
||||
最小可启动的配置:
|
||||
|
||||
```shell
|
||||
global{}
|
||||
routing{}
|
||||
```
|
||||
|
||||
然而,此配置使 dae 处于空载状态。如果你希望 dae 能正常工作,以下是较小配置下的最佳实践:
|
||||
|
||||
```shell
|
||||
global {
|
||||
# 绑定到 LAN 和/或 WAN 接口。将下述接口替换成你自己的接口名。
|
||||
#lan_interface: docker0
|
||||
wan_interface: auto # 使用 "auto" 自动侦测 WAN 接口。
|
||||
|
||||
log_level: info
|
||||
allow_insecure: false
|
||||
auto_config_kernel_parameter: true
|
||||
}
|
||||
|
||||
subscription {
|
||||
# 在下面填入你的订阅链接。
|
||||
}
|
||||
|
||||
# 更多的 DNS 样例见 https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/dns.md
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
request {
|
||||
fallback: alidns
|
||||
}
|
||||
response {
|
||||
upstream(googledns) -> accept
|
||||
!qname(geosite:cn) && ip(geoip:private) -> googledns
|
||||
fallback: accept
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group {
|
||||
proxy {
|
||||
#filter: name(keyword: HK, keyword: SG)
|
||||
policy: min_moving_avg
|
||||
}
|
||||
}
|
||||
|
||||
# 更多的 Routing 样例见 https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md
|
||||
routing {
|
||||
pname(NetworkManager, systemd-resolved, dnsmasq) -> must_direct
|
||||
dip(224.0.0.0/3, 'ff00::/8') -> direct
|
||||
|
||||
### 以下为自定义规则
|
||||
|
||||
dip(geoip:private) -> direct
|
||||
dip(geoip:cn) -> direct
|
||||
domain(geosite:cn) -> direct
|
||||
|
||||
fallback: proxy
|
||||
}
|
||||
```
|
||||
|
||||
如果你不在乎极致速度,而是更注重隐私和 DNS 泄露,使用以下配置替换上述的 dns 部分:
|
||||
|
||||
```shell
|
||||
dns {
|
||||
upstream {
|
||||
googledns: 'tcp+udp://dns.google.com:53'
|
||||
alidns: 'udp://dns.alidns.com:53'
|
||||
}
|
||||
routing {
|
||||
request {
|
||||
qname(geosite:cn) -> alidns
|
||||
fallback: googledns
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
完整样例:[example.dae](https://github.com/daeuniverse/dae/blob/main/example.dae)。
|
||||
|
||||
如果你使用 PVE,可以参考 [#37](https://github.com/daeuniverse/dae/discussions/37)。
|
||||
|
||||
## 热重载和暂停
|
||||
|
||||
当配置变化时,可以方便使用命令进行配置的热重载,在该过程中不会中断已有连接。当想暂停代理时,可使用命令进行暂停。
|
||||
|
||||
详见 [Reload and suspend](../en/user-guide/reload-and-suspend.md)。
|
||||
|
||||
## 错误排查
|
||||
|
||||
详见 [Troubleshooting](../en/troubleshooting.md)。
|
||||
|
||||
## 大鹅宇宙
|
||||
|
||||
Telegram: <https://t.me/daeuniverse>
|
59
docs/zh/how-it-works.md
Normal file
59
docs/zh/how-it-works.md
Normal file
@ -0,0 +1,59 @@
|
||||
# dae 的工作原理
|
||||
|
||||
dae 通过 [eBPF](https://en.wikipedia.org/wiki/EBPF) 在 Linux 内核的 tc (traffic control) 挂载点加载一个程序,通过该程序在流量进入 TCP/IP 网络栈之前进行流量分流。tc 在 Linux 网络协议栈中的位置见下图所示(图为收包路径,发包路径方向相反),其中 netfilter 是 iptables/nftables 的位置。
|
||||
|
||||

|
||||
|
||||
## 分流原理
|
||||
|
||||
### 分流信息
|
||||
|
||||
dae 支持以域名、源 IP、目的 IP、源端口、目的端口、TCP/UDP、IPv4/IPv6、进程名、MAC 地址等对流量进行分流。
|
||||
|
||||
其中,源 IP、目的 IP、源端口、目的端口、TCP/UDP、IPv4/IPv6、MAC 地址均可解析 MACv2 帧而得到。
|
||||
|
||||
**进程名**通过在 cgroupv2 挂载点侦听本地进程的 socket、connect、sendmsg 系统调用,并读取和解析进程控制块中的命令行来得到的。这种方式会比 clash 等用户态程序对传入的 socket 扫描整个 procfs 来得到进程信息要快得多(后者甚至是 10ms 级的)。
|
||||
|
||||
**域名**通过劫持 DNS 请求,将 DNS 请求的域名与所查 IP 进行关联来得到。尽管这种方式有一些问题:
|
||||
|
||||
1. 可能会出现误判。例如需要分流到国内和国外的两个网站拥有同一个 IP,且在短时间内同时被访问,或浏览器有 DNS 缓存。
|
||||
2. 用户的 DNS 请求必须通过 dae。例如将 dae 设为 DNS,或在 dae 作为网关的情况下使用公共 DNS。
|
||||
|
||||
但相比其他方案,这种方案已经是较优解了。例如 Fake IP 方案存在无法通过 IP 分流且存在严重的缓存污染问题,而域名嗅探方案存在只能嗅探 TLS/HTTP 等流量的问题。实际上,通过 SNI 嗅探来进行分流确实是更优选择,但由于 eBPF 对程序复杂度的限制,以及对循环的支持不友好,我们无法在内核空间实现域名嗅探。
|
||||
|
||||
因此,当 DNS 请求无法通过 dae 时,基于 domain 的分流将会失效。
|
||||
|
||||
> 为了降低 DNS 污染,以及获得更好的 CDN 连接速度,dae 在用户空间实现了域名嗅探。在 `dial_mode` 为 domain 或 domain 的变体,且流量需要被代理时,将嗅探的 domain 发送给代理服务器,而不是发送 IP,这样在代理服务器侧会对域名重新进行解析并使用最优 IP 进行连接,从而解决了 DNS 污染的问题,并获得了更好的 CDN 连接速度。
|
||||
>
|
||||
> 同时,当高级用户已经使用了其他的分流方案,且不希望将 DNS 请求通过 dae,但希望被代理的那部分流量可以基于域名进行分流(例如基于目标域名,一部分分流到奈飞节点,一部分分流到下载节点,当然,也可以一部分通过 core 直连),可以通过 `dial_mode: domain++` 来强制使用嗅探的域名重新分流。
|
||||
|
||||
dae 会通过在 tc 挂载点的程序将流量分流,根据分流结果决定重定向到 dae 的 tproxy 端口或放其直连。
|
||||
|
||||
### 代理原理
|
||||
|
||||
dae 的代理原理和其他程序近似。区别是在绑定 LAN 接口时,dae 通过 eBPF 将 tc 挂载点的需代理流量的 socket buffer 直接关联至 dae 的 tproxy 侦听端口的 socket;在绑定 WAN 接口时,dae 将需代理流量 socket buffer 从网卡出队列移动至网卡的入队列,禁用其 checksum,并修改目的地址为 tproxy 侦听端口。
|
||||
|
||||
以 benchmark 来看,dae 的代理性能比其他代理程序好一些,但不多。
|
||||
|
||||
### 直连原理
|
||||
|
||||
一直以来,为了分流,流量需要经过代理程序,经过分流模块之后,再决定是直连还是代理。这样流量需要经过网络栈的解析、处理、拷贝,传入代理程序,再通过网络栈拷贝、处理、封装,然后传出,消耗大量资源。特别是对于 BT 下载等场景,尽管设置了直连,仍然会占用大量连接数、端口、内存、CPU 资源。甚至对于游戏的场景,会由于代理程序的处理不当而影响 NAT 类型,导致连接出错。
|
||||
|
||||
dae 在内核的较早路径上就对流量进行了分流,直连流量将直接进行三层路由转发,节省了大量内核态到用户态的切换和拷贝开销,此时 Linux 相当于一个纯粹的交换机或路由器。
|
||||
|
||||
> 为了让直连生效,对于高级拓扑的用户,请确保按 [kernel-parameters](../en/user-guide/kernel-parameters.md) 配置后,在**关闭** dae 的情况下,其他设备将 dae 所在设备设为网关时,网络是畅通的。例如访问 223.5.5.5 能够得到“UrlPathError”的响应,且在 dae 所在设备进行 tcpdump 可以看到客户端设备的请求报文。
|
||||
|
||||
因此,对于直连流量,dae 不会进行 SNAT,对于“旁路由”用户,这将形成非对称路由,即客户端设备发包时流量通过 dae 设备发送到网关,收包时由网关直接发给客户端设备,绕过 dae 设备。
|
||||
|
||||
> 这里的旁路由定义为:1,被设为网关。2,对 TCP/UDP 进行 SNAT。3,LAN 接口和 WAN 接口属于同一个网段。
|
||||
>
|
||||
> 例如笔记本电脑在 192.168.0.3,旁路由在 192.168.0.2,路由器在 192.168.0.1。三层逻辑拓扑为:笔记本电脑 -> 旁路由 -> 路由器,且在路由器一侧只能看到源 IP 是 192.168.0.2 的 TCP/UDP 流量,而没有 192.168.0.3 的 TCP/UDP 流量。
|
||||
>
|
||||
> 据目前所知,我们是第一个对旁路由进行定义的(笑)。
|
||||
|
||||
非对称路由将带来一个优点和一个可能的问题:
|
||||
|
||||
1. 会带来性能提升。由于回包不经过 dae,减少了路径,直连性能将变得和没有旁路由一样快。
|
||||
2. 会导致高级防火墙的状态维护失效从而丢包(例如 Sophos Firewall)。这一问题在家用网络中一般不会出现。
|
||||
|
||||
以 benchmark 来看,dae 的直连性能和其他代理程序相比就像个怪物。
|
48
docs/zh/proxy-protocols.md
Normal file
48
docs/zh/proxy-protocols.md
Normal file
@ -0,0 +1,48 @@
|
||||
# 其他代理协议
|
||||
|
||||
> **Note**: dae 目前支持以下代理协议
|
||||
|
||||
- [x] HTTP(S), naiveproxy
|
||||
- [x] Socks
|
||||
- [x] Socks4
|
||||
- [x] Socks4a
|
||||
- [x] Socks5
|
||||
- [x] VMess(AEAD, alterID=0) / VLESS
|
||||
- [x] TCP
|
||||
- [x] WS
|
||||
- [x] TLS
|
||||
- [x] gRPC
|
||||
- [x] Shadowsocks
|
||||
- [x] AEAD Ciphers
|
||||
- [x] Stream Ciphers
|
||||
- [x] simple-obfs
|
||||
- [ ] v2ray-plugin
|
||||
- [x] ShadowsocksR
|
||||
- [x] Trojan
|
||||
- [x] Trojan-gfw
|
||||
- [x] Trojan-go
|
||||
- [x] Tuic (v5)
|
||||
|
||||
有其他需求的,一种方式是通过外接其他代理程序来扩展协议支持。下面给出外接 naiveproxy 的例子。
|
||||
|
||||
尽管 dae 等代理程序支持 HTTPS 协议,但由于并不使用 chromium 网络栈,削弱了 naiveproxy 的伪装效果,因此可以选择外接 naiveproxy 程序来实现。
|
||||
|
||||
1. 启动 naiveproxy:
|
||||
|
||||
由于 naiveproxy 的 socks 实现可能有些问题,无法被 curl 和 dae 使用,样例中使用 naiveproxy 开启一个 HTTP 监听端口。注意,HTTP 代理不支持代理 udp 流量,所以如果你外接其他代理程序,建议优先考虑使用 socks5 端口。
|
||||
|
||||
```bash
|
||||
naiveproxy --listen=http://127.0.0.1:1090 --proxy=https://yourlink
|
||||
```
|
||||
|
||||
2. 在 dae 配置的 node 一节中,新增一行:`http://127.0.0.1:1090`,并记得在所使用的组中使用该节点。
|
||||
|
||||
3. 如果你绑定了 WAN 接口,即在 `global.wan_interface` 填写了内容,确保在 routing 一节的靠上位置增加一行,以避免流量从 dae 流向 naiveproxy 之后再次流向 dae,造成回环:
|
||||
|
||||
```shell
|
||||
pname(naiveproxy) -> must_direct
|
||||
```
|
||||
|
||||
这里的 pname 的含义是进程名。你可通过启动时的命令,或运行时通过 `ps -ef` 命令或者观察 dae 的日志来确定 naiveproxy 的进程名。must_direct 的含义是所有流量,包括 dns 查询都放行直连,不重定向至 dae。
|
||||
|
||||
只绑定 LAN 接口的用户不需要做这一步。
|
Reference in New Issue
Block a user