三百兆下行教育网?

六百兆上行教育网?

这便是我对实验室网络的最初印象。
虽然学校的官网宣称教学楼全面部署了 ipv6,但无论是改写 Linux 端的网络配置,还是通过 社工 手段登录路由器后台,我都没有找到 ipv6 连接。不过由于这条网线是从楼上引出,所以我猜测问题可能是出在楼上。 也有可能是学校还没有更换支持 ipv6 的设备

而又因为嵌入式的学习并不依赖于 PC 硬件配置,我也不想背着电脑跑来跑去,所以我将小主机移到了实验室,在享受高速网络的同时,也充当着我的伪·服务器

组建内网

现在主流的组建内网的方式有两种 —— tailscalezerotier

就我使用情况来看,zerotier 在稳定性上比 tailscale 强,在 tailscale 打洞失败时,zerotier 仍可以进行 P2P 打洞。
但是,在 tailscale 的 P2P 打洞成功时,其网络性能比 zerotier 更好,延迟更低。
zerotier
tailscale

两者的免费版都有着各自的限制,tailscale 甚至不能自定义网段。在一番搜索后,我也找到了其开源替代品 —— Headscale。

Headscale 由欧洲航天局的 Juan Font 使用 Go 语言开发,在 BSD 许可下发布,实现了 Tailscale 控制服务器的所有主要功能,可以部署在企业内部,没有任何设备数量的限制,且所有的网络流量都由自己控制。

至于部署教程,我在此也不再贅述。

自动登录

一次认证登录后可全天上网。系统设置每天凌晨2点自动注销下线。
上网安全性增强。认证和注销机制可降低电脑被远程控制的风险,帐号实名可降低非法用户匿名上网导致的安全风险。

根据学校官网的介绍,教学办公区校园网会在凌晨2点自动注销下线,来提高网络安全性。但我的需求是24小时全天连接外网,自然而然就相互矛盾了。
不过好在当初折腾寝室网络时,已经对这种情况有了应对的方法。
很快,我使用 HttpCanary 在手机端抓取到了登录的请求包,也写好了请求登录的脚本。

问题突现

这时,我突然发现 Linux 无法访问认证网页。
起初,我以为是学校的服务器又一次抽风了,便没怎么在意。在搁置了半个小时后,我再次尝试访问网页,结果依旧。而手机端的访问却没有问题。
运行ping命令ping auth.haut.edu.cn,却得到了 目标主机不可达 的回复。
来自 172.17.0.1 icmp_seq=1 目标主机不可达

难不成,是静态网络的缘由?要更改DNS和网桥?
初步更改后,问题仍然没有解决。我甚至通过了社工的手段,进入路由器后台查看DNS,依旧没有奏效。

愁眉莫展之际,我突然起了疑问,为何发送给 auth.haut.edu.cn(172.17.101.100) 的请求,会被主机 172.17.0.1接收?可能是 Manjaro 的默认网桥的设置?
在翻阅了 ArchLinux 的 Wiki 后,我输入了ip route这个命令。
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
根据其反馈的结果,我也找到了问题缘由—— docker 默认网桥。

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。

解决方法

首先,创建一个 sh 脚本,来创建一个新的网桥docker1,来解决ip冲突问题。

1
2
3
sudo brctl addbr docker1
sudo ip addr add 190.168.0.1/24 dev docker1
sudo ip link set dev docker1 up

然后,创建一个autostart服务,在系统启动时运行这个脚本。
vim /usr/lib/systemd/system/autostart.service

1
2
3
4
5
6
7
8
9
10
# autostart.service
[Unit]
Description=run shell script

[Service]
ExecStart= /etc/auto.sh
Type = simple

[Install]
WantedBy=multi-user.target

最后,增加docker.service中的启动参数-b=docker1,使用创建的docker1网桥。
vim /lib/systemd/system/docker.service

1
2
3
# docker.service
ExecStart=/usr/bin/dockerd -H fd:// -b=docker1
ExecReload=/bin/kill -s HUP $MAINPID

至此,就可以reboot来重启 Linux ,来确认重启后 docker 是否使用docker1网桥启动。当然,在请求登录的脚本中,也要使用ip link set dev docker0 downbrctl delbr docker0来删除docker0网桥。

结语

网络已经初步地折腾完毕,一台24H的服务器便部署成功了。
只能说可惜没有 ipv6 ,希望学校在日后的升级里可以全面部署 ipv6 吧。

参考文章:

  1. Docker 从入门到实践 —— 配置 docker0 网桥
  2. Network configuration (简体中文)
  3. Running headscale on Linux