使用 ARP 代理和 promisc 模式进行桥接

使用 ARP 代理和 promisc 模式进行桥接

编辑:我发现这是重复的为什么只有当网络适配器处于混杂模式时才会有 ARP 响应?


我使用带有 Rasbian Stretch 的 Raspberry Pi 3B+,并按照 Debian 的教程使用代理 arp 设置它:使用代理 ARP 桥接网络连接将 eth0“桥接”到 wlan0。据此,很容易设置代理 arp:

rpi3 ~# echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
rpi3 ~# echo 1 > /proc/sys/net/ipv4/ip_forward
rpi3 ~# ip route add 192.168.10.60/32 dev eth0

192.168.10.60是 eth0 上的客户端,应该“桥接”到 wlan0。

但这不起作用。我必须在 wlan0 上启用混杂模式才能使其正常工作,但找不到任何提示来执行此操作。

rpi3 ~# ip link set wlan0 promisc on

是否需要混杂模式Stretch?如果不是,我该如何避免呢?

更新:
检查了一下rp_filter设置为0。
hostapd没有安装。wlan0处于客户端模式并由 管理wpa_supplicant

答案1

显然,不可能在客户端模式下的无线和以太网之间桥接以太网帧。例如,它不会工作。

此外,作为客户端,要小心不要将来自其他来源的帧注入 AP 基础设施。

大多数接入点 (AP) 将拒绝源地址未通过 AP 进行身份验证的帧。

答案2

这似乎只是 Raspberry Pi 的 wifi 上的问题。还有一个重复的问题为什么只有当网络适配器处于混杂模式时才会有 ARP 响应?使用树莓派。在任何教程的其他地方都找不到启用代理 arp 混杂模式的注释。我已经在我的笔记本电脑上验证了它,其中代理 arp 可以在没有混杂模式的情况下工作。

我认为这个问题只能由 RASPBERRY PI FOUNDATION 和/或其闭源驱动程序制造商解决。在那之前我们必须忍受它。

答案3

使用 ARP 代理和 promisc 模式进行桥接

可以“桥接”从 WiFi 到 LAN 的连接(例如,在带有 microUSB-LAN 适配器的 Raspberry Pi Zero W 上),所有设备都位于同一子网(IP范围)使用ARP代理混杂模式

方案:
[路由器] <---WiFi---> [RasPi wlan0 <---bridge---> eth0] <---LAN 电缆---> [有线设备,例如计算机]

提示:提供的解决方案基于这些优秀的资源
来源#1作者:帕斯卡·盖泽
来源#2通过威尔·哈利

这些示例中使用的硬件/操作系统:
带有 microUSB 至 LAN 适配器的 Raspberry Pi Zero W
Raspbian Stretch Lite (2019-04-08) + 更新




解决方案 #1 - 通过接口进行 ARP 代理(手动配置)

注意:这取决于您的 WiFi 路由器是否支持“IP Layer 3 解决方案”(网络层)

1)假设 Raspberry Pi 与路由器的 WiFi 连接已设置并连接

2)安装包

$ sudo apt-get install parprouted dhcp-helper

3)编辑并添加以下行:

假设

  • 无线局域网0是树莓派内置WiFi卡的ID
  • 以太网0是有线以太网卡(microUSB-LAN 适配器)的 ID
$ sudo nano /etc/network/interfaces
# Clone the dhcp-allocated IP to eth0 so dhcp-helper will relay for the correct subnet
auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
  wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
  pre-up /sbin/ip link set wlan0 promisc on
  post-down /sbin/ip link set wlan0 promisc off
  post-up /usr/sbin/parprouted eth0 wlan0
  post-down /usr/bin/killall /usr/sbin/parprouted
  post-up /etc/init.d/dhcp-helper restart
  pre-up /sbin/ifup eth0
  post-up /sbin/ip addr add $(/sbin/ip -4 -br addr show wlan0 | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev eth0
  pre-down /sbin/ip addr del $(/sbin/ip -4 -br addr show wlan0 | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev eth0
  post-down /sbin/ifdown eth0

# Set ethernet interface to "manual" mode
auto eth0
allow-hotplug eth0
iface eth0 inet manual

4)启用数据包转发:

$ sudo nano /etc/sysctl.conf
# Find and uncomment this line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1
# to -->
net.ipv4.ip_forward=1

5)配置 DHCP 中继

DHCP 帮助程序将捕获请求并将它们转发到“真实”DHCP 服务器:

$ sudo nano /etc/default/dhcp-helper
# Change eth0 by the name of your wireless interface (e.g. wlan0)
#DHCPHELPER_OPTS="-b eth0"
# to -->
DHCPHELPER_OPTS="-b wlan0"

6)配置 AVAHI

启用“反射器模式”将允许客户端浏览连接到网桥的所有服务:

$ sudo nano /etc/avahi/avahi-daemon.conf
# Find and change the following line
#enable-reflector=no
# to -->
enable-reflector=yes

7)重启 RasPi

重启后,通过 eth0 / LAN 连接的设备应该可以访问 WiFi 路由器的同一网络。
注意:工作解决方案取决于您的 WiFi 路由器是否支持“IP 第 3 层解决方案”(网络层)

