“双网线”旁路由之“完美”解决IPv6和千兆瓶颈问题

发布日期:分类:Linux & homelab “双网线”旁路由之“完美”解决IPv6和千兆瓶颈问题有 11 条评论

旁路由是一种homelab常见的需求,主路由用硬路由确保稳定,比如用Mikrotik的RouterOS路由器作为主路由,旁路由使用OpenWrt作为软路由,实现广告过滤和隧道等高级功能,这些功能往往都无法硬件加速,需要消耗大量CPU完成,x86的高性能软路由是很合适的选择。比起使用二级路由,可以减少在旁路由上的一次NAT(仅对于IPv4),提高利率,也便于主路由进行管理。

本文提出了一种整活之余有些实用性的特殊旁路由方案,或者也可称为IPv4不NAT的二级路由方案。

本文环境信息:

  • 主路由RouterOS,旁路由OpenWrt,需要主路由具有3个网口(对于硬路由很容易满足),旁路由至少具备双网口,假设其都为千兆网口;
  • 为了使用IPv6二级路由,运营商给的IPv6前缀至少需要为/63;
    • (常见的/56、/60都可满足,但如果给的是/64,虽然或许也能实现功能,但需要不同的设置)
  • 主内网(全功能)网段:192.168.10.0/24,辅助内网(备用/直连)网段:192.168.88.0/24

0x01 传统旁路由设置

传统的旁路由设置只针对IPv4,旁路由只需要一根网线连接内网和旁路由的LAN,旁路由的WAN空置。主路由LAN口IP为192.168.10.1/24,旁路由LAN口IP为192.168.10.2/24,在内网DHCP服务器设置中设置网关为192.168.10.2(DHCP服务器可运行在主路由或旁路由上,但只能有一个),然后在旁路由中设置网关为192.168.10.1。

这样所有客户端都会使用192.168.10.2作为网关,将出口的IP封包发到旁路由上,旁路由因为开启了ip_forward(路由器都会开启),会对这些封包进行转发:由于在旁路由上设置了192.168.10.1作为网关,于是旁路由就会将这些封包直接转发到192.168.10.1的主路由上(传统旁路由的关键就在于,由于是LAN to LAN转发,所以不会匹配防火墙中LAN to WAN的masquerade规则,即不会进行我们常说的路由器NAT)。由于封包在旁路由上进行了转发,隧道软件就可以通过防火墙NAT表中的规则对这些封包进行处理(比如redirect和tproxy),满足我们使用旁路由的需求。

在一般链接的回程(下载)时,经过主路由NAT后的入口封包的目标IP为客户端的内网IP,直接通过交换机到达客户端,无需再经过旁路由,所以理论上是可以对外网跑满双向千兆的。

0x02 传统旁路由的问题

第一个问题就是IPv6,IPv6没有单独的网关选项,对于SLAAC而言(至今Android只支持SLAAC,不支持DHCPv6),如果一台机器进行了RA(路由宣告),让客户端获得了前缀,那么客户端就会认为其是网关。由于公网IPv6前缀由PPPoE获得,所以必然是主路由进行RA,也就自动成为了所有客户端的IPv6网关,无法再指定旁路由为网关。

一个常规的IPv6 RA包

从另一个角度讲,IPv6要求所有设备(Node)必须从Router和Host这两种角色中二选一,而旁路由就恰恰是一个设备既作为Router,又作为Host。

实际上,IPv6也没必要使用旁路由,由于通常情况下IPv6不使用NAT,路由器在这里做的仅仅是转发而已,我们可以放心的使用IPv6二级路由。

另一个问题是千兆瓶颈的问题,这个千兆瓶颈只对于非直连流量(比如隧道流量)存在,即经过隧道的流量,上行和下行的速度总和无法超过1Gbps,这是因为隧道流量返程也需要经过旁路由。对于直连流量而言,如文章第一节所述,由于返程不需要经过旁路由,所以不存在千兆瓶颈,上下行速度总和可以达到2Gbps,即跑满。不过这个问题通常不会带来影响(啥公网隧道能千兆对等),但若能一并解决了也好。

0x03 本文的魔改二级路由方案

为避免混淆,以下使用「软路由」代指我们原本逻辑中的旁路由(即那台OpenWrt的软路由)

这是一种双网口、IPv4旁路由+IPv6二级路由的方案,这种方案实际上更接近于标准的二级路由,但通过一些魔改,让IPv4变成旁路由模式。

拓扑如下:

图中主路由bridge代表主内网,具有软路由提供的高级功能;bridge_alt代表辅助内网,此处仅用于软路由与主路由间的通信,也可接入一个交换机作为直连/备用内网,其不具有软路由提供的高级功能,但能在软路由故障时继续提供标准(直连)的上网功能。如果主路由上不需要扩展辅助内网,也可不为辅助内网创建bridge,使用一接口代替。

这里只列出了IPv4部分的参数。IPv6部分同标准的IPv6二级路由,但要注意,IPv6的RA和DHCP Server要运行在bridge_alt接口上(见下文)。

如果你的主路由的具有硬件交换机且还有很多未用端口,那便可以省掉“主内网 交换机”,这样旁路由就是通过两根线连接了主路由,但并不会成环。

下面开始IPv4部分的详细配置介绍:

在主路由上,基于路由器模式的出厂设置(如Home AP Dual等),进行以下修改:

  1. 首先新建个Bridge,名称为“bridge_alt”:

2. 添加需要的接口到bridge_alt中,这里我除了必要的有线端口ether1外,还添加了机器自带的两个wlan,作为备用网络热点(主内网的wlan由独立的AP提供):

3. 为bridge设置IP:192.168.10.1/24;为bridge_alt设置IP:192.168.88.1/24

4. 为bridge_alt设置分配192.168.88.0/24的DHCP服务器;如果主内网也由主路由提供DHCP服务,则为bridge设置分配192.168.10.0/24的DHCP服务器,并设置网关为192.168.10.2(下图未展示):

5. 在Interface list中,将bridge_alt设置为LAN

然后将软路由WAN口与bridge_alt的接口通过网线连接(本文中为ether0),然后你应该能看到软路由的WAN口从主路由获取了IP:

(你可能会疑惑:这不是二级路由的状态吗?别急,下面我们就关闭它的NAT)

下面我们在软路由中进行设置(类似的,基于OpenWrt的默认设置)

6. 设置软路由的LAN口IP为192.168.10.2;如果在主路由上设置了主内网的DHCP服务,则要关闭软路由LAN的DHCP服务(下图未展示)

7. 最为关键的一步,到防火墙中关闭WAN区域的“IP动态伪装”,也就是masquerade,即我们常说的NAT:

然后将根据拓扑图,将软路由的LAN主路由的bridge主内网的设备都接到交换机上,IPv4的设置就完成了。

关于IPv6的配置,和标准的IPv6二级路由相似,只是RA和DHCPv6 Server的接口设置有所不同,这部分网上有非常多很好的教程,比如:https://wu.renjie.im/blog/network/ros-dhcpv6/zh-cn/,下面仅写出在本文设置中需要注意的点。

主路由上,IPv6的地址设置(包括了RA)和DHCPv6的设置中,需要在且仅在bridge_alt接口上进行设置,而不应对bridge进行任何设置。换句话说,在IPv6下,主路由不会使用主内网bridgebridge的IPv6 RA和路由完全由软路由负责,bridge作为bridge_alt的下级路由,形成标准的IPv6二级路由。

0x04 后记

本文的方法与普通二级路由的最大区别,其实就是对于IPv4:①在二级路由器(本文中的软路由)上关闭了LAN to WAN的masquerade NAT;②在主路由上连通了二级路由的LAN。从而达到了类似旁路由的效果(旁路由就是为了少一层NAT)。

至于为什么可以在关闭二级路由器的NAT,不妨思考一下我们为什么在路由器上需要NAT:如果我们有一个连接上级网络的普通路由器,并关闭了NAT,那么我们发出的包其实还是可以正常的被送到远端的服务器,但由于包中的源IP地址还是我们客户端的内网IP地址,无法通过我们的内网IP向我们回应(其实通常直接就不会被远端服务器的防火墙接受)。而masquerade NAT就是一种特殊的src nat,其永远都会使用路由器本机地址,作为IP封包源地址的替换,从而让远端服务器的回应包能被正确发到路由器上,再由路由器转发给客户端。

但在本文的方法中,首先在我们的包通过二级路由器直接转发给主路由后,由于主路由是带有NAT的,远端服务器的回应包会正常的到达主路由,然后主路由在转发回应包时,由于我们配置了上面的,回应包可以直接发给客户端,无需经过二级路由器,也就无需二级路由器的NAT,正常的完成了一次往返的通信。

最后,本文的方法更多是整活向的。无论是直接使用单路由,还是普通的二级路由,甚至用传统旁路由方式并直接关闭IPv6,其实也没什么不好(毕竟2022年目前ISP和CDN的优化还是针对IPv4为主,很多地方依然是“关闭IPv6以提升上网体验”)。不过homelab的一大乐趣之一就是折腾各种非标准的方案和配置,本文也算是提出了一种旁路由+正常IPv6的解决方案,如果各位读者认为有改进的地方或漏洞,也欢迎在下面留言。

作者:WuSiYu

学生,Web开发者,智能硬件&IOT爱好者

11条评论

  1. 网关路由分离就分离,网关是网关,而不是什么旁路由,真的很讨厌在技术文章里用伪概念、指代模糊不清的名词

    1. 用词的目的是为了方便表达和他人理解,而不是为了咬文嚼字。OpenWrt和一般网络工程的语境是有所区别的(比如你不会去想在OpenWrt上搞MPLS VPN),在前者的语境下“旁路由”一次在国内用的很普遍,大家也都能理解。
      你要是有更加准确且接受程度更高的用词建议,可以在这里提出。

  2. 半吊子的小白,看的云里雾里。因为旁路由+IPv6网络共存的问题而搜索过来(既想要IPv6,又想解决科学上网时IPv6没经过旁路由而导致无法科学),如果大佬能给一个step by step的文章就好了。我的主路由是padavan,旁路由是openwrt

    1. 文中IPv6是走的标准的二级路由,IPv6没有类似“旁路由”的方案(或者太繁琐、兼容性不佳)。
      本文中的方案整体其实就相当接近普通的二级路由,只是IPv4不做NAT,并且下行不经过软路由(这点与旁路由类似)
      padavan的话我没有设备,文中的方案里主路由需要配置两个IPv4的子网,你需要注意能否支持

  3. 够能整活的 hhh 感觉废了这么大劲来节约 v4 的一个 nat 不太划算啊(我看很多人都说 NAT 的问题,但是也不清楚这玩意儿到底有多耗性能),还不如完全二级路由还能避免非对称路由的潜在问题。

    1. 其实最主要的不是节省一个nat,而是家用环境中通常带宽最大的直连v4下行流量可以直接不经过软路由转发,对于性能一般的软路由设备还是挺实用的,不会成为你宽带速度的拖累。另外去除了软路由的nat可以直接让主路由看到终端设备,如果希望利用主路由上的一些流量管理工具也会更方便

  4. IPV4下不需要这么麻烦。
    直接VRRP就好了。

    openwrt的VRRP设置成最高级,如果openwrt挂了,自动切换到ROS上。

    有些设备不想走openwrt,直接设置默认路由到ROS的IP就好了。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注