On 2023-06-24, Stephan Neuhaus <s...@artdecode.de> wrote: > Hi Zack > > On 6/24/23 03:39, Zack Newman wrote: >> There do appear to be contradictions in documentation as well as the pf >> book. The Configuring NAT section is correct as you have seen with your >> own rules. > > I'm not sure about the Configuring NAT section being > correct. I still maintain that the documentation and > observed behaviour are different.
The pf.conf(5) manual page is the best documentation for PF and that is expected to be correct. The pf faq could well be wrong, it's not really had a full review/update/rewrite since before nat-to was introduced - a relatively light conversion to the "new" syntax and mostly smaller changes - no integration of new features in the existing text e.g. the very useful tag/tagged is relegated to an added on "advanced features" section). > I now have the following small ruleset. The rules for > ports 22 and 53 are just so that I can do my > experiments over ssh. (Port 53 may not be necessary > but the blocked packets mess up my logs.) The em0 You can always follow a general "block log" with a "block on port XX" if you want to log most blocked psckets except for certain ones. > interface has the IPv4 address 192.168.0.2. > > set skip on lo > > block log all > > pass in on em0 proto tcp to any port 22 > pass out on em0 proto tcp from any port 22 > pass on em0 proto udp from any port 53 > pass on em0 proto udp to any port 53 This allows someone on the internet to bypass your filter rules and send UDP traffic to any port by simply setting the source port to 53. Just have "to port 53", reply ("from port 53") packets will match the state created by the packet that was passed by the "to port 53" rule. (You would have the same with TCP except for the direction on the rule; still "pass out proto tcp from port 22" is probably not quite what you want). > I now think that either the documentation is wrong, or > pf is wrong. At any rate, there seems to be a rather > serious disconnect between the two. The FAQ clearly > says: > > When a packet is selected by a match rule, parameters (e.g. nat-to) in > that rule are remembered and are applied to the packet when a pass rule > matching the packet is reached. Yes that's wrong. Address changes take effect at the time the match rule is processed when traversing the ruleset; rules processed later "see" the rewritten address. As pf.conf(5) says, Translation Translation options modify either the source or destination address and port of the packets associated with a stateful connection. pf(4) modifies the specified address and/or port in the packet and recalculates IP, TCP, and UDP checksums as necessary. If specified on a match rule, subsequent rules will see packets as they look after any addresses and ports have been translated. These rules will therefore have to filter based on the translated address and port number. > I know that the documentation (at this time) ALSO > says: > > match out on interface [af] \ > from src_addr to dst_addr \ > nat-to ext_addr [pool_type] [static-port] > [...] > pass out [log] on interface [af] [proto protocol] \ > from ext_addr [port src_port] \ > to dst_addr [port dst_port] > > where the pass rule has ext_addr instead of src_addr, > but at least two people on t...@openbsd.org have > confirmed that this is a bug and have already > submitted a diff that replaces ext_addr with src_addr > in the pass rule, see > https://marc.info/?l=openbsd-tech&m=168714686620055&w=2 I think that this bit _is_ correct as written, although it's not particularly useful as it doesn't allow passing just the specific translated packets. I think it's the example rules which are wrong, i.e. match out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.1 pass on tl0 from 192.168.1.0/24 to any directly fixing this would be match out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.1 pass on tl0 from 198.51.100.1 to any however this would be a good place to instead show how to use match...nat-to...tag and pass...tagged, maybe also received-on. Then a) it's clear what traffic is passed and b) that fits better with the very common use-case where the external (nat-rewritten) address is dynamic so you need to use an interface name with parentheses in the nat-to rule. But when you pull at that thread, the current structure of the pf faq section starts to unravel, i.e. it doesn't make sense to separate tags into "advanced", there's a fair bit of information which really isn't useful at the faq level (flag matching? the bit about using "block return" instead of a set of 6 different block rules that nobody learning from the faq would have thought of writing? syn proxy, esoteric scrub rules, being originally written from a point-of-view of "keep state" being a special thing and tweaked from that to the current state, ...) and it becomes a fairly big authoring job. > Should I be taking this to another mailing list? > Should I be submitting a bug report? Or am I just > really really dense and am just too stupid to read the > documentation correctly? Don't know really... In the absence of someone with good knowledge of pf and time+patience to craft an improved faq section, I'd mostly stick to getting information from the manpage for now... (you can get a nicely formatted version with "mandoc -T pdf /usr/share/man/man5/pf.conf.5 > pf.pdf").