2024-07 宿舍网络设计

因为工作原因搬到了校内家属区,楼层高位置略偏信号不好,就想着自己搞一套用起来(冲浪)舒适的网络。

背景&需求

背景

在宿舍:

  • 我的房间信号较差,躺床上翻个身就没信号了
  • 房子弱电箱自带一根校园网入户线,能够通过 pppoe 接入校园网,带宽 100mbps;同时弱电箱预留了到各个房间的网线,房东不允许施工
  • 拨号接入校园网只有 IPv4,运营商随机分配,学校所在城市除电信以外的网络出海质量极差
  • 上一任房客留了若干台路由器,但都是百兆
  • 室友对网络要求不高

在实验室:

  • 设备有组建局域网传输数据的要求,希望在实验室能够组一个内网使用固定 IP
  • 自己的游戏本太重索性丢在宿舍,平时带着轻薄本去实验室,希望能够在实验室通过 VPN 访问宿舍内网
  • 实验室给的电脑配置一般,懒得搭环境直接搞成虚拟化服务器,希望在宿舍也能够通过 VPN 访问实验室内网
  • 校园网奇怪的防火墙策略导致自己代理经常抽风

需求

  • 由于校园网入户线上游交换机协商速率为 1Gbps,希望能够利用这个带宽,保证每人都能够使用自己的校园网账号上网,这样大家都有 100Mbps 带宽
  • 希望单独拉一条电信到自己房间,既能提供良好的网络体验,又能为实验室的机器提供一个稳定的中转
  • 自己房间需要同时接入校园网和电信,使用电信访问 Internet,同时也能通过校园网访问学校内网资源

网络拓扑

设计上主要痛点是房东不允许施工以及只有一根校园网入户线,遂引入一台支持 VLAN 的交换机,路由器则使用软件 VLAN 即可。

拓扑如下图:

设备选型

首先自己手上有一台陪了自己一年的刷好 OpenWrt 的红米 AX6000,前任房客留下了一台 TP-Link 路由器(百兆),三台斐讯 K2 (百兆)。前任房客的设备就留给室友用了。接下来需要一台路由器放到实验室,一台支持 VLAN 的交换机。

由于交换机只需要负载电信的接入与校园网的接入,预计峰值也就 1Gbps+3*100Mbps,因此选择一台够用的,至少 5 口的千兆交换机即可。路由器的话额外需要一台能够刷 OpenWrt 的千兆路由器。

最终设备清单如下:

  • 红米 AX6000
  • 小黄鱼上不到 100 块收的小米 WR30U
  • TP-Link TL-SG2008D

后面两台设备花了 200 多一点,很划算了。

电信最终选择了 500Mbps 的套餐,改桥接。不得不吐槽一下,当地的调测费好贵。

交换机配置

插上交换机直接开干,直接 dot1q 一开,配置结果如下图:

对应描述如下表:

Port VLAN 本征 VLAN 描述
1 50 50 电信接入
2 10 10 校园网接入
3 1,10,50,100 1 我的房间
4 10 10 室友 A 房间
5 10 10 室友 B 房间
6 10 10 未使用
7 10 10 未使用
8 10 10 未使用

由于室友的设备都不支持 VLAN,所以直接本征 VLAN 10。

而我留本征 VLAN 1 的原因是该交换机使用 10.18.18.251 作为默认管理 IP,留着以防交换机出现问题导致无法访问管理界面。

路由器配置

网络配置

子网划分以及相关接口配置如下:

设备 接口 地址 区域 描述
AX6000 wan.10 / wan 校园网接入
AX6000 wan.50 / wan 电信接入
AX6000 wan.100 192.168.121.1/24 wan 交换机管理
AX6000 br-lan 192.168.120.1/24 lan 宿舍子网
AX6000 wg 172.16.100.1/24 vpn site-to-site VPN
WR30U wan / wan 校园网接入
WR30U lan 192.168.240.1/24 lan 实验室子网
WR30U wg 172.16.100.2/24 vpn site-to-site VPN

