This is on a router. I have $mac as the MAC of one client and $set is an ipset of type hash:net. My intention is to deny access to all networks in $set, except for $mac who can access the networks.

-A lan_forward -m mac ! --mac-source $mac -m set --match-set $set dst -j REJECT

But this isn't working. It blocks $set for everyone no matter what the MAC address is. What is the problem? When I turn it into a LOG target I see this:

[ 4128.497456] Blocked website: IN=lanbridge OUT=tun0 MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC= DST=XXX.XXX.XXX.XXX LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=21305 DF PROTO=TCP SPT=40030 DPT=443 WINDOW=64240 RES=0x00 SYN URGP=0

I can confirm with tcpdump that it is rejecting the connection with TCP RST despite having the whitelisted MAC.

EDIT! I found out the problem:

My problem was that I had more than one rule:

-A lan_forward -m mac ! --mac-source $mac1 -m set --match-set $set dst -j REJECT
-A lan_forward -m mac ! --mac-source $mac2 -m set --match-set $set dst -j REJECT
-A lan_forward -m mac ! --mac-source $mac3 -m set --match-set $set dst -j REJECT

So even if the first matched, the second would fail and reject. I almost decided to use MARK but I don't think this is a proper use of packet marking, so instead I just ACCEPT all outgoing from all the MACs, then block all outgoing to the networks specified in the ipset. I just have to remember not to add anything after the ACCEPT rule that I want to apply to any of the MACs I'm filtering.

  • The rule is doing at least three things, maybe break it out into one that allows (or not?) the MAC address, another that does the ipset, then prehaps a custom chain for the TCP/443 handling?
    – thrig
    Aug 2, 2022 at 23:04
  • @thrig I don't really need it to be port 443 (that was just for testing so I'll remove it). I just want it to simply disallow access to $set unless the client has MAC address $mac. Basically I have one system that I want to be able to access some networks and all others I want to be denied. I don't want to "ACCEPT" when set is matched and MAC is matched because then it'll skip subsequent rules. So instead I want it to REJECT when set is matched and MAC is not matched.
    – user536142
    Aug 2, 2022 at 23:05
  • I'm really stupid. I had another rule, nearly identical to that but with a different $mac under it and didn't realize because I was so focused on that rule. So even if it matches the first one and doesn't reject, it'll match the second and reject. Now I just have to find out how to do this most effectively without needing to do "ACCEPT" for the two MACs and then REJECT for all others (because then each packet would have to be checked against the ipset twice).
    – user536142
    Aug 2, 2022 at 23:44

1 Answer 1


One way would be to jump to a new chain to make the accept/reject decision. However, I'm not sure from your description whether the custom MAC address are to be allowed, or blocked, so the logic here may need to be flipped around:

-A lan_forward -m set --match-set $set dst -j a_new_chain
-A a_new_chain -m mac --mac-source $mac -j ACCEPT
-A a_new_chain -j REJECT

This assumes that everything involved is in the set, but that the $mac should be allowed, and everything else rejected.

Another concern may be connection tracking; if open connections must be blocked then the above rules will need to happen before connection tracking is applied, or some external tool be used to kill off existing connections. Otherwise something that can hold a connection open can bypass being added to the ipset table, for any open connections that it already has.

  • alternatively, just RETURN from the chain for the whitelisted MACs (allowing further rules to still reject the packet -- and making it necessary for a further rule to accept it).
    – ilkkachu
    Aug 3, 2022 at 4:22
  • @ilkkachu That's what I used to do but it required I have the separate rules in /etc/firewall.user because this is Openwrt, and I want to keep as much as I can in the fw3 syntax, so I'm limited to not being able to use RETURN or to create custom chains. :(
    – user536142
    Aug 3, 2022 at 20:15

You must log in to answer this question.

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