sha*_*ool 5 networking linux wireless-networking iptables hostapd
我已经通过这个优秀的教程设置了 Raspberry Pi Wi-Fi 热点和hostapd路由:https://thepi.io/how-to-use-your-raspberry-pi-as-a-wireless-access-point/。虽然我跳过了第 8 步,但一切都运行良好,并且我每天都使用它,已经持续了 2 年。在我的情况下,wlan0(集成 Wi-Fi 芯片)被禁用,wlan1(外部 Wi-Fi)被启用。dnsmasqiptables
最近,我注意到来自某些计算机的烦人的流量(NetBIOS 等),我想仅阻止此流量。然而,对我来说非常重要的是:我也希望客户能够相互沟通。很多尝试,不幸的是,我没有成功。
这是我尝试过的:
iptables-> 看到恼人的数据包并表示已被阻止,但仍被 WLAN 上的任何计算机接收
iptables -t raw -I PREROUTING -p tcp --dport 137 -j DROPiptables -t raw -I PREROUTING -p udp --dport 137 -j DROPiptables -t raw -I PREROUTING -p tcp --dport 138 -j DROPiptables -t raw -I PREROUTING -p udp --dport 138 -j DROPiptables -t raw -I PREROUTING -p tcp --dport 139 -j DROPiptables -t raw -I PREROUTING -p udp --dport 139 -j DROPebtables-> 看到恼人的数据包并表示已被阻止,但仍被 WLAN 上的任何计算机接收
ebtables -I INPUT -i wlan1 -p ip --ip-protocol udp --ip-destination-port 137 -j DROPebtables -I INPUT -i wlan1 -p ip --ip-protocol udp --ip-destination-port 138 -j DROPebtables -I INPUT -i wlan1 -p ip --ip-protocol udp --ip-destination-port 139 -j DROPebtables -I FORWARD -i wlan1 -p ip --ip-protocol udp --ip-destination-port 137 -j DROPebtables -I FORWARD -i wlan1 -p ip --ip-protocol udp --ip-destination-port 138 -j DROPebtables -I FORWARD -i wlan1 -p ip --ip-protocol udp --ip-destination-port 139 -j DROPebtables -I OUTPUT -o wlan1 -p ip --ip-protocol udp --ip-destination-port 137 -j DROPebtables -I OUTPUT -o wlan1 -p ip --ip-protocol udp --ip-destination-port 138 -j DROPebtables -I OUTPUT -o wlan1 -p ip --ip-protocol udp --ip-destination-port 139 -j DROPap_isolate=1- hostapd.conf> 烦人的数据包被阻止,但客户端无法相互通信ap_isolate=1中的设置进行过滤-> 客户端无法相互通信
hostapd.confiptables rulesiptables -t filter -A FORWARD -i wlan1 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPTiptables -t filter -A FORWARD -i wlan1 -o wlan1 -j ACCEPTiptables -L -n -v --line-number当我从测试机发送 UDP 广播帧时,计数器会很好地增加。同样的原则ebtables。这让我相信我的规则是好的。
我目前的结论是:iptables(OSI 级别 3)和ebtables(OSI 级别 2)可以查看并阻止流量,但不会在正确的级别上执行操作,因为hostapd(OSI 级别 1)似乎已经将网络数据包广播到 WLAN 上的客户端。
这是我的测试配置的小图:
watch -n 1. +-----------------+
| Device 1 |
((| 172.18.0.240/24 |
+-----------------+
-----------+ +-----------------+
INTERNET |--------| 192.168.0.243 |
-----------+ | RaspberryPi |
| 172.18.0.1/24 |))
+-----------------+
+-----------------+
((| Device 2 |
| 172.18.0.235/24 |
+-----------------+
Run Code Online (Sandbox Code Playgroud)
我希望我已经足够准确地描述了我的情况。如果没有,请向我询问更多详情。
因此,我的问题是:“如何仅阻止向端口 137,138,139 广播 UDP 数据包,但仍允许同一 WLAN 上的客户端相互通信以进行其他所有操作?”
非常感谢您的帮助。
无线 AP 正在处理 LAN:它在第 2 层工作。我将简化并考虑无线帧就像以太网帧(在考虑接入点时这几乎是正确的,即使不是真的:802.11 帧中的四个第 2 层地址标题)。
设置ap_isolate=1可防止在 AP 驱动程序中以低级别桥接帧。相反,这些帧现在被发送到网络堆栈。该堆栈在第 2 层没有太多作用(没有网桥),并将以 IP 数据包(以及 ARP 数据包、IPv6 数据包等)的形式传输发送给主机的帧,由第 3 层的路由堆栈处理。
一旦到达第 3 层的路由,数据包就可以使用主机的 INPUT 规则进行过滤,或者在路由到其他 IP LAN时使用 FORWARD 规则进行过滤。
但在所有情况下,不适合主机的帧都会被丢弃,而不是发送到其他 STA:STA 之间没有通信,这是iptables(错误的层)或ebtables(没有可用的网桥)ap_isolate=1无法过滤的角色之一。
为了能够使用ebtables(以太网桥帧表管理)处理和过滤帧,需要一个桥接器,即使该桥接器的唯一成员是单个无线卡wlan1。
因此,这里是执行此操作的步骤。这些步骤尚未完成。它们必须集成到操作系统的配置中才能正确启动设置,并且必须调整一些内容,主要是因为 IP 设置从 wlan1接口移至br0接口(例如:DCHP 服务器接口、其他iptables规则等) 。
创建一个桥(您必须将其集成到操作系统设置中):
ip link add br0 up type bridge
Run Code Online (Sandbox Code Playgroud)
将 IPv4 配置从 移至wlan1至br0(同上集成/启动)。wlan1不得接收任何 IPv4 地址:172.18.0.1/24 现在应该仅位于上br0。(如果使用此功能,wlan1sysctl -w net.ipv6.conf.wlan1.disable_ipv6=1也不应该再参与 IPv6 :)。在重新启动hostapd之前,无线连接将会丢失。
ip address flush dev wlan1
ip address add 172.18.0.1/24 dev br0
Run Code Online (Sandbox Code Playgroud)
wlan1调整引用现在参考的任何相关配置br0(例如:DHCP 服务器的接口(如果明确定义),也许还有一些iptables规则)。
中/etc/hostapd/hostapd.conf,除ap_isolate=1和 外还interface=wlan1添加:
bridge=br0
Run Code Online (Sandbox Code Playgroud)
并重新启动hostapd。您现在应该得到与此类似的内容:
# bridge link show dev wlan1
3: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 100
Run Code Online (Sandbox Code Playgroud)
在wlan1网桥端口上启用发夹以撤消 的影响。这是处理OP问题的这一部分所必需的:ap_isolate=1
但客户端之间无法通信
用这个命令:
bridge link set dev wlan1 hairpin on
Run Code Online (Sandbox Code Playgroud)
在wlan1桥接端口上收到的帧现在将回显到同一桥接端口。这里的桥接端口和相关媒体是wlan1接口及其无线电波。
客户端通信现已恢复。而不是像以前那样:
STA1 --> AP --> STA2
Run Code Online (Sandbox Code Playgroud)
它现在正在做:
STA1 --> AP --> (wlan1)--br0--(wlan1) --> AP --> STA2
Run Code Online (Sandbox Code Playgroud)
现在可以在网桥级别添加适当的防火墙规则。
如果系统上有多个桥,还应该使用--logical-in/ --logical-out,否则不需要。同样,我没有包含下面的-i wlan1/-o wlan1因此它可以在任何桥接端口上工作(因此包括 的单个桥接端口wlan1)br0。选择您喜欢的。
阻止端口 137 的示例:每行分别。阻止从 STA 到 AP(还包括阻止路由到eth0)、从 STA 到 STA 以及从 AP 到 STA(还包括从eth0路由的情况)。
ebtables -A INPUT --logical-in br0 -p ip --ip-protocol udp --ip-destination-port 137 -j DROP
ebtables -A FORWARD --logical-in br0 -p ip --ip-protocol udp --ip-destination-port 137 -j DROP
ebtables -A OUTPUT --logical-out br0 -p ip --ip-protocol udp --ip-destination-port 137 -j DROP
Run Code Online (Sandbox Code Playgroud)
如标题所示,要仅阻止端口 137 的广播而不阻止单播,可以使用以下规则。可能有不止一种方法可以做到这一点(这里我使用的是 LAN 中携带 IPv4 目标广播地址的帧具有以太网目标广播地址 (ff:ff:ff:ff:ff:ff) 的事实) 。仅显示 FORWARD 情况:
ebtables -A FORWARD --logical-in br0 -d Broadcast -p ip --ip-protocol udp --ip-destination-port 137 -j DROP
Run Code Online (Sandbox Code Playgroud)
笔记:
通过加载设置的内核模块br_netfilternet.bridge.bridge-nf-call-iptables=1,还可以使用iptables(甚至nftables)代替或附加ebtables来过滤IPv4 类型的帧(为了iptables的利益而暂时转换为 IPv4数据包)遍历桥接路径(在以及 IPv4 路由路径)。描述如下:基于 Linux 的桥上的 ebtables/iptables 交互。对于那些没有准备好处理这可能导致的细微损坏的人来说,这可能会非常令人困惑,所以我不建议使用它。
nftables还可以处理过滤,并且最近的版本在这方面具有更好的功能(例如,从内核 5.3 开始,它在桥接路径中获得本机conntrack支持,而不依赖于br_netfilter)。