家里网络环境比较简单,网络相关的硬件也比较少,所以也没啥能折腾的,只有以下几个设备:

  1. 联通光猫
    型号是中兴的 F657GV9-C,在没有联通没有下发动态密码时改了桥接。本来还想破解一下开telnet,后来想想把桥接的配置备份出来就行了,没啥特别的需求就不折腾了。
  2. 软路由
    彻视的N4100,4核4线程,基础频率1.1g,最高频率2.4g,性能比网上这几年流行的J4125还要差,但比arm架构的强多了。主机有4个 Intel I226 的 2.5G 网口,自己买了8G内存和128G的msata,又加了一个内置风扇,本身发热就不大,和光猫一起丢弱电箱夏天也不用担心散热。不打算折腾虚拟机,直接装一个路由系统足够带千兆的带宽了,重点是一套下来也才四百块。
  3. AP,是TP-Link XAP5400GC,单 AP 放在房子中间基本就完全覆盖了

物理连接: 光猫(改桥接) --> N4100 --> TPlink AP XAP5400GC。

由于想找个和 linux 贴近的开源路由系统,最好是和云也能沾点边,所有选择了 vyos,经过一段时间的使用,实现了以下功能:

  1. WAN/LAN 分别使用两个网口,网口绑定,实现盲插
  2. PPPoE 拨号 及 DHCP server
  3. cake qos
  4. Zone Based firewall
  5. 科学相关(略)
  6. 一些远程访问相关的容器

一、物理网卡配置

这个小主机有四个 i226 的 2.5g 网口,网口分配 eth0/eth1 WAN 口,eth2/eth3 LAN 口,这个小机器的网卡顺序在系统中默认不是0/1/2/3,因此要绑定网卡名字和 mac 地址,防止重启后名字变化。

1.1 绑定网卡名字及 mac 地址

set interfaces ethernet eth0 hw-id '60:be:xx:xx:xx:xx'
set interfaces ethernet eth1 hw-id '60:be:xx:xx:xx:yy'

1.2 开启硬件 offload

offload 简单理解就是网卡硬件中已经实现了一些数据包的处理,开启后不在使用 cpu 处理,能够提升性能。以 eth0 为例子,其他的网卡也需要设置:

set interfaces ethernet eth0 offload gro
set interfaces ethernet eth0 offload gso
set interfaces ethernet eth0 offload lro
set interfaces ethernet eth0 offload rfs
set interfaces ethernet eth0 offload rps
set interfaces ethernet eth0 offload sg
set interfaces ethernet eth0 offload tso
set interfaces ethernet eth0 ring-buffer rx '4096'
set interfaces ethernet eth0 ring-buffer tx '4096'

1.3 WAN/LAN 接口配置

我要实现的是 eth0/eth1 绑定成一个 bond0 ,在 bond0 上在启用一个桥接的 br0 作为 wan 口;同理,eth2/eth3 绑定成一个 bond1,在 bond1 上在启用一个桥接的 br1 作为 Lan 口。
这样做的好处是 eth0/eth1 和 eth2/eth3 可以随便插,有冗余的效果,稍加配置也可以实现两个端口的链路聚合,实现带宽叠加。

配置 wan 和 Lan 口物理网卡绑定:

set interfaces bonding bond0 description 'Bond Interface WAN'
set interfaces bonding bond0 member interface 'eth0'
set interfaces bonding bond0 member interface 'eth1'
set interfaces bonding bond1 description 'Bond Interface LAN'
set interfaces bonding bond1 member interface 'eth2'
set interfaces bonding bond1 member interface 'eth3'

设置WAN的桥接 br0 和 LAN 的桥接 br1,这里的 stp 其实开不开都用处不大。另外我给 Lan 口配置了一个10.0.0.254的ip,后续的容器都绑定到这个 ip 上。

set interfaces bridge br0 description 'WAN bridge'
set interfaces bridge br0 member interface bond0
set interfaces bridge br0 stp

set interfaces bridge br1 address '10.0.0.1/24'
set interfaces bridge br1 address '10.0.0.254/32'
set interfaces bridge br1 description 'LAN bridge'
set interfaces bridge br1 member interface bond1
set interfaces bridge br1 stp

