Skip to content

Releases: svenshi/oxidns

v1.4.0

24 Jun 10:33
4ce5653

Choose a tag to compare

OxiDNS v1.4.0

发布概览

OxiDNS v1.4.0 是一个 Minor Release,重点补齐复杂网络环境下的统一出口控制、上游诊断、并发上游结果裁决和缓存热路径优化。

本版本新增 network.outbound 统一出口层,让下载、升级检查、HTTP 请求、Webhook、outbound resolver、forward upstream 和部分探测场景可以复用同一套出口 profile;新增 oxidns probe upstream <addr>,用于在生产启用前验证真实上游链路;同时增强 forward 并发响应选择、DoH HTTP/1.1 / JSON API、WebUI 升级 / 重启体验,以及 query recorder 与 cache 的高负载表现。

未配置 network.outbound.default 的旧配置通常可以直接升级。若配置了默认 outbound profile,未显式设置 outbound 的 upstream 会继承该默认 profile。SOCKS5 proxy 只作用于 TCP、DoT 和 DoH2;UDP、DoQ、DoH3 upstream 会忽略 SOCKS5 proxy。

主要亮点

1. network.outbound 统一出口层

新增全局出口配置:

network:
  outbound:
    default: direct
    profiles:
      direct:
        resolver: system
        proxy: none
      remote:
        resolver:
          nameservers:
            - addr: "1.1.1.1:53"
            - addr: "tls://dns.google:853"
              dial_addr: 8.8.8.8
          ip_version: 4
          timeout: 5s
        proxy:
          socks5: 127.0.0.1:1080

以下路径可以复用 outbound profile:

  • download
  • upgrade
  • http_request
  • Webhook / 内部 HTTP client
  • forward upstream
  • outbound resolver nameserver
  • ip_selector TCP 探测
  • oxidns probe upstream

upstream 本地字段仍有更高优先级,例如 dial_addrbootstrapsocks5 会覆盖 profile 注入值。

2. 新增 oxidns probe upstream

新增上游诊断命令:

oxidns probe upstream <addr>

示例:

oxidns probe upstream udp://1.1.1.1:53
oxidns probe upstream tcp://1.1.1.1:53
oxidns probe upstream tls://dns.google:853 --qname example.com. --qtype A
oxidns probe upstream https://dns.google/dns-query --json
oxidns probe upstream tcp://dns.example.com:53 -c config.yaml --outbound remote

它可以帮助检查:

  • upstream 是否可达;
  • 域名型 upstream 的解析结果;
  • 实际解析来源,例如 literal、dial_addr、configured、bootstrap、system、proxy;
  • 串行基线查询表现;
  • TCP / DoT 是否适合开启 pipeline;
  • UDP / DoH / DoH3 / DoQ 的并发或多路复用表现;
  • 响应 ID、question、qtype 是否串线;
  • 超时、协议错误、传输错误和诊断建议;
  • human / JSON 两种输出格式。

建议在启用 network.outboundbootstrappipeline、加密 upstream、QUIC upstream 或代理出口前,对关键上游先执行 probe。

3. forward.response_selection 并发响应选择

forward 新增并发响应选择模式:

plugins:
  - tag: forward_main
    type: forward
    args:
      concurrent: 3
      response_selection: balanced
      upstreams:
        - addr: udp://1.1.1.1:53
        - addr: udp://8.8.8.8:53

支持模式:

  • fastest:第一个成功 DNS 响应胜出。
  • balanced:默认模式。正向 NOERROR 答案立即胜出;NXDOMAIN 或 NODATA 会短暂等待是否存在正向答案。
  • prefer_positive:正向答案立即胜出;负向答案等待已发起的并发上游全部结束后再返回。
  • consensus:正向答案立即胜出;负向答案需要两个上游确认,并发数不足时退化为 prefer_positive

forward.concurrent 上限提升到 1..=32,并会按实际 upstream 数量自动裁剪。常规配置建议使用 2..=8

4. Cache 策略与热路径优化

cache 新增:

min_positive_ttl: 4

正响应的有效 TTL 低于该值时不会写入缓存。该策略同时作用于普通写入和 lazy refresh。

新增指标:

cache_skip_total{reason="low_positive_ttl"}

同时优化了 cache hit 和 TTL rewrite 热路径:

  • LRU touch 改为自适应间隔,降低高命中场景下的写竞争;
  • TTL rewrite 复用 oxidns-proto 新增 helper,减少逐记录 mutation 开销;
  • lazy refresh 返回低 TTL 响应时,不再误删较新的缓存项。

5. DoH HTTP/1.1 与 JSON DNS API

DoH 入站现在支持 HTTP/1.1 与 HTTP/2 在同一监听上自动协商,HTTP/3 仍为可选能力。

http_server.entries[] 可开启 JSON DNS API:

entries:
  - path: "/dns-query"
    exec: "seq_main"
    json_api: true

开启后,GET 请求可使用:

  • name
  • type
  • cd
  • do
  • edns_client_subnet
  • random_padding

