[Bug 268717] [pf] rdr rules don't work for traffic originating at localhost

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 27 Jan 2023 08:59:35 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=268717

--- Comment #17 from Kristof Provost <kp@freebsd.org> ---
(In reply to dfr from comment #16)
> As far as I understand the code (which is not very well TBH), both nat and rdr rules rely on both PF_IN and PF_OUT events but differ on which event triggers state creation: PF_IN for rdr and PF_OUT for nat with the opposite event matching the other direction to reverse the re-write.

Sort of. I find it more useful to think about when the packets pass through
which parts of the stack. That does imply a direction (i.e. PF_IN/PF_OUT).
In the normal case, when we're thinking of rdr, we'd be dealing with incoming
packets, arriving through ip_input(), triggering a PF_IN pf_test().
For the failing case described here we're dealing with packets that are
generated locally, and the first time they hit the firewall is from ip_output()
(i.e. pf_test(PF_OUT)).

> For connections initiated locally, this symmetry is broken since we generate PF_IN events for the SYN causing the re-write and creating the state but since there is no corresponding PF_OUT for the SYN+ACK reply, the connection fails. This is why I think we need PF_OUT for packets which will be delivered to the local stack rather than routed onward.

For locally generated connections we're only getting the PF_IN after we've
already had a PF_OUT. We can't usefully do anything on SYN+ACK packets, and if
we're trying to add an artificial PF_OUT we're just papering over a problem
that started earlier.

> I thought about whether it makes sense for rdr state creation to happen on PF_OUT but wouldn't that have other problems since the un-redirected destination address may direct the packet to the wrong outgoing interface?

I'm not sure I follow.

> I haven't looked closely at upstream OpenBSD pf but it seems they have changed the rule language considerably which would likely be a problem for FreeBSD unless there is a compability mode. I seem to remember that they support tables for rdr target addresses which may be useful for managing a pool of load-balanced replicas.

Kajetan intends to keep the old syntax supported, at least for a while. I still
need to look at his work in detail, which I don't expect to be able to do
before the end of February.

> I'm looking forward to seeing the right solution for this merged into main (and maybe stable/13).

To be clear, I'm not making any promises about the time and effort I can spend
on this.

-- 
You are receiving this mail because:
You are the assignee for the bug.