$ sudo reboot



解决方案 #2 - 通过 SERVICES 的 ARP 代理(自动脚本解决方案)

注意:这取决于您的 WiFi 路由器是否支持“IP Layer 3 解决方案”(网络层)

1)使用以下内容创建 bash 脚本:

$ sudo nano bridge.sh
#!/usr/bin/env bash

set -e

[ $EUID -ne 0 ] && echo "run as root" >&2 && exit 1

##########################################################
# You should not need to update anything below this line #
##########################################################

# Credits to Will Haley
# Mainly based on source: https://willhaley.com/blog/raspberry-pi-wifi-ethernet-bridge/#option-1---same-subnet
# Edited on line #52 by Tomtom: path to systemd for parprouted.service

# parprouted  - Proxy ARP IP bridging daemon
# dhcp-helper - DHCP/BOOTP relay agent

apt update && apt install -y parprouted dhcp-helper

systemctl stop dhcp-helper
systemctl enable dhcp-helper

# Enable ipv4 forwarding.
sed -i'' s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/ /etc/sysctl.conf

# Service configuration for standard WiFi connection. Connectivity will
# be lost if the username and password are incorrect.
systemctl restart wpa_supplicant.service

# Enable IP forwarding for wlan0 if it's not already enabled.
grep '^option ip-forwarding 1$' /etc/dhcpcd.conf || printf "option ip-forwarding 1\n" >> /etc/dhcpcd.conf

# Disable dhcpcd control of eth0.
grep '^denyinterfaces eth0$' /etc/dhcpcd.conf || printf "denyinterfaces eth0\n" >> /etc/dhcpcd.conf

# Configure dhcp-helper.
cat > /etc/default/dhcp-helper <<EOF
DHCPHELPER_OPTS="-b wlan0"
EOF

# Enable avahi reflector if it's not already enabled.
sed -i'' 's/#enable-reflector=no/enable-reflector=yes/' /etc/avahi/avahi-daemon.conf
grep '^enable-reflector=yes$' /etc/avahi/avahi-daemon.conf || {
  printf "something went wrong...\n\n"
  printf "Manually set 'enable-reflector=yes in /etc/avahi/avahi-daemon.conf'\n"
}

# I have to admit, I do not understand ARP and IP forwarding enough to explain
# exactly what is happening here. I am building off the work of others. In short
# this is a service to forward traffic from WiFi to Ethernet.
#cat <<'EOF' >/usr/lib/systemd/system/parprouted.service
cat <<'EOF' >/etc/systemd/system/parprouted.service
[Unit]
Description=proxy arp routing service
Documentation=https://raspberrypi.stackexchange.com/q/88954/79866
Requires=sys-subsystem-net-devices-wlan0.device dhcpcd.service
After=sys-subsystem-net-devices-wlan0.device dhcpcd.service

[Service]
Type=forking
# Restart until wlan0 gained carrier
Restart=on-failure
RestartSec=5
TimeoutStartSec=30
# clone the dhcp-allocated IP to eth0 so dhcp-helper will relay for the correct subnet
ExecStartPre=/bin/bash -c '/sbin/ip addr add $(/sbin/ip -4 -br addr show wlan0 | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev eth0'
ExecStartPre=/sbin/ip link set dev eth0 up
ExecStartPre=/sbin/ip link set wlan0 promisc on
ExecStart=-/usr/sbin/parprouted eth0 wlan0
ExecStopPost=/sbin/ip link set wlan0 promisc off
ExecStopPost=/sbin/ip link set dev eth0 down
ExecStopPost=/bin/bash -c '/sbin/ip addr del $(/sbin/ip -4 -br addr show wlan0 | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+")/32 dev eth0'

[Install]
WantedBy=wpa_supplicant.service
EOF

systemctl daemon-reload
systemctl enable parprouted
systemctl start parprouted dhcp-helper

2)执行 bash 脚本(检查输出是否有错误):

$ sudo bash bridge.sh

3)重新启动 RasPi

通过 eth0 / LAN 连接的设备重新启动后应该可以访问 WiFi 路由器的同一网络。注意:这取决于您的 WiFi 路由器是否支持“IP Layer 3 解决方案”

$ sudo reboot



一般注意事项:

  • ARP代理需要支持通过 WiFi 路由器实现“IP 第 3 层/网络层”功能(我猜您只需尝试一下即可找到)。
  • 通过 WDS 的首选解决方案(此处未讨论该主题),用于在同一子网上提供桥接解决方案,需要 WiFi 芯片支持 WDSWiFi路由器。您可以检查 Raspberry Pi 的 WiFi 芯片是否支持 WDS
$ iw list

在部分支持的接口模式

Wiphy phy0
...
    Supported interface modes:
         * IBSS
         * managed
         * AP
         * AP/VLAN
         * WDS
         * monitor
         * mesh point
...

如果无线数据传输系统没有明确列出这里,那么WDS就是不支持通过 WiFi 芯片(Raspberry Pi Zero W 不支持 WDS)。

相关内容