Skip to content

luci-app-ssr-plus: Add fake-ip mode and Fix Upload yaml config cannot use external DNS resolution. - #2043

Closed
zxlhhyccc wants to merge 1 commit into
fw876:devfrom
zxlhhyccc:fake-ip
Closed

zxlhhyccc wants to merge 1 commit into
fw876:devfrom
zxlhhyccc:fake-ip

Conversation

@zxlhhyccc

Copy link
Copy Markdown
Collaborator

No description provided.

@gongdao123

gongdao123 commented Sep 8, 2026

Copy link
Copy Markdown

@zxlhhyccc 真机测试完成,发现三个问题,都已定位并验证修复。环境:ImmortalWrt 25.12.1 r37978-cd0a06bfd3fd,mihomo v1.19.30,run_mode=routerpdnsd_enable=7enable_fake_ip=1

问题 1、2 用的是插件聚合生成的 Mihomo 总节点(clash_path),问题 3 是换成机场自带的 Clash 订阅(clash_url)后才暴露的。


问题 1:geosite:gfw 导致 mihomo 无法启动

clash_yaml.lua 第 588 行注入的 nameserver-policy 使用了 geosite:gfw,但官方 v2fly 的 geosite.dat 中没有这个 list:

level=error msg="load GeoSite data error, failed to decode geodata file: GeoSite.dat, base error: list gfw not found in GeoSite.dat"
configuration file test failed

逐个分类验证(mihomo -t -d <workdir> -f config.yaml):

nameserver-policy key 结果
geosite:gfw failed
geosite:cn successful
geosite:apple successful
geosite:cn,private,apple successful
geosite:geolocation-!cn successful

只有 gfw 不行。把

["geosite:gfw"] = result["fallback"] or get_forward_dns_list(),

改成 ["geosite:geolocation-!cn"] 后配置校验通过、服务 3 秒内正常启动。语义上也等价(非中国大陆域名走 fallback)。

顺带一提,同一个函数里对 fallback-filter.geosite 已经做了 = nil 的兼容处理,nameserver-policy 这处漏了。

另外这个失败是完全静默的:生成的配置是 log-level: silent,而 init 脚本在 mihomo 真正加载配置之前就输出了 Main node: Mihomo v1.19.30 (Clash) Started!,所以日志里看不出任何异常,排查成本很高。建议 fake-ip 模式下至少把 log-level 提到 warning


问题 2:陈旧的 nft 快照使 fake-ip 防火墙规则永不生效

修好问题 1 后服务能启动、DNS 也正确返回 198.18.0.x,但流量依然不通,nft198.18.0.0/16 规则数为 0。

定位过程:在 fw_rule_nft() 首行插入 logger从未触发(同时插在 ssr-rules 顶部的 logger 触发 3 次,且 enable_fake_ip 读到的值确实是 1),说明该函数根本没有被调用。

原因是 /usr/share/nftables.d/ruleset-post/99-shadowsocksr.nft —— 它是一个完整的 nft list ruleset 转储(147KB,连 counter packets 1 bytes 60 这样的计数器都被写进去了),由 fake-ip 关闭时生成。fw4 加载它之后,ssr-rules 检测到 ss_spec_wan_ac / jump ss_spec_wan_fw 已存在便跳过规则重建,因此切换 enable_fake_ip 对防火墙没有任何影响。

rm -f /usr/share/nftables.d/ruleset-post/99-shadowsocksr.nft
/etc/init.d/shadowsocksr restart

之后 198.18.0.0/16 规则数从 0 变为 5:

ss_spec_wan_fw:      ip daddr 198.18.0.0/16 meta l4proto tcp redirect to :1234
ss_spec_prerouting:  iifname "br-lan" ip daddr 198.18.0.0/16 ip saddr @ss_spec_lan_ac meta l4proto tcp redirect to :1234
                     iifname "br-lan" ip daddr 198.18.0.0/16 ip saddr @ss_spec_lan_ac meta l4proto udp redirect to :1234

建议在 enable_fake_ip 变更时主动删除或重建这个持久化文件,否则所有在已有安装上开启 fake-ip 的用户都会遇到「fake-ip 不生效」,而且完全无从排查(服务正常运行、DNS 返回 fake-ip、日志无异常,只有流量不通)。


问题 3:订阅自带 dns 段时,listenfake-ip-range 未被强制,DNS 链路完全断裂

