Monday, March 23, 2026

Re: Stateless filtering for established states

> Hello, hoping for some guidance here.
> Trying to build a firewall system on OpenBSD.
>
> It appears that PF has a fundamental design
> problem for high-security environments. When
> you allow creating new states for LAN -> WAN
> traffic, and subsequently need to filter the return
> packets, that is simply impossible.

One option (even if not a good one) is to not create a state when
passing LAN -> WAN. It will make the ruleset at least twice as big and
force you to write all the return rules, aswell as losing the ability
to tie states together and make it possible to exfiltrate data as long
as the traffic originates from port 80,443 on the internal www, but if
you normally would have:

pass in on $ext_if from any to $www port { 80,443 }

you could well make it

pass in on $ext_if from any to $www port { 80,443 } no-state
pass out on $ext_if from $www port {80, 443} to any no-state

and then filter on 1918 IPs before the rule.

> For example: you execute a traceroute and the
> middle hops have RFC1918 IPs. As a general
> rule of thumb, you should filter RFC1918 sources
> from your WAN side. Yet, there is no way to
> acommplish that through PF.

I think that rule of thumb is a bit orthogonal to the design of PF or
firewalling in general. A site, or a customer of an ISP or an
organisation may or may not have a policy to not allow or send RFC1918
(and other non-routable ranges, there are more) but any generic
firewall or router OS will not treat 10.x differently than 9.x or 11.x
networks until you tell it to.
Your rules may treat 10.x differently if you want it so and your own
policies state that you must, but then you (and your FW cpu) have to
do the work to make it happen.

> One workaround I have found is that you can use
> a transit rdomain which is stateless - you can then
> filter per-packet and achieve the desired behavior.
> The caveat: increased CPU usage, less throughput.
> What is the established way to handle this on
> OpenBSD - if there is one at all?

As the previous email reply already stated, your description of the
problem is very vague about what the real issue is.

If your ISP uses RFC1918 inside their network, and you traceroute, the
default position should be for the tools to tell you the truth, which
means that the traceroute reply packets need to retain their RFC1918
source ips so that your traceroute is correctly shown. It would
probably not be terrible if you got a few lines of * * * instead
of 192.168.1.4 and 172.16.5.67 in the middle, but if OpenBSD would
default to stop RFC1918 silently and by default, then it would be very
cumbersome to use OpenBSD as an internal firewall if your internal
network also uses RFC1918, right?

As for sending out RFC1918 to the rest of the world, that is something
every customer endpoint should avoid (for policy reasons) and that is
covered by a simple outgoing source NAT or outgoing block of course,
so that can't really have been what you meant.

--
May the most significant bit of your life be positive.

No comments:

Post a Comment