实验室的路由器直接刷 OpenWrt 配置 WAN 口的 pppoe,不做赘述,这里主要以宿舍的路由器的 WAN 口为例,直接上 /etc/config/network 配置(仅 WAN 口相关配置,脱敏):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
config device
option name 'wan'

config interface 'wan'
option device 'wan'
option proto 'none'

config device
option type '8021q'
option ifname 'wan'
option vid '100'
option name 'wan.100'
option macaddr '**REDACTED**'

config interface 'management'
option proto 'static'
option device 'wan.100'
option ipaddr '192.168.121.1'
option netmask '255.255.255.0'

config device
option type '8021q'
option ifname 'wan'
option vid '10'
option name 'wan.10'
option macaddr '**REDACTED**'

config interface 'campus'
option proto 'pppoe'
option device 'wan.10'
option username '**REDACTED**'
option password '**REDACTED**'
option ipv6 'auto'
option sourcefilter '0'
option delegate '0'
option defaultroute '0'

config device
option type '8021q'
option ifname 'wan'
option vid '50'
option name 'wan.50'
option macaddr '**REDACTED**'

config interface 'ct'
option proto 'pppoe'
option device 'wan.50'
option username '**REDACTED**'
option password '**REDACTED**'
option ipv6 'auto'

由于存在两个 WAN 口,我们决定只使用电信的线路(校园网是随机分配的),因此在 campus 接口中设置 defaultroute '0',这样的话路由表中的默认路由条目就不会指向校园网的接口。

同时我们还有访问校园网资源的需求,因此需要额外配置校园网的路由表条目,首先校园网的地址为 A 类私有地址,我们直接加一条10.0.0.0/8的路由表条目即可;同时学校的校园网 DNS 解析出来的地址与外部地址是一致的,因此我们不需要对 DNS 进行额外处理,使用任意学校域名解析出来的地址到bgp.he.net上查一下对应的地址块,同样加入路由表即可。(很早之前bgp.he.net的 CERNET IPv4 Prefix 的 description 字段是有学校名称的,现在没了,对于持有多个地址块的学校需要额外处理或者直接将整个 CERNET 的 prefix 全部加入路由表)。这里给出/etc/config/network中的配置:

1
2
3
4
5
6
7
config route
option interface 'campus'
option target '10.0.0.0/8'

config route
option interface 'campus'
option target '202.**REDACTED**/**REDACTED**'

由于校园网拨号不提供 IPv6,因此我们不做讨论。

site-to-site VPN 配置

校园网内部的设备好像没有太严格的隔离,自己的两个设备可以互相访问,因此可以配置一个 site-to-site VPN 来保证宿舍与实验室的设备能够相互访问。

对于拨号导致的 IP 变动,我们可以使用 DDNS 服务来解决,具体根据自己的域名配置的 DNS 服务器提供的接口选择配置方案,这里不做讨论。

OpenVPN 方案

OpenVPN 采用 Client-Server 模式,宿舍路由器做 Server,实验室路由器做 Client。

证书生成采用 Easy-RSA,直接根据官方文档生成即可,服务端需要生成一个服务器证书,客户端需要生成一个客户端证书。

服务端配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
config openvpn 'site_to_site'
option dev 'tun'
option comp_lzo 'yes'
option dh '/etc/openvpn/dh.pem'
option keepalive '10 60'
option key '/etc/openvpn/server.key'
option cert '/etc/openvpn/server.crt'
option verb '3'
option ca '/etc/openvpn/ca.crt'
option server '172.16.10.0 255.255.255.0'
option client_to_client '1'
list route '192.168.240.0 255.255.255.0'
option port '1194'
option proto 'udp'
list push 'route 192.168.120.0 255.255.255.0'
option client_config_dir '/etc/openvpn/ccd'

服务端有以下关键配置:

  • client_to_client:允许客户端之间通信(如果要接入多个站点的话需要打开)
  • route:为本机增加到实验室子网(客户端)的路由
  • push:为客户端(推送)增加到宿舍子网(服务端)的路由
  • client_config_dir:客户端配置文件目录