把节点从插件聚合的总节点换成机场自带的 Clash 订阅(clash_url)后,所有 gfwlist 域名完全无法解析

clash_yaml.lua 中这两个值都是「仅当订阅未提供时才设置」:

534:  if not result["fake-ip-range"] then
535:      result["fake-ip-range"] = "198.18.0.1/16"

612:  if result.listen == nil or result.listen == "" then
613:      result.listen = "127.0.0.1:5335"

而我这份机场订阅的 dns 段自带 listen: 0.0.0.0:5053fake-ip-range: 198.10.0.1/16,于是订阅的值存活下来,与插件其余部分硬编码的假设冲突:

插件硬编码 订阅提供 后果
DNS 端口 dnsmasq 转发到 127.0.0.1#5335 mihomo 监听 0.0.0.0:5053 5335 Connection refused
fake-ip 网段 ssr-rules 重定向 198.18.0.0/16 下发 198.10.0.x 假 IP 永不被重定向

实测:

netstat:   :::5053 LISTEN 6256/ssr-retcp          ← mihomo 在 5053
dnsmasq:   server=/google.com/127.0.0.1#5335      ← 却转发到 5335
5335:      Connection refused
5053:      zh.wikipedia.org -> 198.10.0.4
nft:       198.18.0.0/16                          ← 重定向的是 198.18 段
53 解析被墙域名: (无结果)
curl https://www.google.com/generate_204 -> code=000

把 534 / 612 两处改为无条件强制后恢复正常:

fake-ip-range: 198.18.0.1/16
listen: 127.0.0.1:5335
netstat: 127.0.0.1:5335 LISTEN

nslookup zh.wikipedia.org 127.0.0.1        -> 198.18.0.8
nslookup -port=5335 zh.wikipedia.org       -> 198.18.0.8
curl https://www.google.com/generate_204   -> code=204
curl https://zh.wikipedia.org/             -> code=301
curl https://api.mch.weixin.qq.com         -> code=404(直连正常)

这两个值不是用户偏好,而是插件自身基础设施的对接点:listen 必须与 dnsmasq 的转发目标一致,fake-ip-range 必须与 ssr-rules 的重定向网段一致。订阅方无从得知这些约束,建议改为无条件覆盖(或者反过来:让 dnsmasq 与 ssr-rules 从实际生效的配置里读取这两个值)。

顺带一个安全性问题:订阅给的 listen: 0.0.0.0:5053 会让 mihomo DNS 监听所有接口(含 WAN),等于开放解析器;强制为 127.0.0.1 正好也修掉这一点。


三个问题修复后 fake-ip 在我这边工作正常,两种配置来源(clash_path 聚合节点 / clash_url 机场订阅)都验证过。感谢你的工作。

@zxlhhyccc

Copy link
Copy Markdown
Collaborator Author

@gongdao123 请问你有Telegram联系方式吗?你说的1和2问题我还是不太明白,我用你的yaml配置上传后在ipt下能正常代理,nft下我没测试,所以想直接联系你确认一下情况。

@gongdao123

Copy link
Copy Markdown

@zxlhhyccc TG 收不到验证码,无法登录了。

@zxlhhyccc

Copy link
Copy Markdown
Collaborator Author

@gongdao123 我在按你说的修正,明天你测试一下可以吗?因为我不是nft环境无法测试,nft规则我是凭感觉搞的。

@gongdao123

Copy link
Copy Markdown

好的 没问题,晚上回去测一下。我直接给你再打个pr好了? @zxlhhyccc

@zxlhhyccc

Copy link
Copy Markdown
Collaborator Author

好的 没问题,晚上回去测一下。我直接给你再打个pr好了? @zxlhhyccc

@gongdao123 可以的。

@zxlhhyccc

Copy link
Copy Markdown
Collaborator Author

@gongdao123 该PR我会删除,将重新提交PR,到时请测试。

@zxlhhyccc zxlhhyccc closed this by deleting the head repository Sep 9, 2026
@zxlhhyccc

zxlhhyccc commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

@gongdao123 已重新提交PR,请测试,如有问题请及时反馈,没问题我就打算合并。见: #2044
烦请注意务必测试:fake-ip模式切换时,规则文件备份和恢复是否包含198.18.0.1/16的规则,因为fake-ip模式才需要198.18.0.1/16的规则,不启用fake-ip模式不需要198.18.0.1/16规则。

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