如果同一个 GET 请求同时带有 RFC8484 dns= 和 JSON API 参数,优先按 dns= 处理。

6. Query Recorder 读取性能优化

query_recorder 新增派生表:

  • questions
  • meta

qname / qtype 过滤、top qname / qtype / latency 等查询会使用索引化 question 表,不再反复展开 JSON 字段。

新增可选配置:

reader_concurrency: 2

用于限制 WebUI / API 历史与统计查询的 SQLite reader 并发,避免大库场景下突发读请求占用过多 blocking 线程和内存。

现有 records / steps 表保持不变,派生 question index 会自动回填。

7. WebUI 改进

  • 支持配置 network.outbound profile、默认 profile、SOCKS5 和 resolver nameserver。
  • 设置页展示 outbound 运行时指标。
  • 升级流程新增状态展示和 Upgrade Overlay。
  • 重启 / 升级检测改为识别新的 backend instance,而不是只依赖是否观察到停机窗口。
  • WebUI HTML 入口和 SPA fallback 使用 Cache-Control: no-cache,避免升级后缓存旧 HTML shell。
  • hashed 静态资源继续保持长期 immutable 缓存。
  • 补齐 outbound、cache、ip_selector 等新增字段的中英文文案。

8. DNS 规则与文档

  • reject 支持命名 RCODE,例如 reject NXDOMAINreject SERVFAIL
  • 新增 DNS 编码速查表,覆盖常见 RCODE、QCLASS、QTYPE 的数字值和英文助记名。

其他变更

  • 整理 upstream runtime 模块边界,拆分 traits、pooled execution、bootstrap refresh、bootstrap pool factory 等结构。
  • 拆分 forward executor,将 config、factory、single、concurrent、selection、metrics、tests 分离。
  • 修复 HTTP/3 connection accept error 可能在 cached connection-level error 上空转的问题。
  • fallback 无响应分支视为正常控制流,不再作为失败日志记录。
  • hotpath 升级到 0.17.0
  • 升级 jiffbytesh2webpki-rootssyn 等依赖。
  • GitHub Actions 工作流升级到 actions/checkout@v7

升级说明

版本号

  • 根 crate:1.4.0
  • oxidns-proto0.1.3
  • Release tag:v1.4.0

配置兼容性

v1.3.0 升级时,如果没有配置 network.outbound.default,通常可以直接升级。

如果配置了 network.outbound.default,请检查所有未显式设置 outbound 的 upstream,因为它们会继承默认 profile。

SOCKS5 proxy 只作用于:

  • TCP
  • DoT
  • DoH2

以下 upstream 协议会忽略 SOCKS5 proxy:

  • UDP
  • DoQ
  • DoH3

建议升级检查

升级后建议执行:

oxidns build-info
oxidns check -c config.yaml
oxidns probe upstream <critical-upstream>

尤其是以下场景:

  • 使用 network.outbound
  • 使用 bootstrap
  • 使用 TCP / DoT pipeline
  • 使用 DoH / DoQ / DoH3
  • 使用代理出口
  • 使用多上游并发转发

可选新增配置

以下配置都是可选项,不设置时保持默认行为:

  • forward.response_selection
  • cache.min_positive_ttl
  • query_recorder.reader_concurrency
  • http_server.entries[].json_api

致谢

感谢所有反馈 issue、参与讨论、提交 PR、验证网络路径和帮助完善 v1.4.0 诊断能力的用户与贡献者。

What's Changed

  • Add explicit reject 0 soa option by @ksong008 in #218
  • Serve WebUI HTML without immutable caching by @ksong008 in #217
  • Improve query recorder SQLite read scalability by @ksong008 in #215
  • fix(server): stop spinning on HTTP/3 accept errors by @svenshi in #220
  • Feat/reject rcode by @svenshi in #221
  • feat(docs): add DNS code reference and update configuration documentation by @svenshi in #223
  • Refactor/infra network boundaries by @svenshi in #222
  • feat(server): support HTTP/1.1 for DoH by @svenshi in #224
  • ci: bump actions/checkout from 6 to 7 in the github-actions-all group by @dependabot[bot] in #230
  • deps: bump hotpath from 0.16.1 to 0.17.0 in the cargo-major group by @dependabot[bot] in #229
  • deps: bump the cargo-patch-and-minor group with 5 updates by @dependabot[bot] in #228
  • Feat/network outbound by @svenshi in #231
  • Feat/network outbound by @svenshi in #234
  • refactor(network): clarify transport and upstream module layout by @svenshi in #235
  • Fix/webui upgrade by @svenshi in #237
  • feat(cli): add upstream probe diagnostics by @svenshi in #238
  • Feat/225 forward response selection by @svenshi in #239
  • refactor(forward): split executor implementation into modules by @svenshi in #240
  • feat(cache): add minimum positive TTL admission by @svenshi in #241
  • Fix/webui restart by @svenshi in #242
  • perf(cache): optimize cache hit path and TTL rewrite hot path by @svenshi in #243
  • Release/v1.4.0 by @svenshi in #244