其中 /etc/openvpn/ccd/client 内容如下:

1
iroute 192.168.240.0 255.255.255.0

即 OpenVPN 的内部路由,告诉 OpenVPN 服务端该子网是由客户端client接入的。这里的文件名需要与客户端证书的 common name 保持一致。

客户端配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
config openvpn 'site_to_site'
option nobind '1'
option float '1'
option client '1'
option comp_lzo 'yes'
option reneg_sec '0'
option dev 'tun'
option verb '3'
option persist_tun '1'
option pkcs12 '/etc/openvpn/client.p12'
option persist_key '1'
option remote_cert_tls 'server'
option ca '/etc/openvpn/ca.crt'
option pull '1'
list remote '**REDACTED**'

这里的关键配置有:

  • pull:允许服务端推送路由(当然你也可以选择手动添加)

同时为了方便管理,我们可以定义一个接口tun0,并为其关联防火墙区域以保证安全,这里不做讨论。

WireGuard 方案

WireGuard 直接生成密钥+PSK,然后建立 peer 即可,直接上配置(/etc/config/network):

宿舍路由器配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
config interface 'wg'
option proto 'wireguard'
option private_key '**REDACTED**'
option listen_port '51820'
list addresses '172.16.100.1/24'

config wireguard_wg
option description 'lab'
option public_key '**REDACTED**'
option preshared_key '**REDACTED**'
option route_allowed_ips '1'
option endpoint_host '**REDACTED**'
option endpoint_port '51820'
option persistent_keepalive '10'
list allowed_ips '192.168.240.0/24'
list allowed_ips '**REDACTED,IPv6 ULA**'
list allowed_ips '172.16.100.2/32'

实验室路由器配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
config interface 'wg'
option proto 'wireguard'
option private_key '**REDACTED**'
option listen_port '51820'
list addresses '172.16.100.2/24'

config wireguard_wg
option description 'dorm'
option public_key '**REDACTED**'
option preshared_key '**REDACTED**'
option endpoint_host '**REDACTED**'
option endpoint_port '51820'
option route_allowed_ips '1'
option persistent_keepalive '10'
list allowed_ips '192.168.120.0/24'
list allowed_ips '**REDACTED,IPv6 ULA**'
list allowed_ips '172.16.100.1/32'

一些 VPN 上的骚操作

学校防火墙会莫名其妙地封掉我服务器的 443,使我代理抽风,影响工作,不妨利用一下 VPN 回到宿舍使用电信家宽中转一下。直接使用 OpenWrt 的端口转发功能做个 DNAT 即可,配置如下/etc/config/firewall

1
2
3
4
5
6
7
8
9
10
config redirect
option dest 'wan'
option target 'DNAT'
option name 'Relay'
option family 'ipv4'
list proto 'tcp'
option src 'vpn'
option src_dport '1443'
option dest_ip '**REDACTED**' # 服务器IP
option dest_port '443' # 服务器端口

总结

一场酣畅淋漓的网络配置,期间折腾了一个星期左右(主要是等电信的师傅施工啥的),还有就是 VPN 配置过程中没看文档导致各种奇奇怪怪的问题。甚至还有忘记存交换机配置导致交换机重启导致网络整个挂掉的事情。

最早还想拿 MWAN3 做负载均衡,但后来发现与 zerotier 兼容性好像有点问题,就放弃了。还有一个问题是,OpenVPN 的回程路由有的时候会被 zerotier 的路由顶掉,这也是我换用 WireGuard 的原因之一。

Site-to-site VPN 使用 DDNS 服务来解决 IP 变动实际上还是有一定的局限性,IP 变动后实际上是需要重启 VPN 服务来重新解析地址的,再加上 ISP 那边的 DNS 缓存实际上会有几十分钟的延迟,这个问题在实际使用中还是有一定的影响。(条件允许的话可以自己搓一个脚本来监测 IP 变动自动重启 VPN 服务,或者直接搓一套服务来追踪 IP)