2

I´m trying to filter ARP-requests coming from certain IP-addresses in my network. I tried :

table arp filter {
        chain input {
                type filter hook input priority 0; policy drop;
                arp saddr ip 192.168.2.1 counter accept #ISP-Router
                arp saddr ip 192.168.1.100 counter accept #Laptop
                arp operation reply counter accept}}

It should drop all ARP-requests not coming from either the router or the laptop. But requests send by my smartphone are still recieved by my laptop. (My Pi acts as routed access point, it is connected to the ISP-Router via ethernet and uses interface wlan for AP function.)

Then I tried to use table netdev with ingress hook because (at least in theory) it should resolve first:

table netdev wlan {
        chain wlanFilter {
                type filter hook ingress device wlan0 priority 0;
                meta protocol arp counter drop # ARP-requests were still getting from smartphone to laptop, but ARP-Cache on Pi was incomplete afterwards  
                meta pkttype {broadcast, multicast} counter drop # didn´t filter ARP Broadcast}}

I also tried to use the hostapd function ap_isolate=1. Same result.

I use Raspberry Pi OS with kernel version 5.10.17-v7+, hostapd version 2.8-devel, nft version 0.9.6, dnsmasq version 2.80. ip_forward is active and NAT aswell. I wasn´t using a bridge but to be thoroughly: I tried table bridge with similar rules, no success. I then changed the whole setup to bridged access point instead of routed. I tried all rulesets again. Didn´t work either.

Could it be, that Hostapd forwards packets to the local network before packetfilter like Nftables are enforced? Or is there something wrong with my ruleset? Or is it something else altogether?

4
  • Thanks for your reply. I will try it again tomorrow with ap_isolate and try different settings with it. What do you mean with "Forget ARP family?" Isn´t this the exact usecase for this table? Just to be clear: I want to be able to filter ARP while still using the Pi as a routed access point. I tried the different approaches just to check if they would work. Jul 27, 2021 at 20:07
  • 1
    I realize just now you are routing, so I might not have given you correct information sorry (here's the link I put before if you need it: superuser.com/questions/1661060/… , but I'm not sure at all you need it now).
    – A.B
    Jul 27, 2021 at 20:16
  • 1
    The key is ap_isolate, it's just that the feature seems to require support from the driver/firmware of the wireless NIC.
    – Tom Yan
    Jul 28, 2021 at 8:02
  • Yes, ap_isolate should theoretically work. As you said @Tom Yan the problem could be with the BCM43455 chip of the Pi 3 B+. Another user had a similar problem: raspberrypi.org/forums/viewtopic.php?t=175082. I will try again with an USB dongle with a RT5370 chip as soon as I can get a hold of one (I can only get a dongle with RT5372 which was recommended if I would import it and I don´t want to). Jul 28, 2021 at 16:31

1 Answer 1

2

As some in the comments suggested, the key was the option ap_isolate in hostapd.conf. It didn´t work before because of missing support from the driver of the BCM43455 chip which is the built-in NIC of the Raspberry Pi 3 B+. It does work with the RT5370 chip used in some Wifi Dongles. Therefore I used one of those in my setup.

I needed to change some configurations aswell.

First: activate predictable interface names in raspi-config to bind the name to the MAC address. Without it the names for wlan0 (internal card) and wlan1 (external card) would sometimes swap after reboot.

Second: deactivate built-in card with sudo rfkill list -> sudo rfkill block <number of interface of built-in card> to avoid conflicts between the NICs.

Then I followed the answer of user A.B on https://superuser.com/questions/1661060/hostapd-how-to-block-only-netbios-broadcasts-to-clients-in-same-wlan-by-applyin to activate hairpinning.

Now I could create rules to filter local traffic using the bridge family. For example:

table bridge br0 {
        chain forward {
                type filter hook forward priority 0; policy drop;
        }
}

can be used to isolate all clients. Further rules could be used to allow certain communication:

table bridge br0 {
        chain forward {
                type filter hook forward priority 0; policy drop;
                ether type arp accept
        }
}
1
  • 1
    Glad you got it working. Btw, naming the table br0 won't make it affect only br0. You might consider adding expressions with ibrname br0 or obrname br0 or iif wlx.../oif wlx... to restrict the scope (and then ponder the default drop policy) in case you're using multiple bridges on the same system (eg: running LXC. Not talking about Docker which would probably break your setup).
    – A.B
    Aug 2, 2021 at 15:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .