美服 LoL 走 real-ip 的 mosdns + sing-box 部署记录

记录如何在 mosdns 和 sing-box 的 fake-ip 分流环境里,把 Riot / League of Legends 域名单独剥离出来,改成 real-ip 直连,避免游戏被 fake-ip 误伤。

这篇是给美服 LoL 单独整理的部署记录。

背景很简单:你已经有一套正常工作的 sing-box + mosdns + fake-ip 环境,平时浏览器、下载、流媒体都没问题,但美服 LoL 的体验不稳定,甚至出现“选了直连也不行”的情况。最后真正的关键点不是节点本身,而是 Riot / League of Legends 相关域名被 fake-ip 链路提前接管了

本文的目标不是重写整套代理架构,而是只做两件事:

  1. 让 LoL / Riot 相关域名在 DNS 层走 real-ip。
  2. 让 sing-box 路由层把这些域名明确导向 direct

这样做之后,游戏连接不会再落到 28.0.0.0/8 这类 fake-ip 上,延迟和兼容性都会更稳。

1. 先理解问题

如果你已经在用 mosdns 的 fake-ip 模式,常见流程是这样的:

客户端 -> mosdns
mosdns -> 返回 fake-ip
客户端 -> 连接 fake-ip
sing-box 还原域名后再决定走代理还是直连

这套机制对网页、下载、流媒体通常很顺。

但 LoL 不一样,它的连接链路里会出现:

  • 登录域名
  • 客户端域名
  • 游戏服域名
  • 语音 / 控制域名
  • 一些地区性 pvp.net 域名

这些域名如果都被丢进 fake-ip,后续连接就不再是传统意义上的“真实 IP 直连”。有时 sing-box 面板里你明明切了 direct,实际连接还是没走你想要的路径。

所以正确思路不是“让 LoL 也走 fake-ip”,而是反过来:

  • LoL / Riot 域名走 real-ip
  • 这些域名在 sing-box 路由里强制 direct

2. 先看现有环境

先确认你已经有:

  • mosdns 负责 DNS 分流
  • sing-box 负责透明代理和路由
  • fake-ip 已经在跑

常见检查命令:

systemctl is-active sing-box
systemctl is-active mosdns

如果你用的是 Alpine 或 OpenRC,服务命令可能不同,但思路一样。

再确认 mosdns 监听和 sing-box 监听:

ss -lntup | grep -E ':53|:111|:5353|:9090|:9333'

3. 为什么 direct 还不够

很多人会先在 sing-box 里加一条:

{
  "rule_set": "geosite-riot",
  "outbound": "direct"
}

这一步是必要的,但不一定够。

原因是:

  1. 如果 mosdns 还在把 LoL 域名转成 fake-ip,那 sing-box 看到的第一眼已经不是原始 DNS 结果了。
  2. 某些游戏连接路径并不是单一的 HTTP 请求,而是会混合登录、控制和游戏会话。
  3. 仅改路由,不改 DNS,效果经常不稳定。

所以要同时改两边。

4. 在 mosdns 里加 real-ip 列表

先把 Riot / LoL 相关域名加入 realiplist.txt

路径通常是:

/cus/mosdns/rule/realiplist.txt

可以追加这些常见后缀:

# Riot / League of Legends real-ip direct
domain:riotgames.com
domain:riotcdn.net
domain:leagueoflegends.com
domain:lolesports.com
domain:pvp.net
domain:lolstatic.com
domain:lolstatic-a.akamaihd.net
domain:rgpub.io
domain:riotcdn.cn

这一步的意思是:

  • 这些域名不要再走 fake-ip
  • 让 mosdns 给它们返回真实公网 IP

如果你的 mosdns 里已经有“记忆直连”或者“订阅直连”机制,也可以把这些域名放进去,原则一样:让它们进入 real-ip 链路。

5. 在 sing-box DNS 里提前拦截 Riot

仅改 mosdns 还不够,sing-box 自己的 DNS 规则也要补一层。

/etc/sing-box/conf/02_dns.json 里,给 geosite-riot 单独加一条:

