OpenWrt 是一个专门面向嵌入式设备的 Linux 发行版。你可以将 OpenWrt 支持的型号的嵌入式设备,比如各种路由器上的系统,换成一个有更多可能性可以折腾的 Linux 系统。
› OpenWrt 官方网站
investor
V2EX  ›  OpenWrt

luci-app-updns 满足了当下我对 OpenWrt DNS 解析的一切想象

  •  
  •   investor · 23h 58m ago · 723 views

    最初我的需求只是网络走哪里,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@OpenWrt:~# 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 在这个文件中; 由于该规则指定了 ZERO-IP 返回, 于是 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" >> /etc/apk/repositories.d/customfeeds.list
    
    # 更新软件源并安装软件包
    apk update
    apk add updns luci-app-updns luci-i18n-updns-zh-cn
    

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

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

    开放源代码:

    zro
    zro
    20h 39m ago
    1
    可以像 Mihomo 那样设定某个上游走 Proxy ,或者设定覆写指定 ECS ,或者查询结果 Disable-IPv6 ?

    看起来还不错啊,应该能换掉 dnsmasq😁😁
    investor
    investor
    OP
    20h 4m ago
    2
    @zro
    - 1. NFT set 就是为某个上游走 Proxy 设计的, Luci 配置有一项是 将上游 DNS IP 加入 NFT 集合, 也就是说 你可以在防火墙 为该集合 的 ip 精准控制流量走向, 虽然 NFT 防火墙 流量控制看起来很复杂 , 但是只要会配一次, 其他就是粘贴复制, 例如,
    ```nft
    ip daddr @us4 \
    meta l4proto { tcp, udp } \
    meta mark set 0x10 \
    tproxy ip to :1080 \
    return
    ```

    我这里是举例名为 us4 的 NFT set, 这个集合存储了上游 DNS IP 、以及它解析过的 ip, 那么这个集合的流量都发送到透明代理所在的 1080 端口.

    以上是举例, 但代理软件的底层也是这样做的, updns 所做的是提供 基础设施 , 至于流量如何控制走向, 你来决定.

    - 2. 设定覆写指定 ECS, 我没理解用途.

    - 3. Disable-IPv6 是支持的啊, 规则定义匹配的域名, 解析结果返回仅 IPv4 就好了, 你可以随意灵活配置规则.

    updns 支持独立运行 或者 作为 dnsmasq 的上游, 根据需要选择.
    zro
    zro
    16h 34m ago
    3
    谢谢回复,如果不直接支持代理,以后会不会加入和 tunnel 对接的上游,比如 tunnel 的 target 是 dns.google:853 ,本地监听 127.0.0.1:8853 ,那 updns 的上游可以设置成 tls://dns.google#127.0.0.1:8853 类似这样子,因为 nft set 要另外连接 VPN ,或者开 Redirect/TProxy 才能用得上

    ECS 用途是这样:比如 HK 节点比较快,但要看美区的 Netflix ,那我会从 HK 节点查询 netflix 的美区 Netflix CDN 的 IP ,那 DNS 客户端不支持 ECS 改写的话,结果就是 HK 的 Netflix CDN 了,然后 US 节点访问去 HK 的 CDN
    investor
    investor
    OP
    14h 43m ago
    4
    非常乐意回复:

    - 1. 你可能没理解我的意思, 我本意表达, 只要 Tunnel 或者说任何代理进程 只要在 OpenWrt 上提供了可供连接的本地入口,理论上就可以通过 nftables 配合 Redirect 或 TProxy 接管流量, 并把流量转发到 Tunnel
    或者说代理的端口。 updns 提供了 把 上游 DNS 和 域名 的 ip 加入 nftables ip 集合, 接下来要做的就是在本地做 nftables 规则, 把流量 转发至你举例的 8853 端口即可.

    再次补充, 如果 你举例的 127.0.0.1:8853 就是一个 DNS 服务器 及端口, 你直接把它列为上游 DNS 即可. updns 支持 多种协议自定义上游; 例如 UDP/TCP 默认端口为 53,DoT 为 853,HTTPS/DoH 为 443。自定义 DNS 端口使用“主机:端口”格式(IPv6 示例:[2001:db8::1]:5353)。DoH 请填写完整 URL,例如 https://dns.example:8443/dns-query。

    - 2. 理解了你的 ECS 场景, 这个还挺有趣, 列入高优先级;
    investor
    investor
    OP
    14h 13m ago
    5
    @zro 再次补充第一点, 我做几个场景举例, 不知道能不能命中你的场景;

    一、“代理 做 DNS 解析 + 代理 访问网站” --- 场景如下:

    1、我在 updns 添加了 dns.google 的 DoT 协议的上游.

    2、我使用 updns 添加了一条规则 ‘Am111’, 所有匹配 某个域名列表‘YM888’的 DNS 查询, 其( 域名解析结果的 ip 地址 + dns.google 的 ip 地址) 都动态加入 名为 ‘us777’ 的 nft set 中;

    3、我在 OpenWrt 配置 Redirect 或 TProxy 规则(根据本地代理端口运行的协议), 将 所有 IP 在 ‘us777’ 集合中的流量 , 转发至本地 1080 端口;

    4、1080 端口是本地代理端口, 协议可能有多种, 例如 tproxy、socks5 等等;

    5、最终效果就是: 所有 (匹配 域名列表 YM888 的访问 + 其域名解析) 都会走代理;

    二、“有自建 DNS 服务器” --- 场景如下:

    首先, updns 支持 多种协议自定义上游; 例如 UDP/TCP 默认端口为 53,DoT 为 853,HTTPS/DoH 为 443。自定义 DNS 端口使用“主机:端口”格式(IPv6 示例:[2001:db8::1]:5353)。DoH 请填写完整 URL,例如 https://dns.example:8443/dns-query。

    1、 你只需要把自建 DNS 服务器 在 updns 上 添加为一个上游 DNS, 例如添加后取名 ‘上游 ZJDNS-8853’;

    2、 在 updns 上添加一个规则 , 把匹配某个域名列表 的 DNS 解析, 都交给 ‘上游 ZJDNS-8853’ 解析; 当然了 你也可以不做 域名列表匹配, 那么不匹配任意规则的 域名 的 DNS 解析, 都交给 ‘上游 ZJDNS-8853’


    总之, updns 的设计哲学就是 让你对 DNS 解析拥有更灵活的控制能力。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1855 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:11 · PVG 18:11 · LAX 02:11 · JFK 05:11
    ♥ Do have faith in what you're doing.