距离上一篇文章发布已经好几个月了,自己的网络搭建也和之前有了比较大的区别,就简单的记录一下吧。

基础网络访问

首先是居住场所对 Internet 的访问。大概是去年十月吧,我从之前住的那个只有无线接入网络的小地方搬出来,开始和同事一起合租。花的钱和之前差不多,但是体验上提升了不止一个档次,最明显的一点是对路由器和无线接入点有了完全的控制能力。这间出租房已经准备好了电信的 100Mbps 宽带,然而却配了一个稀烂的无线路由器,并且是由光猫进行 PPPoE,也就是上网过程中出现了两次 NAT,强迫症表示十分不满。

第一步就是解决掉原配的无线路由器,换上了自己在大二时购买的网件 R6250。同时着手光猫的破解,准备将其由路由模式改为桥接模式。光猫的处理上没有遇到什么困难,掀开弱电箱看一下光猫型号并 Google,就顺利地找到了可用的相关教程。然后掏出同事的 x86 路由器,灌入来自 OpenWrt x86_64 18.06.1,并配置好 PPPoE 接口,就顺利的完成了路由改桥接的工作。至于 R6250 呢,则将它配置成接入点(AP)模式,并将 WAN 口与路由器的 LAN 口连接即可。

除此以外,我还购买了迅雷的快鸟会员,该服务可以将 100Mbps 的宽带提升到 200Mbps 下行,20Mbps 上行的水平,体验进一步飞升。

科学上网

正常上网的问题顺利完成之后,科学上网就需要及时安排到位了。既然租的房子只提供了上海电信的运营商网络,那么面向该运营商购买合适线路的 VPS 即可。众所周知中国电信的下一代承载网(CN2)品质非常高,恰好 Bandwagon Host(搬瓦工)也提供了 CN2 GIA 路线的服务器,价格也不算贵,那么买就完事儿了。用了一段时间下来 CN2 GIA 果然没有辜负我对它的期待:

1552641314247-ping.png

图例中第二个 IP 地址是我购买的 VPS 的 IP。就我目前个人使用体验来说,带宽足,流量多,延迟稳定是给我留下印象最深的三个。稳定水平上面的 ICMP 统计就足够说明。而带宽方面,这台服务器任何时刻都能将我 200Mbps 下行,20Mbps 上行的宽带跑满,非常靠谱。

游戏加速

不过那台位于洛杉矶的 VPS 呢,延迟水平因为绕了这么远的路肯定不会低,用它来承载延迟敏感的 PS4 游戏代理显然就会很吃瘪,所以我还另外购买了一台腾讯云的香港虚拟机,同样也是 CN2 的路线,延迟又非常低(35ms 上下),流量价格(0.8CNY/GB)也算是可以接受,毕竟只是改善一下 PS4 和其他游戏设备的联机质量。这两台服务器搭配着使用就几乎能满足所有的个人上网需求了。

游戏加速的方案很简单,因为我使用了一台 OpenWrt 的路由器,配置 shadowsocks-libev 十分容易,只要去 luci 里点点按钮就能完成。将 PS4 的网络加入设备列表,并配置全部流量通过腾讯云的代理,就能享受到极致稳定的 PS4 联机体验了。不过这里还有一个问题,就是家境贫寒,万一哪天 PS4 在家没事儿干下载了一个 100GB 的 RDR2,那流量费就爆炸了。所以呢,需要针对 PSN 的国内 CDN 做一个特判,强制这部分流量直接连接。

首先,使用运营商 DNS 对这些 IP 地址进行手动解析:

ares.dl.playstation.net
gs.ww.np.dl.playstation.net
gs2.ww.prod.dl.playstation.net
poseidon.dl.playstation.net
zeus.dl.playstation.net

并将解析得到的 IP 地址写入 host,我这里就是:

61.130.26.209   ares.dl.playstation.net
61.130.26.216   gs.ww.np.dl.playstation.net
61.130.26.203   gs2.ww.prod.dl.playstation.net
58.218.214.16   poseidon.dl.playstation.net
61.130.26.211   zeus.dl.playstation.net

然后呢,将出现过的 IP 全部加入到 shadowsocks 配置的绕过地址(编辑 /etc/config/shadowsocks):

config access_control
        # ...
        option wan_bp_list '/dev/null' # 不要使用 ChinaDNS 的 chnroutes
        list wan_bp_ips '61.130.26.209'
        list wan_bp_ips '61.130.26.216'
        list wan_bp_ips '61.130.26.203'
        list wan_bp_ips '58.218.214.16'
        list wan_bp_ips '61.130.26.211'

并将 PS4 的代理模式设置为 正常:

config lan_hosts
        option enable '1'
        option host '172.16.10.190'
        option type 'n'

最后重启各类服务:

/etc/init.d/dnsmasq restart
/etc/init.d/shadowsocks restart

这样做的原理就不用多说了吧,很容易理解的。如果觉得太麻烦了的话,可以参考文章最后提供的一个自动更新脚本。

那么,如果我想用 PS4 的 YouTube 来看视频的话,还需要额外解决一个问题:DNS 污染。这里不再推荐 ChinaDNS 的模式,比较麻烦而且规则不算友好。我使用的方案是:任何人都可以自行搭建同时支持地域优化和无污染的 DNS

动态 DNS

