在我的家庭网络 (10.0.0.0/24) 中,我想部署一台网络打印机,而无需从交换机到它铺设电缆。因此,我使用了 Raspberry Pi,它通过 Wifi 连接到我的无线网络,并将其以太网端口与打印机连接起来。目标是在这里拥有类似 Wifi-以太网桥的东西...
RPi Ethernet IP (eth0): 10.0.0.32
RPi Wifi IP (wlan0): 10.0.0.31
Printer IP: 10.0.0.30
在玩了 tcpdump 之后,我发现,RPi 正在响应来自路由器 (10.0.0.1) 的 ARP 请求,只有当我
net.ipv4.ip_forward = 1
net.ipv4.conf.all.proxy_arp = 1
已启用。我可以通过阅读手册页来理解什么。我使用从路由器到打印机 IP 的简单 ping 来测试这一点。
现在,当我删除路由器上的 ARP 缓存而没有在 RPi 上打开 tcpdump 时,ARP 响应不知何故停止工作。所以我想知道为什么当我在 Pi 上启动 tcpdump 时它又开始工作了。原来,tcpdump 将 Raspberry Pi 的 WiFi 接口置于混杂模式。为了正常工作,我将 Pi 的 WiFi 接口置于永久混杂模式
ip link set wlan0 promisc on
现在一切都运行良好,但是因为我觉得这个解决方案“有异味”,所以我想知道这里发生了什么,以及为什么 proxy_arp 不够用?
此外,由于我这里有两个网络接口,在同一个子网上工作,我通过一些路由策略确保只有到打印机的流量通过 eth0 路由。
localhost ~ # ip rule show
0: from all lookup local
32764: not from all to 10.0.0.30 lookup main
32765: from all to 10.0.0.30 lookup print
32766: from all lookup main
32767: from all lookup default
localhost ~ # ip route show table print
10.0.0.30 dev eth0 scope link
答案1
从根本上来说,有两种方法可以完成您要做的事情:路由和桥接。
这两种方法都不使用proxy_arp
。proxy_arp
如果您的网络的某些部分认为您正在路由,而其他部分认为您正在桥接,您可以使用这种方法。这是您排除所有其他选项后才可以使用的最后手段。
我的建议是,在诉诸路由和桥接解决方案之前,您需要充分了解它们,并了解为什么它们都不适合您proxy_arp
。
您的使用案例听起来不像proxy_arp
是必要的案例之一。
解决桥接问题
WiFi 在堆栈的两层使用 MAC 地址。您将拥有一对用于端点的 MAC 地址,就像在有线以太网中一样。您将拥有一对指示无线链路端点的 MAC 地址。
不幸的是,原始 WiFi 标准假设这四个 MAC 地址中的一对特定地址始终相同,而这种假设在桥接时并不正确。因此,引入了名为 WDS 的新标准来解决这个问题。
因此,为了配置桥接,您需要确保 WiFi 连接两端的硬件都支持 WDS 并已启用它。接下来,您需要恢复sysctl
所做的这两项更改,因为它们不用于桥接。
最后,您需要在 Pi 上配置一个桥接器,将有线和无线接口合并为一个桥接器。如果您希望 Pi 也能使用 IP,请在桥接接口上进行配置,而不是在底层物理接口上进行配置。
这是需要配置的一大堆事情,并且存在硬件不支持 WDS 的风险。
解决路由问题
如果您想要进行路由,您仍需要恢复proxy_arp
设置。net.ipv4.ip_forward = 1
但该设置对于路由设置来说是正确的。
在 Pi 上,您需要为两个网络接口配置不同的前缀。您已配置的无线设备10.0.0.0/24
可以保留原样,因为该部分已在运行。
但是,您需要为有线接口配置另一个前缀。一个可能的选择是10.0.1.0/24
。您可以将其分配10.0.1.1
给 Pi 上的有线接口。
打印机可以配置为静态 IP 地址,10.0.1.2
或者您可以让它动态配置,这需要您在 Pi 上安装 DHCP 服务器,该服务器会分发前缀中的地址10.0.1.1
。
最后,您需要通过添加路由表条目来告知现有路由器有关这个新网络的信息。在现有路由器的配置中,为前缀10.0.1.0/24
(也可以写为10.0.1.0/255.255.255.0
)添加路由表条目,网关地址为10.0.0.31
。您需要确保该地址10.0.0.31
以某种方式保持静态,否则您的路由表条目将变得不正确。