• WildHawk692

    最初我的需求只是网络走哪里,DNS 就跟着走哪里,这符合网络流量最短路径. 因此 基于域名匹配的 DNS 路由、 NFT set联动要被作为核心实现. 现在历时 15 天, 经过 108 次版本迭代, 我做成了它 且 开源.

    与dnsmasq不同的是,updns 提供了更灵活的 DNS 路由、 NFT set联动,除此之外它还支持 DoT、DoH 且拥有强大的 主动预取、 广告拦截 和 DNS 审计 能力。

    与smartdns不同的是,updns 在 OpenWrt 上提供了更简洁清晰的 Luci 交互、更严谨的 NFT set联动, 除此之外, updns 尊重本地网络, 不做 IP 端点 速度探测, 因为当下 运营商 提供的 DNS 在国内大部分网络已经路径最优, updns 做的是 获取本地解析文件, 自动将运营商 DNS 纳入可自行选择的上游之一. 这里说的有点多, 因为此前我也是 smartdns 用户, smartdns 做的也不错, 但是现在我放弃了它.

    来展示, 哈哈哈:

    OpenWrt → ~ # ping www.baidu.com
    PING www.baidu.com (2409:8c00:6c21:11eb:0:ff:b0bf:59ca): 56 data bytes
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=0 ttl=55 time=5.535 ms
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=1 ttl=55 time=5.462 ms
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=2 ttl=55 time=5.397 ms
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=3 ttl=55 time=5.507 ms
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=4 ttl=55 time=5.366 ms
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=5 ttl=55 time=5.126 ms
    64 bytes from 2409:8c00:6c21:11eb:0:ff:b0bf:59ca: seq=6 ttl=55 time=5.305 ms
    ^C
    --- www.baidu.com ping statistics ---
    7 packets transmitted, 7 packets received, 0% packet loss
    round-trip min/avg/max = 5.126/5.385/5.535 ms

    下面是 DNS 审计功能, 在 OpenWrt 你可以通过 updns <域名> 命令, 清晰获取指定域名 匹配的规则、选择的上游、加入了哪个 NFT Set 、解析结果是怎样:

    root:~# updns google.com

    ╭─ updns ──────────────────────────────────────────╮
    │
    │ DOMAIN
    │ ──────────────────────────────────────────────
    │ Domain : google.com.
    │ Query Type : A / AAAA
    │ Query Path : Cache Hit
    │
    │ DNS RESULT
    │ ──────────────────────────────────────────────
    │ Matched Rule : US Access
    │ Upstream : A=Google-DoH / AAAA=Google-DoH
    │ Action : IPv4 + IPv6
    │ Response : NOERROR
    │
    │ NFT SETS
    │ ──────────────────────────────────────────────
    │ IPv4 : inet/fw4/us4
    │ ✓ Contains resolved IPv4
    │ IPv6 : inet/fw4/us6
    │ ✓ Contains resolved IPv6
    │
    │ ANSWERS
    │ ──────────────────────────────────────────────
    │ • 142.251.219.142
    │ • 2607:f8b0:4005:818::200e
    │
    ╰──────────────────────────────────────────────────╯

    广告拦截 功能当然也有了, 你要做的只是把需要屏蔽的站点域名放入一个文件, 让 updns 来使用它, 下面我通过日志功能来展示它:

    Sat Nov 14 17:16:51 2026 daemon.info updns[18922]: QUERY [CLI] ad.xiaomi.com. A → AD Blocked → ZERO-IP RULE → NOERROR
    Sat Nov 14 17:16:51 2026 daemon.info updns[18922]: QUERY [CLI] ad.xiaomi.com. AAAA → AD Blocked → ZERO-IP RULE → NOERROR

    如上, 我定义了一个名为 AD Blocked 的规则, 它匹配指定域名列表文件, ad.xiaomi.com http://ad.xiaomi.com 在这个文件中; 由于该规则指定了 ZERO-IP 返回, 于是 ad.xiaomi.com http://ad.xiaomi.com 的 DNS 解析会被拦截, 并以 ZERO-IP 返回, 最终客户端拿到的解析结果是: 0.0.0.0 / ::. 除了 ZERO-IP , updns 也支持 NXDOMAIN 拦截.

    下面是, 如何安装, 对于 OpenWrt 25.12, 我提供了官方软件源, 通过下面命令可以便利安装:

    下载软件源签名公钥

    wget -O /tmp/updns-public.pem https://downloads.garinasset.com/updns/openwrt/signing.pem

    核对公钥 SHA-256

    sha256sum /tmp/updns-public.pem

    安装公钥

    cp /tmp/updns-public.pem /etc/apk/keys/updns.pem

    配置软件源

    ARCH="$(apk --print-arch)"
    echo "https://downloads.garinasset.com/updns/openwrt/25.12/${ARCH}/packages.adb&quot; >> /etc/apk/repositories.d/customfeeds.list

    更新软件源并安装软件包

    apk update
    apk add updns luci-app-updns luci-i18n-updns-zh-cn

    对于历史版本, 可以查看 官方 指南 手动编译安装.

    以上, 除介绍以外, 还有一些实用且强大的功能, 包括缓存 主动预取, 因为迫切想让大家使用体验, 我就不过多展开了. 对了, updns 我给它的官方取名是 道岔 DNS, 想象像铁路道岔一样, updns 可以让你对 DNS 解析拥有更灵活的控制能力。

    开放源代码:

    GitHub 软件仓库 https://github.com/garinasset/updns

    使用指南 https://github.com/garinasset/updns/blob/main/docs/GUIDE.md

    主楼
  • AmberWolf248

    这个DNS路由设计思路很赞,特别是自动将运营商DNS纳入上游的做法很务实。

    #1
  • QuietFox700

    这工具看起来挺酷,不过实际使用时会不会有配置复杂的问题?毕竟不是所有人都擅长折腾这些网络工具。

    #2
  • RapidDeer84

    这项目看起来真不错,特别是NFT set联动功能很实用,我这边的OpenWrt正好需要这种灵活的DNS路由方案。

    #3
  • WildStone75

    你们这个广告拦截功能具体是怎么实现的?我线上也一直想弄这个。

    #4
  • RapidOrbit92

    updns 的 NFT set联动看起来很强大,但会不会在某些路由器上造成性能问题啊?

    #5

发表回复

登录后回复