[WIP] Debian软路由的L3桥接探索与部署记录

目标环境

  • 使用DHCP进行v4地址下发
  • 使用SLAAC/DHCPv6自动配置v6
  • 目标网段有潜在的基于MAC地址的访问控制
  • DHCP/SLAAC可以不受访问控制限制运作

目标效果

使用本L3桥接作为网关设备,架于上游网段与下游之间,使得下游所有终端:

  • 无感进行DHCP与SLAAC,获得上游网络网段配置,而无需进行NAT
  • 数据流量遵从访问控制,以网关身份发出

预研

ipv4 forward

L3软路由需要在上行和下行两个端口都启用内核IPv4包转发:

/proc/sys/net/ipv4/conf/xxx/forwarding: Enable IP forwarding on this interface. This controls whether packets received on this interface can be forwarded.

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

避免使用 /proc/sys/net/ipv4/ip_forward.

注:实际还需fw配置限制才可视为安全。避免全局转发的意义不是特别大

ipv6 forwarding

看起来不推荐逐interface进行配置。没找到详细的说明。但是不影响进行逐interface配置,实际上没有区别。

在上行和下行都启用 /proc/sys/net/ipv6/conf/xxx/forwarding

这样会导致上行端口v6自动配置被禁用(实测运行时没有…?可能是autoconf为1的原因,文档没写)。重新使能 echo 2 | sudo tee /proc/sys/net/ipv6/conf/xxx/accept_ra

还会导致NA中IsRouter位使能,个人认为不应当在上行端口使能该位,因为该端口并不提供对所在子网的路由功能(做L3桥接时更希望这个上游端口表现为普通host,但是拿了很多ip地址),解决办法暂无。应该不影响运作,只要不响应其它RS/RA。

proxy_arp & ndp_proxy

都需要在上下游端口分别启用,除此之外还需要配置好静态路由表,内核才会根据路由表进行proxy。了解到的常用思路是,根据arp或ndp cache,去更新路由表即可。但该方法无法动态响应网络拓扑变化,轮询效率低,所以可能无法利用内核满足需求,需要用户态daemon服务监听ND/ARP包去管理路由表:

ndppd:还支持转发rs/ra,但是不会自动修改路由表,比较容易增加支持

parprouted:v4的成熟解,动态arp转发+路由增删,但是不支持policy routing,但是很容易增加支持。

实际实现时可以利用policy routing,专门拉一个路由表给proxy,便于维护与删除条目,不与系统默认路由表产生冲突。rule就可以简单的根据source interface进行区分。

v4和v6的DAD都是借助于ARP/ND实现,所以无需特殊处理

dhcp & dhcpv6 relay

isc dhcrelay处理v6应该没有问题,但是它要求必须指定v4的dhcp上游地址,没有理解原因。

dhcp-helper:支持广播上游,下游没有使用bpf而是直接监听dhcp端口。Linux only。不支持DHCPv6。

rs/ra relay

as solved by ndppd already

其它广播协议
  • mDNS:暂不实现,无需求

PoC

0x1 静态IP测试ARP/ND与路由转发

测试环境:

  • 一台笔记本电脑,我的开发机,我在本机进行各种操作
  • 一台x86工控机,有两个板载网口,当作软路由
  • 一台树莓派,作为软路由后的子网设备。
  • 一台L2交换机,接软路由下行、树莓派网口、我的笔记本电脑有线

树莓派网口配双别名,一个使用标准dhcp+slaac自动配置,一个静态v4(10.40.160.10),和工控下行口放在一个网段,方便ssh连接

工控机下行口配置IPv4静态地址(10.40.160.1),作为回退的管理地址。我的笔记本有线口也配置成相同静态网段(10.40.160.100),访问工控机。

工控机上游口使用dhcp+slaac自动配置,使其也成为上游网络的一部分(理论无需如此,但是这样配置可以方便连接至软路由,当整个网络环境运作之后)。

多增加的这个树莓派,原因是,我的笔记本无线和工控机上行端口在一个局域网里,如果再把下行也接到笔记本有线,之后笔记本上的路由情况就很麻烦。所以单独提了个树莓派验证。

吐槽一下rpios,怎么转用NetworkManager了…当自己是Desktop Grade是吧(

工控机上行口为eno1,下行口为br-downstream预先配置成了网桥(但是暂时没用)。树莓派有线口为eth0

所有测试配置都会在重启后失效

IPv4

  1. ssh登录到工控机
  2. 启用ip forward:
    echo 1 | sudo tee /proc/sys/net/ipv4/conf/eno1/forwarding
    echo 1 | sudo tee /proc/sys/net/ipv4/conf/enp1s0/forwarding
  3. 安装parprouted:sudo apt-get install parprouted
  4. 运行parprouted:sudo parprouted -d eno1 br-downstream
  5. 查看工控机路由表:ip r
    发现10.40.160.100/32这些地址已经被增加了路由表条目。但这个没什么用
  6. 在树莓派上增加一个上游网段的IP(现在只有一个10.40.160.10这个静态地址):sudo ip addr add 192.168.198.72/24 dev eth0
  7. 查看树莓派上的路由,发现对应lan的路由已自动增加
  8. 尝试从笔记本arping树莓派:arping 192.168.198.72:反馈的mac是工控机上行口的
  9. 尝试从树莓派arping笔记本,反馈的mac有工控机下行口的,但是怎么还有我笔记本有线口的…?怪,笔记本有线口响应了请求笔记本wifi上的IP的arp…
  10. 尝试两边互相ping,没通。

树莓派debug:

  1. 在树莓派上开tcpdump,并转发到我笔记本电脑的wireshark:笔记本上nc -lp 2345 | wireshark -k -S -i -,树莓派上tcpdump -s 0 -U -n -w - -i eth0 | nc 10.40.160.100 2345,wireshark使用icmp作为过滤器
  2. 从笔记本ping树莓派
  3. 树莓派成功抓到了ping,并pong了回去。查看包的目标ip和mac,也都是正常的,ip是笔记本ip,mac是工控机下行口

工控机下行口debug

  1. 在工控机上开tcpdump,如法炮制,但是监听下行口
  2. 也成功抓到了完成正确的ping

工控机上行口debug

  1. 在工控机上行口继续
  2. 这回只抓到了ping没有pong。所以是工控机没有转发icmp。

额外测试一下tcp和udp工作不:也不

结论是工控机forward没有工作。

检查工控机fordwarding设置。下行口怎么是0啊,恼。(啊我纸张了。之前启用ip forward的时候,下行端口填的是物理端口,而我实际用的是虚拟的网桥口)

设置成1,重新ping,通了。首ping延迟很高,百余毫秒,是工控机arp转发带来的。

测测iperf3:双向都只有300M多点。鉴于现在流量是笔记本走无线到路由器,再走有线到工控机,再到树莓派,瓶颈一定是在wifi上。看工控机cpu占用,一个核心吃了大概1/3,也就可能刚刚好跑千兆。不知道内核有没有并行加速。

以及parprouted的请求队列好像蛮短的,延迟还不低,可能队列长度也需要tunning一下

20231019,今天就到这里了。下回先把parprouted改造成支持policy routing的样子再继续

部署