New Contributors

Full Changelog: v1.3.0...v1.4.0

v1.3.0

16 Jun 09:58
a44b965

Choose a tag to compare

OxiDNS v1.3.0

🚀 发布概览

OxiDNS v1.3.0 是一次面向执行器语义、上游连接稳定性和工程结构的 Minor Release。核心变化包括 black_hole 升级为全 qtype 拦截器、upstream 连接池与 bootstrap 路径进一步加固,以及 Rust 包结构调整为 cli + infra + 精简 core

如果你依赖 black_hole、复杂上游池、RouterOS address-list 联动,或将 OxiDNS 作为 Rust library 嵌入使用,建议仔细阅读升级说明。

✨ 主要亮点

  • black_hole 支持 nxdomain / nodata / null / custom / refused 模式,并覆盖所有 qtype;旧的 ips 配置会自动保持 custom 兼容语义。
  • Upstream 连接池新增 min_conns,并强化 deadline、取消安全、slot 回收、不可用连接裁剪和 bootstrap CNAME 选择逻辑。
  • ros_address_list 新增 RouterOS API 连接、发送、接收超时配置;启动阶段扫描后台化,避免慢 address-list 阻塞 DNS 服务启动。
  • zoneparser 扩展标准 RDATA 解析能力,覆盖更多常见记录类型,并继续保留 RFC3597 generic syntax 兜底。
  • 修复规则文件解析中逗号被错误切分的问题,包含逗号的 domain / matcher 表达式可以正确保留。
  • Rust 代码结构重组为 src/cli/src/infra/ 和精简 src/core/,CLI、基础设施和 DNS 执行语义边界更清晰。
  • Release workflow 修复已打包产物被二次 archive 的问题。

⚠️ 升级说明

  • v1.2.3 配置通常可以直接升级到 v1.3.0
  • 请重点检查 black_hole
    • 旧的 ips 写法会继续按 custom 处理。
    • 无参 black_hole 现在默认返回 NXDOMAIN
    • null / custom 对非 A/AAAA 请求返回 NODATA,不再继续透传。
  • Upstream bootstrap 必须写成 IP:port,不要使用域名。
  • 新增 upstreams[].min_conns 默认为 0,不配置时仍保持懒加载连接行为。
  • ros_address_list 的 timeout 字段都是可选项,默认兼容旧配置;大型共享 address-list 仍建议拆分为 OxiDNS 专用列表。
  • Rust library embedders 需要迁移公开 module path:旧顶层 network / build_info / upgrade / service 和原 core 下的基础设施模块已迁入 infracore::contextcore::rule_matcher 保持不变。
  • 根 crate 版本为 1.3.0oxidns-zoneparser 升级到 0.1.1

📦 下载与校验

  • 根据你的平台和 bundle 选择对应 release archive。
  • standard 适合大多数部署;需要最完整能力时选择 full;极简自定义部署可选择 minimal 或自行按 feature 构建。
  • 替换生产环境二进制前,请使用 release assets 中的校验信息确认文件完整性。

What's Changed

  • feat(executor): make black_hole a full interceptor by @svenshi in #191
  • refactor: reduce complexity risk in DNS internals by @svenshi in #190
  • fix(executor): avoid blocking startup on RouterOS scans by @svenshi in #192
  • fix: 400 Bad Request, message: missing Accept header by @ohyooo in #196
  • deps: bump the cargo-patch-and-minor group with 3 updates by @dependabot[bot] in #198
  • deps: bump sysinfo from 0.38.4 to 0.39.3 in the cargo-major group by @dependabot[bot] in #199
  • fix double-archiving zipped artifacts by @ohyooo in #200
  • fix(upstream): make pooled queries deadline and cancel safe by @svenshi in #203
  • fix(matcher): preserve commas in rule files by @svenshi in #206
  • Refactor/package structure by @svenshi in #208
  • Release/v1.3.0 by @svenshi in #207
  • release v1.3.0 by @svenshi in #210

New Contributors

Full Changelog: v1.2.3...v1.3.0

v1.2.3

11 Jun 03:49
9601a02

Choose a tag to compare

OxiDNS v1.2.3

这是一个 Patch Release,重点修复高 CPU 相关问题,并改进 WebUI 升级体验。

主要亮点

  • 修复 /api/reload 后 TCP / DoT 响应写入任务可能空转,导致 CPU 占用升高的问题。
  • 降低上游 DNS 不可用或重启期间,pipeline / reuse 连接池忙等重试带来的 CPU 开销。
  • WebUI 新增英文界面 i18n,覆盖控制台页面、插件定义、帮助文档和主要组件文案。
  • WebUI 升级检查与应用升级请求支持可选 GitHub Token,并提供显式持久化控制和风险提示。
  • 补充 build-info 命令文档,便于查看构建能力矩阵和排查发布包能力差异。

