Page MenuHomeFreeBSD

pf: don't route broadcast or multicast traffic
Needs ReviewPublic

Authored by rcm on Tue, Apr 21, 5:40 PM.

Details

Reviewers
kp
Group Reviewers
network
Summary

pf_route() and pf_route6() forward broadcast and multicast traffic
when a route-to rule matches, without any check against the output
interface's broadcast domain. Apply the classification idiom used
elsewhere in the stack (M_BCAST/M_MCAST flags, IN_MULTICAST,
in_ifnet_broadcast, etc.) to guard against such leaks.

Sponsored by: Rubicon Communications, LLC ("Netgate")

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

rcm requested review of this revision.Tue, Apr 21, 5:40 PM

I always assumed "policy routing" by packet filters a tool that allows to shoot into ones leg. I can imagine some weird scenarios where people would use pf to actually inject packets where it won't be routed by the normal stack.

I always assumed "policy routing" by packet filters a tool that allows to shoot into ones leg. I can imagine some weird scenarios where people would use pf to actually inject packets where it won't be routed by the normal stack.

That's fair. Though, currently, an operator who uses pf route-to without realizing it can emit L2 broadcasts across broadcast domains is foot-shooting themselves unknowingly. :)

In D56559#1294664, @rcm wrote:

I always assumed "policy routing" by packet filters a tool that allows to shoot into ones leg. I can imagine some weird scenarios where people would use pf to actually inject packets where it won't be routed by the normal stack.

That's fair. Though, currently, an operator who uses pf route-to without realizing it can emit L2 broadcasts across broadcast domains is foot-shooting themselves unknowingly. :)

We do not prevent a superuser from foot-shooting and we do not assume that superuser is stupid. A warning should be enough.

In D56559#1294664, @rcm wrote:

I always assumed "policy routing" by packet filters a tool that allows to shoot into ones leg. I can imagine some weird scenarios where people would use pf to actually inject packets where it won't be routed by the normal stack.

That's fair. Though, currently, an operator who uses pf route-to without realizing it can emit L2 broadcasts across broadcast domains is foot-shooting themselves unknowingly. :)

We do not prevent a superuser from foot-shooting and we do not assume that superuser is stupid. A warning should be enough.

Another potential solution to this that came up in discussion with @kp was using block out quick rule(s) to plug up any problematic leaks.

So I think the question is really: are we okay with pf_route
forwarding broadcasts when ip_forward (nominally) doesn't? If yes, then I do agree at least a few lines in the man page be introduced that calls out this difference, and maybe prescribes example rules that can be used to plug any undesirable leaks.

lytboris_gmail.com added inline comments.
sys/netpfil/pf/pf.c
9810

To cope with concerns mentioned by @glebius I'd put here a deprecated-upon-creation sysctl to revert packet processing to the previous behavior. This sysctl should be set to "drop, not forward" value by default.

10170

Same as above

There are good arguments for both blocking and allowing this I believe.
I'm not entirely sure where I fall. On the one hand, yes, users should be allowed to shoot themselves in the foot if they really want to, but on the other hand, it's non-obvious that this will happen. There are going to be a lot more users in the "I didn't want this to happen but it did" camp than there'd be in the "I want to do this dumb thing and pf won't let me." camp.

I do also see test failures in sys/netpfil/pf/pfsync:rt_af, sys/netpfil/pf/src_track:sn_types_compat and sys/netpfil/pf/src_track:sn_types_pass with this patch. I've not debugged these, but this change does appear to be responsible.

sys/netpfil/pf/pf.c
9810

I really wouldn't do that. We'd be making this already very complex and error-prone code even more complex.

In D56559#1295079, @kp wrote:

I do also see test failures in sys/netpfil/pf/pfsync:rt_af, sys/netpfil/pf/src_track:sn_types_compat and sys/netpfil/pf/src_track:sn_types_pass with this patch. I've not debugged these, but this change does appear to be responsible.

I initially hit a failure in pfsync:rt_af but after rebuilding and trying again, I am no longer hitting that failure (or failures in src_track:*):

pfsync:rt_af  ->  passed  [7.679s]
route_to:bcast_baseline  ->  passed  [4.693s]
route_to:bcast_directed  ->  passed  [1.755s]
route_to:bcast_limited  ->  passed  [2.479s]
src_track:sn_types_compat  ->  passed  [4.351s]
src_track:sn_types_pass  ->  passed  [3.050s]

Weird.

In D56559#1294810, @rcm wrote:

So I think the question is really: are we okay with pf_route
forwarding broadcasts when ip_forward (nominally) doesn't? If yes, then I do agree at least a few lines in the man page be introduced that calls out this difference, and maybe prescribes example rules that can be used to plug any undesirable leaks.

I think we are okay. Packet filters are really designed to make network stacks to malfunction.

A good documentation change would be better than a policy.

In D56559#1294810, @rcm wrote:

So I think the question is really: are we okay with pf_route
forwarding broadcasts when ip_forward (nominally) doesn't? If yes, then I do agree at least a few lines in the man page be introduced that calls out this difference, and maybe prescribes example rules that can be used to plug any undesirable leaks.

I think we are okay. Packet filters are really designed to make network stacks to malfunction.

A good documentation change would be better than a policy.

That's fine by me. I will pivot to an addition to pf.conf(5) and tweak the test cases here in the original patch to instead use rules to plug the leaks.