上海电信可能是 IP 地址真的特别多,到现在依然给所有的宽带用户提供公网 IP 地址,这就让随时通过奇妙的方案远程访问内网设备十分容易。不过呢,总是去记 IP 比较不现实。之前呢我一直是在路由器上编写 /etc/ppp/ip-up.d/report-ip 脚本来将最近一次 PPPoE 获得的 IP 地址上报到其他我能很容易查看到的地方,比如 Telegram Bot 中。但是这个方案仍然不够理想。

某一天我突然想起来 Microsoft Azure 是提供了各种语言的 SDK 的(其实是 REST API 的包装…),那么自己起一个 DDNS 服务的想法就非常易于实现了。这里我放一份自己实现的,基于 Azure Node.js SDK 的实现,改写成其他你喜欢的语言也没什么难度: https://github.com/ntzyz/playground

远程接入

有了 DDNS 之后,远程接入就非常简单了,这里我准备了两个接入方案,目前都持续正常运行。

WireGuard

WireGuard 想必大家都已经有所了解,配置一个这样的 VPN 可以说是毫无难度,更何况 OpenWrt 提供了 WebUI 来完成配置的填写。因此这里就不再多说了。

Tinc VPN

Tinc VPN 是一个网状网络的 VPN 方案,最大的特点是每一个网络中的设备与其他设备通讯时,会优先尝试创建点对点的连接,而不会消耗其他设备的流量和带宽。同时,与 WireGuard 的 L3 VPN 不同,Tinc 可以提供 L2 级别的虚拟网络设备,即 VPN 的接口承载的是以太网报文,而不是 IP 报文,可以顺利的与其他网络设备进行桥接,也能完成网络发现、广播之类的操作。

具体的配置可以参考 Tinc 官方的文档,非常简单易懂,我这里就简单的说说我利用这个 VPN 实现的效果:

首先我将我所有的服务器和路由器接入到同一个私有网络中,位于网段 172.16.0.0/24,并在所有的设备上配置了网络中路由器的路由(172.16.10.0/24 via 172.16.0.10, 172.16.11.0/24 via 172.16.0.11),这样我的服务器和路由器之间就能通过 Tinc 顺利的访问对方,以及对方子网内的设备。这样做的好处就是当我放假在家时,可以直接访问到上海房子内网的设备(比如 Gen8),进而可以很方便的访问文件,操作设备,甚至是通过SMB的文件共享远程看动画。同时,我在其他的一些境外服务器上配置了 nginx,将一部分域名直接反代到家中路由器的 IP 地址。这样就能很容易的操作路由器的配置,不会被国内 HTTP 服务不备案直接封禁规则的约束了。

反向游戏加速

家里的 Gen8 跑了一些奇奇怪怪的游戏服务器(比如 Factorio 啊,Don't Starve Together 啊,Space Engineer 啊,Minecraft 啊),@ZephRay 也想来玩一玩。前面提到 CN2 GIA 的 VPS 网络质量非常好,如果我们能将一些游戏的服务通过这台服务器进行转发,就能有效地提升北美地区玩家的联机体验。转发的方案有很多,我这里就记录两个目前正在使用的方案:

  1. 使用 Linux 内核的 netfilter 进行转发,通过 iptables 即可完成操作,这个可以在网上找到很多相关的命令,就不在多说了。
  2. 使用 Nginx 提供的 stream 反代,这种方式同时支持 TCP 和 UDP,而且配置简单,值得推荐。
  3. 使用 HAProxy,这种方案最大的问题是只支持 TCP,所以不是很推荐。

以上方案都是建立在 Tinc VPN 的基础之上,在配置时无需再担心家里宽带 PPPoE 之后 IP 的变更,因此操作起来也很方便。即使 PPPoE 发生断开重连,Tinc 也能在网络恢复后的若干秒内恢复正常。


用于自动更新 PSN DNS 的脚本,适用于 OpenWrt

#!/bin/sh

set -e

PSN_DOMAINS="ares.dl.playstation.net gs.ww.np.dl.playstation.net gs2.ww.prod.dl.playstation.net poseidon.dl.playstation.net zeus.dl.playstation.net"
UPSTREAM_DNS="223.5.5.5"
TMP_FILE="/tmp/host_psn"

touch $TMP_FILE

cat /etc/hosts | grep -iv playstation > $TMP_FILE
uci set shadowsocks.@access_control[0].wan_bp_ips=

echo -e "# PlayStation Network CDN domains resolved with "$UPSTREAM_DNS >> $TMP_FILE

for DOMAIN in $PSN_DOMAINS
do
  printf "Resolving $DOMAIN ... "

  DATA=`dig @$UPSTREAM_DNS +short $DOMAIN | grep -Po '^(\d+(\.|$)){4}' | sort | awk '{ print $1"\t'$DOMAIN'" }'`

  # save to file
  echo -e "$DATA" >> $TMP_FILE

  # get all ips
  echo -e "$DATA" | awk '{ print "uci add_list shadowsocks.@access_control[0].wan_bp_ips="$1 }' | sh
  
  printf " OK!\n"
done

cp /etc/hosts /etc/hosts.backup
cp $TMP_FILE /etc/hosts
rm $TMP_FILE

uci commit

echo "Host file replaced. Old host file is /etc/hosts.backup, if any errors encountered"

/etc/init.d/shadowsocks restart
/etc/init.d/dnsmasq restart