修复内容

  • TCP / DoT 响应 writer 会在连接响应通道关闭时退出,避免 reload 后遗留任务持续空转。
  • 上游连接池在创建替代连接失败时加入短暂退避,避免上游故障期间只 yield 不等待的重试循环。
  • pipeline 池仅处于饱和状态时仍保持快速调度重试,不影响正常高并发路径。
  • WebUI 在升级状态为空闲时不再显示无意义的 header 操作入口。
  • 修正插件文档中的默认值说明,并保持中英文文档一致。
  • 替换测试中的固定等待为确定性同步,修复 cron Windows 计时波动,并在 query recorder top clients 断言前刷新 writer,降低测试偶发失败。

升级说明

  • v1.2.2 配置可直接升级到 v1.2.3
  • 不引入新的必填配置字段。
  • 不需要 YAML 配置迁移。
  • 建议使用 TCP / DoT 入站、频繁调用 /api/reload,或曾在上游 DNS 重启 / 不可用时观察到高 CPU 的部署升级。

What's Changed

  • feat(webui): add upgrade GitHub token controls by @svenshi in #182
  • Fix/high cpu usage by @svenshi in #181
  • fix(webui): hide idle upgrade header action by @svenshi in #183
  • docs(plugin): correct documented default values by @svenshi in #184
  • feat(webui): english i18n by @svenshi in #186
  • docs: update CLI documentation to include build-info command and it… by @svenshi in #187
  • chore(release): prepare v1.2.3 by @svenshi in #188

Full Changelog: v1.2.2...v1.2.3

v1.2.2

10 Jun 09:45
57dec84

Choose a tag to compare

OxiDNS v1.2.2

版本定位

  • Patch Release,核心变更为新增 HTTP 升级 API(plugin-upgrade feature)与 WebUI 实时更新通知,支持在 WebUI 内检测可用更新、比较版本并触发升级流程。同时修复 ${VAR} 环境变量展开的 YAML 解析顺序问题(先解析 YAML 再展开占位符,防止 YAML 注释干扰展开),修复 WebUI 对 ${VAR} 表单值的引号包裹处理,以及 H2/H3/DoQ 连接在远端关闭后的僵尸连接清理。不引入破坏性配置变更。

主要变更

  • feat(upgrade):新增 HTTP 升级 API(受 plugin-upgrade feature 保护),WebUI 新增更新通知横幅,可检测 GitHub 最新版本、展示当前/可用版本对比,并在 WebUI 内触发升级流程。
  • feat(webui):WebUI 升级面板适配后端 plugin-upgrade 能力,整合更新检测、升级状态展示与操作入口。
  • fix(upgrade):修复 apply 状态生命周期管理,并改为通过 POST body 传递所有升级参数,提升参数传递的可靠性。
  • fix(api):将 upgrade 模块路由注册限定在 plugin-upgrade feature 开启时,避免未编译升级能力的构建暴露相关接口。
  • fix(config)${VAR} 占位符展开改为在 YAML 解析后进行(而非之前),修复 YAML 特殊字符和注释可能干扰展开逻辑的问题;同时防止 YAML 注释文本被误作展开内容处理。
  • fix(config):将 expand_env_in_value_with_lookup 函数提升为公开可见,供外部代码复用。
  • fix(webui):修复 WebUI 在 ${VAR} 表单字段值两端错误剥除/保留引号包裹的问题(两处相关修复)。
  • fix(upstream):修复 H2(DoH)、H3(DoH3)、DoQ 连接在远端关闭后未可靠释放的僵尸连接问题,防止连接泄漏。
  • fix(tests):将集成测试中的固定 sleep 等待替换为轮询等待,提升测试可靠性。
  • fix(doc):修正 ${qname} 文档注释格式。

配置与升级说明

  • 根 crate 版本号升级为 1.2.2;本周期 crates/macroscrates/protocrates/ripsetcrates/zoneparser 均无改动,无需子 crate 同步升级;release tag 应使用 v1.2.2
  • v1.2.1 配置可直接升级到 v1.2.2,未引入新的必填配置字段。
  • HTTP 升级 API 受 plugin-upgrade feature 保护,仅在 standard / full bundle 中可用;minimal 构建不受影响。
  • 部署中使用 ${VAR} 占位符且配置文件含 YAML 注释的场景,建议升级以确保展开行为正确;旧写法无需修改,升级后行为自动改善。
  • 使用 H2/H3/DoQ 上游且长期运行的部署,建议升级以修复僵尸连接可能导致的连接泄漏。

What's Changed

  • Release/v1.2.1 by @svenshi in #170
  • fix(upstream): close zombie connections reliably across H2/H3/DoQ by @svenshi in #174
  • Fix/config env by @svenshi in #173
  • fix(webui): drop stray-quote-wrap stripping around ${VAR} placeholders by @svenshi in #175
  • feat(upgrade): add HTTP upgrade API and WebUI update notification by @svenshi in #176
  • fix(upgrade): use POST body for all params and fix apply state lifecycle by @svenshi in #177
  • Release/v1.2.2 by @svenshi in #178

