Skip to content

fix: 避免重复 DNS redirect 跳转 - #5226

Closed
eyaeya wants to merge 1 commit into
vernesong:devfrom
eyaeya:net/fw4-dns-redirect-idempotence
Closed

eyaeya wants to merge 1 commit into
vernesong:devfrom
eyaeya:net/fw4-dns-redirect-idempotence

Conversation

@eyaeya

@eyaeya eyaeya commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Dependency chain

推荐合并顺序:#5223 和本 PR 都改 luci-app-openclash/root/etc/init.d/openclash 的 fw4 DNS 区域,建议先合并 #5223,再合并本 PR 并按需解决文本冲突。语义组合方式是:同时保留 #5223nat_output guard 和本 PR 的 openclash_dns_redirect chain / jump 幂等。

问题现象

fw4 + enable_redirect_dns=2 场景下,restore/start 重入会重复追加 openclash_dns_redirect 链内规则和 dstnat -> openclash_dns_redirect jump。时间长了会造成 nft 规则堆叠,日志和排障也会被重复规则干扰。

根因

#5209 已解决 direct DNS hijack 规则的 IPv4/IPv6 识别,但 enable_redirect_dns=2 的 jump 规则没有 OpenClash DNS Hijack comment,也没有独立 guard;openclash_dns_redirect 链每次 add rule 前也没有 flush,因此 restore 重入会累积规则。

证据

  • IPv4 enable_redirect_dns=2 分支每次都会向 openclash_dns_redirect add 规则,并无条件向 dstnat insert jump。
  • IPv6 enable_redirect_dns=2 分支同样无条件 insert IPv6 jump。
  • reload "restore" 路径会调用 do_run_modecheck_core_status,不一定先完整 revert firewall,因此调用点需要自身幂等。
  • tests/fw4_dns_hijack_guard_test.sh 覆盖了 IPv4/IPv6 jump 识别,并用结构断言确认真实 jump 插入在对应 fw4_has_dns_redirect_jump guard 下。

修复方案

  • 新增 fw4_has_dns_redirect_jump,按 IPv4/IPv6 识别 dstnat -> openclash_dns_redirect jump。
  • enable_redirect_dns=2 重建前 flush openclash_dns_redirect 链,避免链内 redirect 规则堆叠。
  • IPv4/IPv6 jump 插入前分别检查已有 jump,缺失时才插入。

为什么没有扩大修复范围

没有修改 fw3/iptables 分支,没有改 direct DNS hijack 规则,也没有处理 nat_output DNS 幂等;后者由 #5223 单独处理。本 PR 只覆盖 enable_redirect_dns=2 的 redirect chain 和 dstnat jump。

与已有开启态 PR 的关系

验证命令和结果

均已通过:

bash -n luci-app-openclash/root/usr/share/openclash/*.sh
bash -n luci-app-openclash/root/etc/init.d/openclash
bash -n tests/*.sh
tests/fw4_dns_hijack_guard_test.sh
for t in tests/*.sh; do "$t"; done
git diff --check
rg -n '^(<<<<<<<|=======|>>>>>>>)' luci-app-openclash/root/etc/init.d/openclash tests/fw4_dns_hijack_guard_test.sh

最后一条无命中。

剩余风险

未做 live router 验证。该补丁会在 enable_redirect_dns=2 时刷新 openclash_dns_redirect 链内容;如果用户在运行中切换 DNS redirect 端口或 LAN access 规则,下一次 restore 会以当前 UCI 状态重建该链。

@vernesong

Copy link
Copy Markdown
Owner

@eyaeya 不要刷pr否则屏蔽,具体解决哪个issues请关联实际用户反馈

@eyaeya

eyaeya commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

这个拆分 PR 已被新的合并版 PR 取代:#5229

原因:#5223#5226 都修改 fw4 DNS 劫持/redirect 相邻逻辑,并且按任意顺序合并都会在 luci-app-openclash/root/etc/init.d/openclashtests/fw4_dns_hijack_guard_test.sh 产生真实冲突。新的合并版 PR 保留了本 PR 的行为,同时把 nat_output guard 与 redirect jump guard 统一整理成单个 reviewer 友好的提交。

已在合并版 PR 中验证:

  • focused fw4 DNS guard test
  • init.d/openclash 语法检查
  • git diff --check
  • conflict marker scan
  • 多轮对抗式复核,最终无修改点

@eyaeya eyaeya closed this Jul 8, 2026
@eyaeya

eyaeya commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@eyaeya 不要刷pr否则屏蔽,具体解决哪个issues请关联实际用户反馈

好的,我将停止提交PR。
我所提交的每一组PR均是在实实在在解决确实存在的健壮性问题,也是我和朋友们个人使用下来的各种真实报错和不稳定。提交PR对于我而言无利益相关,我也不需要此作为背书凭据。
如果不欢迎PR,我尊重项目发起者的喜好。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants