V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LEXUGE
V2EX  ›  DNS

dcompass - 纯 Rust 实现的高性能混合 DNS 服务器

  •  
  •   LEXUGE · 10 天前 via iPhone · 2914 次点击

    https://github.com/LEXUGE/dcompass

    具体内容都在 GitHub 里,功能大概为: 高速( 760 qps ) 自由路由规则,支持递归嵌套,且提供完整运行前功能检查 支持 DoH (未来支持 UDP ) 缓存持久化,应对恶劣网络环境 应对网络环境热切换(不会出现 SmartDNS Wi-Fi 换 4G 直接 DoH 断连的问题) IPv6 AAAA 屏蔽 选择性 SNI 发送,防止 SNI 被侦测 纯 Rust 实现 轻量域名匹配( 160 us per match )

    目前自用体验良好,deploy it and forget it 自测速度快于 smartdns ( 640 qps )

    nixos 用户可以看一下 https://github.com/icebox-nix/netkit.nix ,内含打包好的 dcompass 以及可以直接使用的 nixos module

    第 1 条附言  ·  10 天前
    qps 是真实网络环境下多次测试结果,不是 mock test
    第 2 条附言  ·  8 天前
    目前提供 windows, linux, linux-armv7, macos 的 binary
    https://github.com/LEXUGE/dcompass/actions/runs/373581534
    欢迎下载测试
    48 条回复    2020-11-22 15:37:28 +08:00
    billzhuang
        1
    billzhuang   10 天前 via iPhone
    支持下,阅读代码中
    no1xsyzy
        2
    no1xsyzy   10 天前
    建议发 /go/create
    lbp0200
        3
    lbp0200   10 天前
    异步模型用的协程吗?
    LEXUGE
        4
    LEXUGE   10 天前
    @lbp0200 (不是很了解具体术语)是基于 tokio runtime 的,目前因为 tokio 0.2 和 0.3 的迁移,upstream 是 single-threaded 的,event loop 是 multi-threaded. 未来迁移以后可能性能会更好一些
    xarthur
        5
    xarthur   10 天前
    支持 ipset 吗?
    tpsxiong
        6
    tpsxiong   10 天前 via Android
    支持 unbound 那样的迭代查询不
    LEXUGE
        7
    LEXUGE   10 天前 via iPhone
    @xarthur 目前还不支持,但是代码设计的时候就考虑到这点了
    LEXUGE
        8
    LEXUGE   10 天前 via iPhone
    @tpsxiong recursive query 吗,只要请求写了 recursive needed 的话上游就会支持,因为实际上这是一个 DNS 转发服务器
    shynome
        9
    shynome   10 天前 via Android
    qps 要讲在什么配置下的,不同配置下的 qps 不同
    LEXUGE
        10
    LEXUGE   10 天前 via iPhone   ❤️ 1
    @shynome 我给两个测试用了相同语义的配置。虽然数据会有变化,但是还是能反应在相同网络环境和相同设备上的速度的。
    Jirajine
        11
    Jirajine   10 天前 via Android
    不错,正好也想用 rust 实现一个 dns 转发器。
    提几个建议:
    1. 配置文件支持 yaml/toml 。
    2. 把核心逻辑抽出来写成 lib,方便调用。
    3. 支持更多规则,正则、abp 等。
    4. 支持扩展插件,弄个 Python 脚本或者像 coredns 一样留个框架让用户自己添加代码再重编译。
    Jirajine
        12
    Jirajine   10 天前 via Android
    以及 smartdns 特有的 过期缓存、prefetch 、速度测试等,这样就可以完全替代,解决 smartdns 仅 Linux 可用的问题。
    LEXUGE
        13
    LEXUGE   10 天前 via iPhone
    @Jirajine 插件还未考虑,不过核心逻辑 droute 是一个 lib,且提供 trait 支持自己实现匹配规则
    Jirajine
        14
    Jirajine   10 天前 via Android
    @LEXUGE 我这里指的插件主要是 hook,让用户在处理请求时注入自己的自定义代码。
    大概是这样:
    fn process_dns(&c: Context){
    plugin_A(c);
    plugin_B(c);
    // 用户自己实现一个函数或类型,然后插入到这里。
    }
    然后在你自己的核心逻辑中调用 process_dns 函数。
    tpsxiong
        15
    tpsxiong   10 天前
    @LEXUGE iterative dns query
    zro
        16
    zro   10 天前
    能不能像 dnsmasq 那样可以有 add-subnet 选项,配合上游 EDNS 。。

    好像没找到其他能 add-subnet 的 DNS 转发,包括 unbound~~
    LEXUGE
        17
    LEXUGE   10 天前 via iPhone
    @zro 目前只做了包转发,added to the todo list
    INTEL2333
        18
    INTEL2333   10 天前 via Android
    话说大佬,能不能做个双栈 EDNS
    v4 和 v6 非同一个运营商提供的时候非常难受

    比如 A 记录走 8888,AAAA 记录走 2001:4860:4860::8888

    或者

    向 8.8.8.8 发送两次查询,EDNS 分别对应 v4 和 v6
    zro
        19
    zro   10 天前
    @INTEL2333 #18 应该跟你差不多,v6 是 HE 的,能说下你是什么方案吗?
    我现在的方案不太成熟,要开两个 unbound,其中一个只查 v6 。。。
    INTEL2333
        20
    INTEL2333   9 天前 via Android
    @zro 我现在是开了 2 个 adgh

    adgh1 是 v4 only

    adgh2 是选优模式,上游 adgh1 和 2001:4860:4860::8888

    不过出结果太慢了
    LEXUGE
        21
    LEXUGE   9 天前
    @zro EDNS 我没有
    @INTEL2333 可以考虑,不过我没有 v6 环境,很难测试
    LEXUGE
        22
    LEXUGE   9 天前
    新加入了 DNS over TLS 功能的支持
    INTEL2333
        23
    INTEL2333   9 天前 via Android
    @zro 还有个可能不符合你要求的解决方案,只用一个 adgh

    用 8.8.8.8 并过滤
    240e:*
    2408:*
    2409:*
    INTEL2333
        24
    INTEL2333   9 天前 via Android
    @LEXUGE 唔,应该不用 v6 环境也能测试,方案 2 的话,应该指定一下 edns 地址就可以了

    蟹蟹大佬啦
    HalloCQ
        25
    HalloCQ   9 天前
    @zro 支持 edns 的大把。overture,adguardhome 等等
    LEXUGE
        26
    LEXUGE   9 天前
    @HalloCQ overture 挺 buggy 的...我还修过一个 bug...也就是因为它和 smartdns 都很 buggy 我才决定自己写
    打算支持 EDNS,回去写个 roadmap
    HalloCQ
        27
    HalloCQ   9 天前
    @LEXUGE 我也没用它了,刚换成 adgh,感觉挺好用
    zgzh
        28
    zgzh   9 天前
    感谢~已经部署,成功运行,查询速度很快
    zro
        29
    zro   9 天前
    @INTEL2333 #23
    ADGH 要是能加上“只查询 IPv6”功能就好弄多了;像你这样 ADGH 开一个 v4 only 的,有遇到像这样的情况吗?
    手机挂 Surge 开 T 宝,查最近请求时发现,居然还会访问某个 v6 IP 的网站,无域名的;偶尔一打开又会问我要不要切换到美国版 T 宝。。但看 Surge 的请求,IP 归属地都是五星旗

    @HalloCQ #25

    ADGH 的 ECS settings:edns_client_subnet — Enable EDNS Client Subnet option. If enabled, AdGuard Home will be sending ECS extension to the upstream DNS servers. Please note, that this will be done for clients with public IP addresses only.

    从公网查询才有效果的。。因为我是在境外 VPS 搭,所以需要像 dnsmasq 的 add-subnet 这样的功能,没发现 ADGH 有其他 ECS 的设置~
    INTEL2333
        30
    INTEL2333   9 天前 via Android
    @zro 唔,没遇到过
    上面那个方案其实还可以节省一个 adgh

    上游 8.8.8.8 和 2001:4860:4860::64,选优模式

    过滤
    240e:*
    2408:*
    2409:*
    64:ff9b::*

    不过似乎会造成无 aaaa 的域名在查询 aaaa 记录时返回时间超过 1s
    INTEL2333
        31
    INTEL2333   9 天前 via Android
    @zro 话说淘宝会不会也有类似腾讯的 httpdns ?
    如果有的话似乎就难办了,只能 ip6tables 来 drop 了
    LEXUGE
        32
    LEXUGE   9 天前 via iPhone
    @zgzh 啊这,我都没法 crate,你直接 build 的吗
    我不敢保证现在不会有 breaking change,不过感谢支持
    zgzh
        33
    zgzh   9 天前
    @LEXUGE 是的 下载源码后 cargo build --release,在树莓派上顺利构建
    LEXUGE
        34
    LEXUGE   9 天前 via iPhone
    @zgzh 那我打算提供一下交叉编译版本
    HalloCQ
        35
    HalloCQ   8 天前
    @zro 因为你的 adgh 部署在服务器上,当你本地向 adgh 请求的时候,adgh 拿到的就是你的公网 ip 了
    HalloCQ
        36
    HalloCQ   8 天前
    @zro 就算运营商分配给你的不是公网 ip,但是你 adgh 是搭在一个外网的 vps 上,难道 adgh 还能拿到你的内网 ip 不成?
    zro
        37
    zro   8 天前
    @HalloCQ #35 Sorry,没说清楚,本地是以 VPN 跟外网 VPS 连的,所以 ADGH 根本不知道我的外网 IP 。。ADGH 没有对外暴露端口的~
    HalloCQ
        38
    HalloCQ   8 天前
    @zro 我是把 adgh 部署到国内服务器,然后分流。国内域名用 doh.pub ,国外域名请求 dns.google 。速度快的不行,还能去广告
    2001225354
        39
    2001225354   7 天前
    会有路由器版本么
    LEXUGE
        41
    LEXUGE   7 天前
    目前支持的架构有 x86_64-unknown-linux-musl, armv7-unknown-linux-musleabihf, armv5te-unknown-linux-musleabi, x86_64-pc-windows-gnu, x86_64-apple-darwin, aarch64-unknown-linux-musl 。
    已经测试的设备有:windows, linux, raspberry pi 3B+ (openwrt,使用 aarch64 ),都可以直接下载运行
    可能有问题的架构:apple-darwin (不知道为什么, GitHub Action 的 Catalina 编译出来 linker 会炸)
    未来可能会支持: mips
    大部分的架构都使用了 musl 静态编译,尽可能无依赖,欢迎测试
    有新的架构想加入 release 编译的 list 可以留言
    fengjianxinghun
        42
    fengjianxinghun   7 天前
    我也有个类似的。。。
    静态插件是这样
    pub static GLOBAL_MODULE_TABLES:Lazy<Mutex<Vec<Box<dyn Fn() -> Box<dyn PFilter<Output=PAction> + Send> + Send>>>> = Lazy::new(|| .....

    然后在 async/await hook 点生成新的 trait PFilter 对象
    fengjianxinghun
        43
    fengjianxinghun   7 天前
    还有,既然是 rust 。按照传统,建议支持 toml 配置。
    ysc3839
        44
    ysc3839   7 天前 via Android
    请问目前有实现 overture 的功能吗?
    希望实现先查询 A DNS,如果返回的 IP 数据匹配某个列表再去查询 B DNS,并返回 B DNS 的结果。
    目前似乎只有 overture 能实现这样的逻辑。
    LEXUGE
        45
    LEXUGE   7 天前
    @fengjianxinghun 求链接? toml 考虑支持
    @ysc3839 后期打算加入复杂服务端的配置(如 DoH 服务端),以及更加自由的路由配置(有点搞得像 table 了),这样可以部署在自己的服务器上
    LEXUGE
        46
    LEXUGE   7 天前
    @ysc3839 这么做其实有 blacklist 的意思,但是 IP blacklist 很难维护且感觉过滤效果不好。目前 dcompass 只支持 prequery 的 routing.
    ysc3839
        47
    ysc3839   7 天前 via Android
    @LEXUGE 这里的 list 是中国的 IP 地址,感觉是比较好维护的。主要是为了解决 CDN 的问题。
    LEXUGE
        48
    LEXUGE   6 天前
    @ysc3839 加入 todo list
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1880 人在线   最高记录 5268   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:00 · PVG 01:00 · LAX 09:00 · JFK 12:00
    ♥ Do have faith in what you're doing.