Full Changelog: v1.2.1...v1.2.2

v1.2.1

08 Jun 15:37

Choose a tag to compare

v1.2.1

v1.2.0 配置可直接升级,无破坏性变更。

新功能

  • WebUI Basic Auth 登录:新增完整的登录流程与统一鉴权管理入口。启用了管理 API auth 配置的部署升级后刷新页面即可看到登录界面,无需修改配置。
  • 插件画布拖拽布局:插件画布支持按内容键控的拖拽定位,画布位置跟随内容标识持久化。

性能优化

  • ros_address_list:将 ROS API 写入操作并行流水化,并移除新增条目后的重查询步骤,大批量地址列表更新延迟显著降低。

Bug 修复

  • upstream 连接池:修复网络中断恢复后连接池进入死锁状态、连接获取持续阻塞的问题。
  • config${VAR} 替换现可正确处理被 YAML 引号包裹的占位符(如 "${MY_VAR}"),与裸占位符行为一致。
  • WebUI:插件未被应用时展示明确警告提示;抑制无关 404 错误噪音。
  • WebUIselect 字段保存时保留数值类型,避免隐式转为字符串导致配置校验失败。
  • WebUI:查询记录流程图现在展示全部序列规则,不再只显示部分规则。

其他

  • Cargo patch-and-minor 依赖批量升级(2 个包)。
  • CI 构建环境升级到 Ubuntu 24.04;新增 release 产物收集步骤。

升级说明

  • v1.2.0 配置可直接升级,无需修改任何字段。
  • 子 crate(macros / proto / ripset / zoneparser)本周期无改动,无需同步升级。
  • 如果此前在 ${VAR} 占位符外加了额外 YAML 引号来规避解析问题,升级后行为已统一,旧写法继续有效,也可按需简化。

What's Changed

  • Release/v1.2.0 by @svenshi in #157
  • Add step to collect release files in workflow by @svenshi in #158
  • Update GitHub Actions to use Ubuntu 24.04 by @svenshi in #159
  • deps: bump the cargo-patch-and-minor group with 2 updates by @dependabot[bot] in #164
  • Fix/webui issues by @svenshi in #166
  • feat(webui): add Basic Auth login flow and unified auth management by @svenshi in #167
  • fix(upstream): prevent connection pool deadlock after network outage by @svenshi in #168
  • perf(ros_address_list): pipeline concurrent writes and drop post-add … by @svenshi in #169

Full Changelog: v1.2.0...v1.2.1

v1.2.0

03 Jun 15:27

Choose a tag to compare

OxiDNS v1.2.0

OxiDNS 1.2.0 是一个 Minor Release,本周期最大的变化是引入完整的编译期特性体系与三档预设 bundle,把 DoQ / DoH3、DoT / DoH、api / webui / metrics、可选插件以及 TLS / HTTP 依赖全部改为按需启用,并把"编译进来的能力"暴露给 CLI、API 与 WebUI。同步上线两个新插件 ip_selectordynamic_domain_set + learn_domain,扩展 env 匹配器为多条件表达式,并修复缓存、DoH 监听、upgrade 等关键问题。

⚠️ 本版本含一个破坏性变更:env 匹配器移除了遗留的两参数 ["KEY", "VALUE"] 解析,详见下方升级说明。

✨ 亮点

  • 编译期特性体系:新增 minimal / standard(推荐)/ full 三个 bundle,叠加 server-doq / server-doh3 / server-dot / server-doh、upstream-doq / upstream-doh3 / upstream-dot / upstream-doh、api / webui / metricsplugin-mikrotik / query-recorder / ipset / cron / script / download / http-request / reverse-lookup / upgrade / arbitrary / plugin-ip-selector / plugin-dynamic-domainprovider-protobuf / adguard-rule 等细粒度 flag。minimal 二进制约 8.9 MB(vs full 约 21 MB,缩小约 58%)
  • Release 产物按 bundle 切分:新增 Linux musl minimal / standard 归档(full 名称保持不变),upgrade 与安装脚本支持显式选择 bundle;standard 已包含 apiwebuiquery_recorderupgrade
  • 运行时能力反射:CLI 与 system/health 上报激活的 bundle 与支持的插件类型;WebUI 在新建、引用选择、卡片、详情视图中自动禁用未编译进来的插件类型。
  • 新插件 ip_selector(executor):A / AAAA 响应 IP 选优,支持带上限的 TCP / ping 探测、得分缓存、并发探测合并、DNSSEC 安全处理与失败兜底放行。
  • 新插件 dynamic_domain_set(provider)+ learn_domain(executor):可写、文件持久化、支持热快照与 API 规则管理的动态域名集;learn_domain 不依赖 SQLite、不触发整体 reload,即可把查询/响应按过滤条件写入动态集;WebUI 新增规则列表、添加 / 删除 / 清空管理面板。
  • env 匹配器多条件:每个参数都按独立表达式解析;推荐 KEY=VALUE 精确匹配,KEY:VALUE 作为别名,支持 value 中含分隔符。
  • WebUI 卡片拖拽排序:仪表盘与插件中心均支持拖拽。插件中心的排序写回配置文件的 plugins 顺序(暂存后由"应用更改"统一保存);仪表盘固定卡片顺序仅作为本地偏好持久化到 localStorage
  • 新增 dynamic_domain_set WebUI 规则管理面板learn_domain 字段级文档。

