个人网络配置方案 提到过,之前我的 PS4 代理方案是在 OpenWrt 路由器上通过 LuCI 配置 shadowsocks-libev 来完成的。 此方案理论上并没有什么问题或者不妥,但是在实际游戏中,常常会遇到无法和好友使用 PS4 内置的 Party 进行语音的问题,甚至还会出现彻底无法加入好友的集会所的情况。 这些问题出现时 PS4 大概率会提示说:Cannot use voice chat with the following player: xxxxx. This might be because of NAT type limitations。 考虑到 Monster Hunter World: IceBorne 发售日临近,这个问题若是不解决恐怕又要出现和好基友花半小时开任务十分钟掉线的尴尬画面了。

使用 WireGuard 进行加速

首先是换掉 shadowsocks,改用 WireGuard 提供 VPN 方案。具体来说的话,shadowsocks 本身是对 socks5 代理进行加密传输来实现代理,本质上是一个应用层代理。而透明代理是对设备的 IP Packet 进行代理,需要额外的工作才能实现,目前主要的两种方式是 ss-redir 和 iptables 流量重定向,或者是使用移动平台上常见的 tun2socks 来完成 L5 转 L3。WireGuard 那边呢,因为这玩意本身就是一个 L3 VPN,在两个 peer 上都会创建一个 tun 接口,并使用 UDP 来完成 tun 接口中流量的传递,对操作系统等来说这就是一个常规的 L3 隧道,也就避免了不必要的麻烦。

我们分别在代理服务器和家里的路由器上创建 WireGuard 接口,这些步骤网上已经有大量的内容可供参考,就不再描述了。假定服务器的 IP 为 172.16.150.16/24,路由器的 IP 为 172.16.150.1/24。和正常的 VPN 使用场景不同,我们需要让远程服务器提供 NAT 服务,因此需要在服务器端的 iptables 上动一些手脚,在 WireGuard 的配置文件的 [Interface] 部分增加以下内容:

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

OpenWrt 那一侧呢就很简单了,直接安装 luci-proto-wireguard 和其他你需要的管理工具,然后去 LuCI 中创建 WireGuard 接口并添加 Peer 配置。创建完成之后启动接口,WireGuard 应该就顺利启动运行了。

为 PS4 创建路由规则

既然是为 PS4 提供游戏加速,这个 VPN 承载的数据也只应该是 PS4 的连接,子网内的其他设备仍然应该使用运营商的默认路由访问互联网(主要是付不起这个流量费 QAQ),也就是需要做一下简单的策略路由。第一步,在 /etc/iproute2/rt_tables 文件内追加一些内容:

echo '200     ps4' >> /etc/iproute2/rt_tables

然后,在 iptables mangle 表中的 PREROUTING 链上插入规则,给所有来自 PS4 的流量打上一个 mark:

iptables -I PREROUTING -t mangle -s 172.16.10.190/32 -j MARK --set-mark 100

并给之前创建的名为 ps4 的路由表添加默认路由,将默认路由指向 WireGuard VPN 中的服务端 IP:

ip route add default via 172.16.150.16 dev wg_vpn table ps4

最后添加规则,让带有 mark 100 的流量走 ps4 路由表即可:

ip rule add fwmark 100 table ps4

完成这些操作之后,打开 PS4 上的网络浏览器,访问任意一个能查看到自己 IP 的网站(例如 https://ipinfo.io/)来验证是否生效。

排除 PS4 的下载流量

和之前一样,现在这年头游戏动辄五六十 GB,走 VPN 下载显然不妥,因此依然需要对这些流量进行处理。

我们依然先使用国内的 DNS 解析 PSN 所有的 CDN 服务器,并将这些地址写入 host 文件中,我这里解析下来后的内容如下:

# PlayStation Network CDN domains resolved with 223.5.5.5
63.243.242.154  ares.dl.playstation.net
63.243.242.155  ares.dl.playstation.net
63.243.242.160  ares.dl.playstation.net
63.243.242.161  ares.dl.playstation.net
63.243.242.168  ares.dl.playstation.net
63.243.242.169  ares.dl.playstation.net
63.243.242.170  ares.dl.playstation.net
63.243.242.171  ares.dl.playstation.net
63.243.242.176  ares.dl.playstation.net
63.243.242.155  gs.ww.np.dl.playstation.net
63.243.242.160  gs.ww.np.dl.playstation.net
180.153.126.12  gs2.ww.prod.dl.playstation.net
180.153.126.137 gs2.ww.prod.dl.playstation.net
23.62.109.111   poseidon.dl.playstation.net
23.62.109.95    poseidon.dl.playstation.net
63.243.242.154  zeus.dl.playstation.net
63.243.242.155  zeus.dl.playstation.net
63.243.242.160  zeus.dl.playstation.net
63.243.242.161  zeus.dl.playstation.net
63.243.242.168  zeus.dl.playstation.net
63.243.242.169  zeus.dl.playstation.net
63.243.242.170  zeus.dl.playstation.net
63.243.242.171  zeus.dl.playstation.net
63.243.242.176  zeus.dl.playstation.net

这样我们只需要将上面出现过的所有 IP 地址的默认路由改成 PPPoE 接口即可:

cat /etc/hosts | grep -i playstation \
               | grep -v '#' \
               | awk '{ print $1 }' \
               | sort | uniq \
               | awk '{ print "ip route add "$1"/32 dev pppoe-wan table ps4" }'
               | sh

完成之后,我们可以进入 PS4 的设置 -> 网络,进行网络连接测试,并观察路由器上 WireGuard 接口的 RX/TX 变化,来验证配置是否生效。

当然这些下载流量应该有更加优雅的解决方案,比如在 dnsmasq 的配置文件中指定这些域名使用运营商 DNS,并通过 ipset 来标明这部分流量来实现策略路由。这些就留着给下一次 PS4 网络优化再做吧(

服务器的选择

考虑到 WireGuard 是一个 UDP 为主的 VPN 协议,选择服务器比选择日常使用的代理服务器要麻烦很多。服务器方面,我个人比较建议去选择一些能“不过墙”的方案,比如某阿里云深圳机房和香港机房经典网络的某些网段能内网互通,只要交两倍的流量费和两倍的服务器费就能蹭上专线访问外网。当然还有其他的一些方法,这些我就不多说了。家庭宽带这一侧的话,就还是尽可能选正经运营商吧,截至目前我自己的上海电信宽带依然拥有公网 IPv4 地址,UDP 好像也没遇到什么特别激进的 QoS,可以说是非常感谢了(


2019 年 9 月 12 日更新:

Iceborne 已经打通好几天了,真好玩建议大家都来玩一玩,这一整套加速方案也在过去的几十个小时的游戏时间里保证了几乎完美的游戏体验:Party 完全没有出现过 NAT 警告,游戏本身也从未发生过掉线等问题。