{
  "rule_set": "geosite-riot",
  "action": "route",
  "server": "remote-dns",
  "rewrite_ttl": 60
}

重点是放在 geosite-geolocation-!cn -> fakeip-dns 之前。

这样 Riot 域名会优先走真实 DNS,而不是被泛化的国外 fake-ip 规则吃掉。

6. 在 sing-box 路由里强制直连

再到 /etc/sing-box/conf/05_route.json 里,加上 Riot 专用直连规则:

{
  "rule_set": "geosite-riot",
  "outbound": "direct"
}

建议放在前面,优先级高于这些规则:

  • udp/443 拒绝
  • geosite-geolocation-!cn
  • 其它大范围国外规则

这样就不会出现“游戏被整体判成代理流量”的情况。

7. Riot 规则集怎么定义

如果你的 sing-box 配置里还没有 geosite-riot,可以补一个本地规则集:

{
  "type": "local",
  "format": "binary",
  "tag": "geosite-riot",
  "path": "/etc/sing-box/rules/geosite/riot.srs"
}

这一步之后,路由和 DNS 才能引用同一个规则标签。

8. 你会看到什么变化

改完后,Riot / LoL 常见域名会从 fake-ip 变成真实 IP。

例如:

leagueoflegends.com            -> 真实公网 IP
login.riotgames.com            -> 真实公网 IP
na-red.lol.sgp.pvp.net         -> 真实公网 IP
lol.secure.dyn.riotcdn.net     -> 真实公网 IP
clientconfig.rpg.riotgames.com -> 真实公网 IP

而不是:

28.0.x.x

这就是关键。

9. 你的 sing-box 主结构不用动

这类修复不需要重写整套 sing-box:

  • 不用改 TUN
  • 不用改主分流框架
  • 不用改已有的代理节点结构

只要保证:

  1. Riot 域名在 DNS 层走 real-ip
  2. Riot 域名在路由层走 direct

就够了。

10. 验证方法

10.1 看 DNS 返回值

先确认同一个域名不再返回 fake-ip。

python3 - <<'PY'
import socket, struct, random

def q(name, server, port):
    tid = random.randrange(65536)
    parts = name.rstrip('.').split('.')
    body = b''.join(bytes([len(p)]) + p.encode() for p in parts) + b'\0' + struct.pack('!HH', 1, 1)
    pkt = struct.pack('!HHHHHH', tid, 0x0100, 1, 0, 0, 0) + body
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.settimeout(2)
    try:
        s.sendto(pkt, (server, port))
        data, _ = s.recvfrom(4096)
        an = struct.unpack('!H', data[6:8])[0]
        return an
    finally:
        s.close()

print(q('login.riotgames.com', '127.0.0.1', 53))
PY

更实用的是直接看返回 IP,别再出现 28.0.0.0/8

10.2 看 sing-box 路由

sing-box check -C /etc/sing-box/conf
systemctl restart sing-box

10.3 看实际业务

LoL 不是测速站,最终要看:

  • 游戏能不能进
  • direct 后是否还会绕回代理
  • 登录页和对局内是否稳定

11. 常见坑

只改 sing-box,不改 mosdns

这会导致 DNS 还是 fake-ip,游戏还是不稳。

只改 mosdns,不改 sing-box

这会导致域名虽然拿到了真实 IP,但路由还可能被丢到代理出口。

规则顺序放错

geosite-riot 要比泛化的 geosite-geolocation-!cn 更靠前。

混淆理解错

Riot/LoL 这类场景,真正关键的是 DNS 和路由,不是再去堆一个更花的节点参数。

12. 经验结论

这次实测最重要的结论是:

  • LoL 不是单纯“节点慢”
  • 也不是单纯“选 direct 就行”
  • 真问题通常在 fake-ip 链路里

把 Riot 域名拉回 real-ip,再让 sing-box 明确直连,游戏体验会比单独折腾节点更稳定。

13. 一句话总结

美服 LoL 要稳,核心不是“再换一个更快节点”,而是:

Riot 域名 -> real-ip
sing-box 路由 -> direct

这样游戏连接才不会被 fake-ip 搅乱。