On Tue, May 26, 2020 at 09:26:07PM +0200, Sven M. Hallberg wrote:
> hi all,
>
> i sent the following question to misc@ on march 29th but received no
> response. i hope you don't mind me retrying on tech@.
>
> while playing around with pf, i noticed that some connections that i
> thought should be blocked, were in fact not. here is my fairly standard
> bridge setup between a wlan interface and a wired ethernet.
>
> # cat /etc/hostname.em0
> group lan
> up
>
> # cat /etc/hostname.athn0
> mediaopt hostap
> nwid xxx wpakey abcd1234
> group lan
> up
>
> # cat /etc/hostname.vether0
> group lan
> inet 192.168.22.145/28
>
> # cat /etc/hostname.bridge0
> add em0 add athn0 add vether0
> blocknonip athn0
> up
>
> i then set up pf rules that should let the (w)lan interfaces talk to
> the world.
>
> # cat /etc/pf.conf
> set skip on lo
> block return
> pass out # ingress filter
> pass in on lan from lan:network to any
>
> now this all works as intended. but, when i remove athn0 from the lan
> group, i would expect the above ruleset to block any incoming
> connections from the wlan.
>
> # ifconfig athn0 -group lan
Did you flush states between your tests (pfctl -F states) ? -> After you
removed athn0 from lan group ?
>
> and indeed, i could not ping a wired host from the wlan. however, i
> could still access the router (192.168.22.145) itself from the wireless.
> as far as i can tell, this is due to the following code in if_bridge.c,
> bridge_process() -- comments by me:
>
> if (bridge_ourether(bif0->ifp, eh->ether_dhost)) {
> /* addressed to the iface it came in on */
> bif = bif0;
> } else {
> SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
> if (bif->ifp == ifp)
> continue;
> if (bridge_ourether(bif->ifp, eh->ether_dhost))
> /* addressed to some other bridge member */
> break;
> }
> }
> if (bif != NULL) {
> /* ... */
> if (bridge_filterrule(&bif0->bif_brlin, eh, m) ==
> BRL_ACTION_BLOCK) {
> goto bad;
> }
> /* ... */
> }
>
> a packet that comes in on a member of a bridge and is addressed to _any_
> bridge member interface, is processed as input to (only) the destination
> interface. if that destination interface differs from the one that the
> packet actually came in on, pf rules for the actual input interface are
> not evaluated.
>
> this seems to contradict the following statement in the NOTES section of
> bridge(4) -- in any case, it certainly contradicted my intuition:
>
> Bridged packets pass through pf(4) filters once as input on the receiving
> interface and once as output on all interfaces on which they are
> forwarded. In order to pass through the bridge packets must pass any in
> rules on the input and any out rules on the output interface. Packets
> may be blocked either entering or leaving the bridge.
>
> now, to be clear, i don't mind that the packet passes through 'in' rules for
> vether0 in my example, but i wonder if it should not also pass through
> the 'in' rules for 'athn0'.
>
> i would appreciate enlightenment on this. note that (contrary to misc) i
> am subscribed to tech@, so no cc needed.
>
>
> thanks,
> pesco
>
> PS: at the time, i was using OpenBSD 6.6, but the code in question
> appears unchanged in current.
>