🐛 关键修复

  • cache:size 视为条目上限而非启动时 map 容量,避免大缓存配置的预分配开销;启动与 API dump 加载后立即按上限裁剪。修复 #147
  • server:DoH3 / TLS 前置条件不满足或 HTTP/3 初始化失败时,先回收已启动的 HTTP/2 监听任务,避免泄漏的 DoH 监听句柄。
  • upgrade:从运行时配置推断 WebUI 资源路径,修复与 --working-dir 组合使用时找不到 WebUI 资源的问题。
  • config:消除运行时占位符 {...}env 占位符的歧义。
  • dynamic_domain_set:序列化追加写入、分行写入新增规则、写文件前先校验、保持内存与文件状态一致。
  • perf(sequence):步骤记录改为受内部 _sequence-step-recording feature 控制,仅在 query_recorder 启用时编译进来。

💥 破坏性变更

env 匹配器移除遗留的两参数解析

  • 旧写法 env: ["KEY", "VALUE"] 之前等价于 $KEY == VALUE;现在表示"环境变量 KEYVALUE 都存在"
  • 迁移方法(任选其一):
    • env: ["KEY=VALUE"](推荐)
    • env: ["KEY:VALUE"]
  • 如果你确实想保留新语义(两个环境变量都存在),无需修改。
  • 详见 docs/migrate-from-mosdns 中的迁移说明。

⬆️ 升级说明

  • 根 crate 升级至 1.2.0;本周期 crates/macros / crates/proto / crates/ripset / crates/zoneparser 均无改动,子 crate 无需升级。Release tag:v1.2.0
  • 使用默认(full)或 standard bundle 时,v1.1.4 配置可直接升级;如选择 minimal 或自定义裁剪 feature,配置里引用未编译进来的插件 / 协议会在启动时报错 "not compiled in; rebuild with --features ..."。
  • 选择最小化部署:cargo build --release --no-default-features --features minimal(或 standard)。Release 通道同时发布 minimal / standard / full 三套 Linux musl 归档,upgrade 与安装脚本支持显式 bundle 选择。需要 WebUI、query_recorderupgrade 的部署建议使用 standardfull
  • 大缓存部署(如 size > 200000)强烈建议升级:先前会预分配过大 map,且 API dump 加载后未严格裁剪。
  • 启用 DoH 且未启用 DoH3、或启用 DoH3 但缺少必需 TLS 配置的部署建议升级:先前在 HTTP/3 初始化失败时可能残留 HTTP/2 DoH 监听句柄。
  • dynamic_domain_set / learn_domainplugin-dynamic-domain 控制,ip_selectorplugin-ip-selector 控制;二者均已包含在 standard / full bundle 中。

📦 依赖升级

  • socket2 0.6.3 → 0.6.4
  • jiff 0.2.24 → 0.2.28
  • wincode 0.5.4 → 0.5.5
  • http 1.4.0 → 1.4.1
  • hyper 1.9.0 → 1.10.1
  • rusqlite 0.39 → 0.40
  • windows-service 0.6 → 0.8.1

📚 文档

  • 新增 PLUGIN_DEV.md 插件开发与注册指南
  • 新增 SECURITY.md 安全策略
  • 新增自定义构建中文文档与 quickstart 预设能力矩阵
  • 新增 roadmap 时间线组件
  • 移除安装文档中的 GHCR 引用
  • 修复 TLS 配置文档格式

What's Changed

  • Feat/webui drag ordering by @svenshi in #145
  • fix(cache): avoid eager allocation for large cache limits by @svenshi in #148
  • feat(build): gate api/tls/http protocols behind Cargo features by @svenshi in #144
  • fix(upgrade): infer WebUI path from runtime config by @svenshi in #152
  • fix(config): disambiguate runtime and env placeholders by @svenshi in #151
  • feat(matcher): support multiple env conditions by @svenshi in #150
  • feat(executor): add ip_selector response IP selection by @svenshi in #154
  • feat(plugin): add dynamic domain learning by @svenshi in #153
  • deps: bump the cargo-major group with 2 updates by @dependabot[bot] in #156
  • deps: bump the cargo-patch-and-minor group with 5 updates by @dependabot[bot] in #155

Full Changelog: v1.1.4...v1.2.0

v1.1.4

30 May 02:54

Choose a tag to compare

OxiDNS v1.1.4

Patch Release · 2026-05-30

本次为补丁版本,重点优化 provider 与规则匹配路径的内存占用与重载开销,并修复 WebUI 在移动端的可用性、查询记录图表标签显示,及 Monaco 编辑器的加载方式;同时新增「从 mosdns 迁移」文档。本版本不引入破坏性配置变更,查询热路径行为保持不变。

⚡ 性能与内存

  • client_ip / resp_ip / ptr_ip 内联 IP 匹配器编译后改用 finalize_compact,不再保留一份重复的源 IP 区间副本(ip_set / geoip 此前已如此)。
  • finalize_compact 现在将合并后的 IPv6 区间移动进编译结构,而非克隆。
  • geoip 加载时通过 add_v4_network / add_v6_network 直接喂入 CIDR 字节,省去每条记录 String 格式化再重新解析的往返,加快加载与 reload。
  • adguard_rulebadfilter 解析改为一次构建 HashSet,替换原先每次比较都重新分配 cache key 的 O(n²) 扫描。

以上均为内部实现改进,不改变匹配语义与查询热路径行为。

🖥️ WebUI 修复

  • 修复配置编辑器与插件筛选在移动端无法正常使用的问题。
  • 修复查询记录图表 Top-N 标签被截断、无法完整显示的问题。
  • Monaco 编辑器改为本地自托管,不再从 jsdelivr CDN 加载,便于离线或受限网络环境下使用。

📖 文档

  • 新增「从 mosdns 迁移」指南。

🔧 配置与升级说明

  • 根 crate 版本号升级为 1.1.4;本版本无 crates/ 子 crate 改动,无需同步升级;release tag 为 v1.1.4
  • v1.1.3 配置可直接升级到 v1.1.4,未引入新的必填配置字段。
  • provider / 匹配器优化为内部改进,无需调整任何配置。
  • 受限或离线网络环境下使用 WebUI 配置编辑器的部署可受益于 Monaco 本地自托管,无需访问外部 CDN。

What's Changed

  • Release/v1.1.3 by @svenshi in #130
  • feat(docs): feat mosdns migrate doc Closed #134 by @svenshi in #135
  • fix(webui): show full Top-N labels in query recorder charts by @svenshi in #139
  • fix(webui): self-host Monaco editor instead of jsdelivr CDN by @svenshi in #140
  • fix(webui): make config editor and plugin filters usable on mobile by @svenshi in #142
  • release v1.1.4 by @svenshi in #143

Full Changelog: v1.1.3...v1.1.4

v1.1.3

27 May 15:18

Choose a tag to compare

版本亮点

Patch release,修复 ripset 中两个 Linux netlink 协议 bug —— nftset interval 集合写入被内核以 EINVAL 拒绝、ipset 创建集合时 hashsize / maxelem 字节序错误 —— 另外修复一个 WebUI 溢出问题,并预告 black_hole 插件后续版本的重设计。

本版本不引入破坏性配置变更,v1.1.2 配置可直接升级。

主要变更