二、 WAN 口 PPPoE 拨号配置

2.1 拨号配置

前提是光猫要改桥接,并且有宽带的拨号信息,先从光猫的 LAN 口接一条网线到 vyos 的 eth0 或 eth1 接口,并启用一个pppoe0的接口, 自动配置 MTU :

set interfaces pppoe pppoe0 authentication password '宽带密码'
set interfaces pppoe pppoe0 authentication username '宽带账号'
set interfaces pppoe pppoe0 description 'China Unicom'
set interfaces pppoe pppoe0 ip adjust-mss 'clamp-mss-to-pmtu'
set interfaces pppoe pppoe0 source-interface 'br0'

2.2 IPv6 PD 配置

首先设置需要设置 prefix,我的运营商是给的是/60

set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface br1 address '1'
set interfaces pppoe pppoe0 dhcpv6-options pd 0 interface br1 sla-id '0'
set interfaces pppoe pppoe0 dhcpv6-options pd 0 length '60'
set interfaces pppoe pppoe0 ipv6 address autoconf
set interfaces pppoe pppoe0 ipv6 adjust-mss 'clamp-mss-to-pmtu'

设置路由器公告RA:

set service router-advert interface br1 link-mtu '1490'
set service router-advert interface br1 prefix ::/64 valid-lifetime '172800'
set service router-advert interface pppoe0

2.3 多拨

多拨需要运营商支持,vyos 的多拨非常简单,新启用一个 pppoe 的接口拨号即可:

set interfaces pppoe pppoe1 authentication password '宽带密码'
set interfaces pppoe pppoe1 authentication username '宽带账号'
set interfaces pppoe pppoe1 description 'China Unicom WAN multi-pppoe-2'
set interfaces pppoe pppoe1 source-interface 'br0'

至此 WAN 的配置全部结束。

三 、 LAN 配置 DHCP

3.1 启用 LAN 口的 DHCP server

LAN 的网段是 10.0.0.0/24,DHCP 的分配 IP 范围是 10.0.0.100-200,同时下发了 dns server 和 ntp server。

set service dhcp-server dynamic-dns-update
set service dhcp-server hostfile-update
set service dhcp-server listen-interface 'br1'
set service dhcp-server shared-network-name LAN_br1 authoritative
set service dhcp-server shared-network-name LAN_br1 option ntp-server '10.0.0.1'
set service dhcp-server shared-network-name LAN_br1 option time-zone 'Asia/Shanghai'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 subnet-id '1'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 lease '86400'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 option default-router '10.0.0.1'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 option domain-name 'home.local'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 option domain-search 'home.local'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 option name-server '10.0.0.1'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 range 100 start '10.0.0.100'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 range 100 stop '10.0.0.200'

3.2 绑定静态 IP

如果有固定的硬件,可以绑定固定的 IP

set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 static-mapping TPlink-AP ip-address '10.0.0.2'
set service dhcp-server shared-network-name LAN_br1 subnet 10.0.0.0/24 static-mapping Sony-TV ip-address '10.0.0.21'

绑定固定 IP 后,直接ping TPlink-AP或者 ping Sony-TV 还无法解析,还需要配置 DNS。

3.3 局域网 DNS 配置

Vyos 自带 Powerdns recursor ,不添加上游 dns 服务器也可以正常解析。

set service dns forwarding allow-from '10.0.0.0/24'
set service dns forwarding authoritative-domain home.local records a TPlink-AP address '10.0.0.2'
set service dns forwarding authoritative-domain home.local records a Sony-TV address '10.0.0.21'
set service dns forwarding listen-address '10.0.0.1'
set service dns forwarding listen-address '::1'
set service dns forwarding name-server 10.0.0.254

vyos 的 pdns 为了保持简单,能设置的功能并不多,本例子中的上游是 dns server 是本机的 mosdns container ,绑定的是 10.0.0.254 udp 53端口。可以改成公共 dns 也可以设置多个。

3.4 局域网 NTP 配置

set service ntp allow-client address '10.0.0.0/24'
set service ntp interface 'br1'
set service ntp listen-address '10.0.0.1'
set service ntp server asia.pool.ntp.org
set service ntp server time.apple.com
set service ntp server time.aws.com
set service ntp server time.cloudflare.com

到这一步基本的局域网配置就已经可以了,其他设备加入就可以自动获取 ip 并上网了。

四、QoS 流量管理

Vyos 提供了非常完善的 Qos Policy,常见的流量策略都支持。家用不用那么麻烦直接使用 Cake 仅需要设置一下带宽,要注意的是启用 Qos 会占用 CPU,同时可能会导致带宽跑不满。好处是多人占用带宽时,可以为每一个人合理分配宽带资源。

set qos policy cake Qos_Cake_Lan bandwidth '1gbit'
set qos policy cake Qos_Cake_Lan description 'Qos For Lan interface br1'
set qos policy cake Qos_Cake_Lan flow-isolation dual-src-host
set qos policy cake Qos_Cake_Lan rtt '100'
set qos interface br1 egress 'Qos_Cake_Lan'

五、防火墙配置

Vyos rolling 版本已经实现了zone based 的防火墙。

5.1 全局配置

配置防火墙的全局配置和默认的 statefull 行为。

set firewall global-options all-ping 'enable'
set firewall global-options state-policy established action 'accept'
set firewall global-options state-policy invalid action 'drop'
set firewall global-options state-policy related action 'accept'
set firewall global-options syn-cookies 'enable'

5.2 创建 zone

创建三个zone,分别是 LOCAL/LAN/WAN,在 Vyos 中,local zone指vyos自身。创建 zone 的同时指定与其他 zone 之间的访问规则,ipv4 和 ipv6 的规则要分开指定。

set firewall zone LOCAL default-action 'drop'
set firewall zone LOCAL from LAN firewall ipv6-name 'LAN_to_LOCAL-ipv6'
set firewall zone LOCAL from LAN firewall name 'LAN_to_LOCAL'
set firewall zone LOCAL from WAN firewall ipv6-name 'WAN_to_LOCAL-ipv6'
set firewall zone LOCAL from WAN firewall name 'WAN_to_LOCAL'
set firewall zone LOCAL local-zone

set firewall zone LAN default-action 'drop'
set firewall zone LAN from LOCAL firewall ipv6-name 'LOCAL_to_LAN-ipv6'
set firewall zone LAN from LOCAL firewall name 'LOCAL_to_LAN'
set firewall zone LAN from WAN firewall ipv6-name 'WAN_to_LAN-ipv6'
set firewall zone LAN from WAN firewall name 'WAN_to_LAN'
set firewall zone LAN interface 'br1'

set firewall zone WAN default-action 'drop'
set firewall zone WAN from LAN firewall ipv6-name 'LAN_to_WAN-ipv6'
set firewall zone WAN from LAN firewall name 'LAN_to_WAN'
set firewall zone WAN from LOCAL firewall ipv6-name 'LOCAL_to_WAN-ipv6'
set firewall zone WAN from LOCAL firewall name 'LOCAL_to_WAN'
set firewall zone WAN interface 'br0'
set firewall zone WAN interface 'pppoe0'

5.3 创建 zone 之间的访问规则

为了方便调试,对于 drop 的规则启用日志。创建 zone LOCAL 到 WAN 和 LAN的 ipv4 和 ipv6 规则:

set firewall ipv4 name LOCAL_to_LAN default-action 'accept'
set firewall ipv4 name LOCAL_to_WAN default-action 'accept'

set firewall ipv6 name LOCAL_to_LAN-ipv6 default-action 'accept'
set firewall ipv6 name LOCAL_to_WAN-ipv6 default-action 'accept'

创建 zone LAN 到 WAN 和 LOCAL的 ipv4 和 ipv6 规则:

set firewall ipv4 name LAN_to_LOCAL default-action 'accept'
set firewall ipv4 name LAN_to_WAN default-action 'accept'
set firewall ipv4 name LAN_to_WAN rule 20 action 'return'
set firewall ipv4 name LAN_to_WAN rule 20 description 'ipv4 stateful from LAN to WAN'
set firewall ipv4 name LAN_to_WAN rule 20 state 'established'
set firewall ipv4 name LAN_to_WAN rule 20 state 'related'
set firewall ipv4 name LAN_to_WAN rule 20 state 'new'
set firewall ipv4 name LAN_to_WAN rule 20 state 'invalid'