Fixes

  • nftset interval 集合:ADD / DEL 改为 nft 用户态使用的两元素列表形式,解决真实内核以 EINVAL 拒绝写入的问题(#127);TEST 改为仅发送起始 key,交由内核 interval 树判定包含关系。同时修正元素 timeout 的字节序,并放宽 dump 解析对孤立 INTERVAL_END 锚点的容错。
  • ipset 创建集合hashsize / maxelem 改为大端字节序写入 —— 小端主机上 hashsize=2048 此前会被内核读成 524288。同时移除多余的 IPSET_ATTR_LINENO=0 嵌套属性,与 libipset 行为对齐。
  • WebUI:修复 query_recorder 详情面板长内容时标签栏纵向溢出。

Tests

  • 大幅扩充 ripset 报文格式单元测试与真实内核下的 ipset 集成测试覆盖。

Docs

  • black_hole 执行器文档加入醒目提示,预告后续版本将引入 mode 字段(nxdomain / nodata / null / custom / refused)以覆盖所有 qtype。本版本行为保持不变。

升级说明

  • 根 crate 1.1.21.1.3oxidns-ripset 0.1.10.1.2
  • 强烈建议 Linux 上使用 nftset 且集合声明了 flags interval 的部署升级 —— 否则 ADD / DEL 会在真实内核上以 EINVAL 失败。
  • 建议 Linux 上通过 OxiDNS 创建 ipset 集合并显式设置 hashsize / maxelem 的部署升级 —— 如果集合由外部 ipset CLI 预先创建,本次修复不影响已存在的集合。

What's Changed

Full Changelog: v1.1.2...v1.1.3

v1.1.2

26 May 17:28

Choose a tag to compare

版本定位

Patch Release,重点修复 Linux nftsetflags interval 集合上的写入失败、Windows 服务安装脚本问题,并完善 systemd 部署的工作目录语义、WebUI 运行日志与 query_recorder 排行查看体验。本版本不引入破坏性配置变更。

主要变更

Bug 修复

  • nftset(#122):修复执行器在小端主机上读取集合 flags 时使用本机字节序,导致 flags interval 集合的 is_interval 永远为 false,所有 CIDR 写入均以 Unsupported entry for set type 失败的问题;现按大端解码并新增字节序回归测试。
  • nftset 写入器:按前缀独立处理,将 IpSetError::ElementExists 视为可跳过的 no-op,仅在结构化 warn 日志中聚合 ok / skipped / failed 计数,不再因为单次 EEXIST 整体禁用插件。
  • systemd 单元:修复 Debian 打包的 systemd 单元因 WorkingDirectory 预启动 CHDIR 失败的问题;现以 -d/--working-dir 作为运行时相对路径(包含 WebUI 资源)的唯一基准。
  • Windows 安装/卸载脚本:调整服务管理流程、二进制路径处理与卸载顺序,避免残留进程或路径异常。
  • WebUI 容错:JSON 响应与 query_recorder SSE 流现在能容忍非 JSON 错误、心跳帧、空载与异常事件,避免控制台在偶发网络抖动时报错。

功能增强

  • WebUI 运行日志查看器:新增整行换行开关;后端 LogEntry.timestamp 升级到毫秒精度,UI 在 T+elapsed 旁补充本地 HH:MM:SS.mmm,方便与外部时间线对齐。
  • query_recorder 排行 (#116):移除 top client / top qname / slow-query 排行接口固定的 200 行上限,WebUI 排行榜和慢查询列表新增"加载更多"按钮以支持更大的结果集。
  • WebUI 插件字段文档:与 Rust 插件配置同步刷新。

文档

  • 文档站点新增 Hero 组件、改进安装步骤与 Docker 运行命令展示,新增多平台快速上手指引。
  • 补齐 Debian /etc/oxidns/var/lib/oxidns 目录约定、WebUI 符号链接说明与 client_ip 排错章节(#118)。

配置与升级说明

  • 根 crate 版本号升级为 1.1.2oxidns-ripset 同步升级到 0.1.1
  • v1.1.1 配置可直接升级到 v1.1.2,未引入新的必填配置字段。
  • 强烈建议升级:在 Linux 上使用 nftset 插件、且集合声明了 flags interval 时,旧版本该集合在小端架构上完全无法写入。
  • 通过 deb 包升级的部署,新版本不会再设置 systemd WorkingDirectory;如果此前依赖该值改写相对路径,请改用 -d/--working-dir 显式指定。
  • 已使用 query_recorder 排行接口的客户端可以传入更大的 limit;旧的 200 行响应仍能按原方式解析,行为兼容。

What's Changed

  • docs(plugin): document redirect rule forms and forward usage by @svenshi in #111
  • chore(release): prepare v1.1.0 by @svenshi in #112
  • Add history clearing support and improve delete dialog flow by @svenshi in #115
  • fix(webui): sync plugin field docs by @svenshi in #120
  • Enhance query recorder with larger stats limits and UI improvements by @svenshi in #121
  • feat: add Hero component with installation instructions and features … by @svenshi in #123
  • fix: update Windows installation scripts and service management by @svenshi in #124
  • Fix/122 nftset by @svenshi in #125

Full Changelog: v1.1.1...v1.1.2

v1.1.1

25 May 08:29

Choose a tag to compare

OxiDNS v1.1.1

这是一个补丁版本,主要改进 query_recorder 的历史记录管理能力,并修复 WebUI 插件删除流程中的若干交互问题。

主要变更

  • query_recorder 新增历史记录清空能力:

    • 新增 DELETE /api/plugins/<tag>/records 管理接口。
    • 清空前会 flush 后台写入队列。
    • 会删除已持久化的查询记录、执行路径 steps,并清空内存 tail。
    • 返回 cleared_records 表示本次删除的主表记录数。
  • WebUI 查询记录面板新增“清空历史”按钮:

    • 提供二次确认弹窗,避免误删。
    • 清空后自动刷新记录列表、插件命中统计和选中详情状态。
    • 清空过程中会禁用相关操作并显示状态反馈。
  • 优化插件删除弹窗体验:

    • 修复引用提示弹窗宽度不足、内容溢出的问题。
    • 更清楚地展示引用来源、目标类型和不可移除原因。
    • 修复取消删除弹窗后误打开插件详情抽屉的问题。
    • 修复“进入编辑器修复”会提前移除插件的问题。
    • 配置存在错误时,删除按钮仍可打开弹窗查看原因,不再表现为常显且不可点击。

兼容性与升级说明

  • 本版本不引入破坏性配置变更。
  • 现有 v1.1.0 配置可直接升级到 v1.1.1
  • 新增的 query_recorder 清空接口是可选管理能力,不影响现有查询记录采集行为。
  • “清空历史”操作不可撤销,请在确认不再需要历史查询记录后使用。

What's Changed

  • feat(query_recorder): add history clearing support by @svenshi in #113
  • fix(webui): polish plugin delete dialog flow by @svenshi in #114

Full Changelog: v1.1.0...v1.1.1