set firewall ipv6 name LAN_to_LOCAL-ipv6 default-action 'accept'
set firewall ipv6 name LAN_to_WAN-ipv6 default-action 'accept'
set firewall ipv6 name LAN_to_WAN-ipv6 description 'ipv6 stateful from LAN to WAN'
set firewall ipv6 name LAN_to_WAN-ipv6 rule 20 action 'return'
set firewall ipv6 name LAN_to_WAN-ipv6 rule 20 state 'established'
set firewall ipv6 name LAN_to_WAN-ipv6 rule 20 state 'new'
set firewall ipv6 name LAN_to_WAN-ipv6 rule 20 state 'related'
set firewall ipv6 name LAN_to_WAN-ipv6 rule 20 state 'invalid'

创建 zone WAN 到 LAN 和 LOCAL的 ipv4 和 ipv6 规则,需要注意的是要放行 WAN pppoe的ipv6 pd相关的 dhcp/icmp 等:

set firewall ipv4 name WAN_to_LAN default-action 'drop'
set firewall ipv4 name WAN_to_LAN default-log
set firewall ipv4 name WAN_to_LOCAL default-action 'drop'
set firewall ipv4 name WAN_to_LOCAL default-log

set firewall ipv6 name WAN_to_LAN-ipv6 default-action 'drop'
set firewall ipv6 name WAN_to_LAN-ipv6 default-log
set firewall ipv6 name WAN_to_LOCAL-ipv6 default-action 'drop'
set firewall ipv6 name WAN_to_LOCAL-ipv6 default-log
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 10 action 'drop'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 10 icmpv6 type-name 'echo-request'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 10 protocol 'ipv6-icmp'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 20 action 'accept'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 20 protocol 'ipv6-icmp'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 30 action 'accept'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 30 destination port '546'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 30 protocol 'udp'
set firewall ipv6 name WAN_to_LOCAL-ipv6 rule 30 source port '547'

六、科学上网

个人一直反感写这类文章,这里仅提供思路。vyos 是专业的路由系统,又支持 podman, 实现科学功能相当容易。
我个人使用的方案是 ospf over wireguard over websocket, 需要配置以下内容:

  1. 无污染的 dns: 使用 mosdns 运行在 vyos 的容器中, 实现国内外域名分流,广告屏蔽等
  2. 境外服务器: 1. 安装 bird 跑 ospf和bfd 2. wireguard 3. openresty + v2ray server 4. ospf 分流脚本
  3. Vyos: 1. ospf(non-broadcast)+ bfd 2. wireguard 3.v2ray容器(udp over websocket/load balancer)

七、其他杂项配置

set system host-name 'vyos'
set system name-server '10.0.0.1'
set system time-zone 'Asia/Shanghai'
set system update-check auto-check
set system update-check url 'https://raw.githubusercontent.com/vyos/vyos-rolling-nightly-builds/main/version.json'

set service ssh access-control allow user 'vyos'
set service ssh listen-address '10.0.0.1'
set service ssh port '22'
set system login user vyos authentication plaintext-password 'vyos.opswill.com'

set system config-management commit-archive location 'https://user:pass@backup.opswill.com'
set system config-management commit-archive source-address '10.0.0.1'
set system config-management commit-revisions '100'

另外还跑了一些容器:

  1. cloudflare-dns :ddns,每五分钟更新 ipv4 和 ipv6 地址
  2. cloudflared:cloudflare tunnel,使用 zero trust 远程访问路由器
  3. tailscale: 手机等设备使用家里的网络上网
  4. mosdns: 上文有提到,提供无污染 dns server
  5. v2ray: 提供udp over websocket 供wirguard使用

八、总结

虽然写了一大堆,但是整体配置起来非常快,感觉比其他有 web 管理的路由系统更容易配置和使用。家里已经稳定运行了将近一年,我基本上每个月升级两次,即使 rolling 版本也很少遇到问题,值得推荐和使用。