PF submission stuck waiting for nearly 4 years

Steamworks for example uses libjingle to find a workable connection from a set of candidates, this employs STUN which simply cannot work with an asymmetric NAT...
Coincidentally, I was just reading about STUN, and am curious about its flaws. My understanding was that it will try to connect the two peers directly, and will only fall back to a proxied connection if this fails. Are you saying all connections where one end is behind asymmetric NAT will always fall back to proxied?


Maybe the "symmetric NAT" on that page is a thinko, and they really meant to write "asymmetric NAT?"
(I don't consider that page authoritative because they're trying to sell me something.)
 
RFC4941: bookmarked.
It's no panacea
"The temporary addresses standardized in RFC 4941 were originally meant to mitigate some of the security and privacy issues discussed in this tip. However, we will see that they fail to mitigate a number of potential problems, while at the same time introducing additional complexity."
 
IMHO, the idea that somehow "hiding" IP addresses was something desirable was always flawed, but you can sure discuss that in depth. It's not really on-topic here, while the purpose of NAT definitely is in the light of a patch attempting to improve NAT.

Considering NAT "for security" has always been ill-advised, and THAT is a fact: You never knew what exactly a specific NAT implementation was doing, but you knew (or: COULD know) the purpose, which is routing as many packets as possible, therefore allowing operation as close to the scenario without NAT as possible.

Side note, I really had a giggle about that GRC page, basically saying "NAT gives security, but maybe not enough, so use moar NAT for moar security" :D sorry, just too hilarious.
 
But if it's not a "niche-product", we could try to figure out reliable tests.
I have no idea about how much sense it makes to fully implement some RFC's.
But as a layman I generally it is reasonable to assume that non-deprecated IETF specifications are probably somewhat well-thought.

And in this case, if I understand correctly, there would be quite some use cases, if there were a way to easily enable this one RFC on the users' own risk, it could turn out to be useful for people who need a router that supports all this hole-punching for lan parties, kids network with all the newest Upnp fads, internet cafes etc, and be it as inofficial community patch of expressedly unknown quality and security.

This would at least create the possibility for interested people to get actively involved, without too much hassle.
 
Well, thinking about usefulnes, I now tend to consider NAT a "thing from the past" anyways. But as long as there are some die-hard IPv4-only networks, it will still have its use…

As long as NAT is widely used, I think this patch makes sense, as it indeed improves the (intended!) functionality of NAT. Of course, you should still be able to do firewalling based on "connection tracking" (and therefore forbid connections originating from somewhere else to the same socket), but you should also be aware that this is no silver bullet, and it is only tied to NAT because NAT will never work without any kind of connection tracking.
 
Coincidentally, I was just reading about STUN, and am curious about its flaws. My understanding was that it will try to connect the two peers directly, and will only fall back to a proxied connection if this fails. Are you saying all connections where one end is behind asymmetric NAT will always fall back to proxied?


Maybe the "symmetric NAT" on that page is a thinko, and they really meant to write "asymmetric NAT?"
(I don't consider that page authoritative because they're trying to sell me something.)
That was actually my bad, what I meant is of course 'symmetric NAT'. It has been a while since I last had to pull my hair out over messing with different NAT types and I always found the established terms to be highly misleading, as there is nothing symmetric in symmetric NAT and no cone in any cone type NAT, at least not in my imagination (or lack thereof) of things.

The reason why STUN cannot help if you are behind a symmetric NAT is that this type of NAT will create a separate NAT mapping for each set of local IP:local port/remote IP:remote port. So when host A which is behind a symmetric NAT asks STUN server B on the internet about what IP address/port B sees from A, this information is useless as it cannot be used by host C on the internet to connect to A.

If both ends are behind a symmetric NAT then the only option is the use of a relay/proxy server. In case only one side is behind a symmetric NAT there might still be a chance for direct communications, but that will likely depend upon how intelligently the automated mechanisms handling this stuff have been implemented.
 
Glad we can all finally agree that the problem is the non-specificity of the terms being used...

Just my 2¢: msplash, you've been choosing your words kinda awkward, to say it politely... While IMHO Zirias was arguing sensibly, you didn't. I do have some basic knowledge in networking, but still I have to & want to learn more; now one who presumably knows more than me is gone. Thx a lot.
Honestly don't know how you came to that conclusion. I have intentionally tried to be precise with the words I use. Note sure how that comes off as awkward.
 
AFAIK the considered functionality (UDP STUN and whatever) is not only used for certain games, but also for VoIP network.
And, while I do not care much about ill-devised games, VoIP routing should be considered an important usecase for a Unix server.
 
I find it extremely hard to extrapolate an expected EOL of IPv4. 10 years? 20? 50? Maybe it will stay alive in leaf networks for the next two centuries? Just can't tell.
 
  • Kristof Provost wants tests, there are none. Do we take that job? Are we qualified? I'm not, unless you help me.
  • Kristof Provost states that he didn't have the time "to examine the implications in sufficient detail." FMLU, this could be things like: the patch accidently disables vital codepaths, variables don't get initialized that were w/o the patch, ... what else?
  • The author claims to have corrected some of the style(9) issues, but there are still many. These are minor issues that even a trained codemonkey can fix easily?
  • There's a goto in the patch. Usually that should trigger extra attention?
  • The patch is several years old, thus it's not clear if it will run-through on current 14-CURRENT sources.
  • I consider "to demonstrate a use case for the patch" as lower priority, because simply throwing in the terms VoIP, SIP, WebRTC triggers enough attention?
TWIMC I started trying to understand that RFC4787, and interestingly, it states at the very beginning:
Code:
   The requirements of this specification apply to Traditional NATs as
   described in [RFC2663].

   This document is meant to cover NATs of any size, from small
   residential NATs to large Enterprise NATs.  However, it should be
   understood that Enterprise NATs normally provide much more than just
   NAT capabilities; for example, they typically provide firewall
   functionalities.  A comprehensive description of firewall behaviors
   and associated requirements is specifically out-of-scope for this
   specification.  However, this specification does cover basic firewall
   aspects present in NATs (see Section 5).

   Approaches using directly signaled control of middle boxes are out of
   scope.

   UDP Relays (e.g., Traversal Using Relay NAT [TURN]) are out of scope.
TURN was the term I was searching for above. STUN's companion.
So msplash was not that wrong about firewalling functionalities of NATs.

Back on topic:
  • Without reading the patch, it should be possible to derive assertions from the relevant sections 1. & 3. of that RFC4787, maybe in some cases from other RFCs it references. We could write these down using the same notation from the RFC. These could be just a few in the three groups: on session start, while a session is active, when the session is dropped. Correct?
  • After beeing proof-read twice, these can be translated to be woven into the code as KASSERT(9)s, right?
  • Maybe some more code-specific tests/assertions can or should also be added then, like "there must/cannot be an entry in that hashtable for this", "this is an unique entry", ...
  • Maybe we should start with this topic?: IMHO we should also try to formulate assertions about the traditional behaviour of the pf-NAT, because these would greatly help to asure that
    1. our understanding how the traditional NAT works conforms to the actual implementation
    2. our tests for the patch comply to that, indicating they are the right tests & assertions
    3. the patch does not break the non-patched parts of the code.
    4. This would also help to increase Kristof Provost's trust in the patch.
I'm having trouble to accept the term session in conjunction with UDP, but that should hopefully go away soon. ;) IIRC, when writing tests/assertions, the part that I underlined above is important: not to glimpse into the code (if it is preexistent), but write them down in a more abstract way 1st.
 
I use Webrtc just fine even with my insecure, evil "symmetric" NAT. This feature is not necessary. I reiterate my preference that there be a way to turn this off if the patch is accepted. I guess it won't really affect me if it is because I use Openbsd for my firewall. I seriously doubt this patch would gain any traction in that project.
 
So why exactly does someone need a patch to do something that should be easily achieved just by adding static-port to the nat rule? And why should such behaviour then be forced upon just about everyone else, by making it the default behaviour? I think this is all backwards, seriously.
 
So why exactly does someone need a patch to do something that should be easily achieved just by adding static-port to the nat rule? And why should such behaviour then be forced upon just about everyone else, by making it the default behaviour? I think this is all backwards, seriously.
It *should* only affect NAT, not any rules using connection tracking (aka "keep state"). So, if done right, you can filter in the exact same way as before, if you like. It should only change the behavior if all you have is a NAT rule.

Of course, with a simple configuration like from the handbook
Code:
block in all
pass out all keep state
you *expect* your firewall to block anything incoming except for direct answers to what's outgoing. If the patch would change this, it would be broken, no matter whether you use NAT or not.

But it's reasonable to expect something like
Code:
nat on tun0 from $internal_net to any -> (tun0)
to do a "best effort" approach of routing (by rewriting) as many packets as possible. Just add simple filter rules (like above) to make this more restrictive.
 
There's a goto in the patch. Usually that should trigger extra attention?
Just had a look at the "goto"s introduced by the patch. They're fine, following your typical "goto cleanup"/"goto failed" idiom. A lot of C code needs this kind of goto for a clean and readable structure, possible alternatives are much worse.
 
It *should* only affect NAT, not any rules using connection tracking (aka "keep state"). So, if done right, you can filter in the exact same way as before, if you like. It should only change the behavior if all you have is a NAT rule.
I don't think it's that simple. My understanding is that the filtering rules are evaluated only if there is no matching state entry. And from what pf.conf(5) tells, such states are created automatically from translation aka NAT rules:
Code:
TRANSLATION
     Translation rules modify either the source or destination address of the
     packets associated with a stateful connection.  A stateful connection is
     automatically created to track packets matching such a rule as long as
     they are not blocked by the filtering section of pf.conf.
The interesting question is what does that mean with regard to RFC4787 section 5 - Filtering behaviour? In particular the passage that states:
Having the filtering behavior being an option configurable by the administrator of the NAT ensures that a NAT can be used in the widest variety of deployment scenarios.
So how would one go about - in the context of a pf.conf(5) file - actually configuring the required filtering behaviour of the NAT? As I sure as hell want an Address and Port-dependent Filtering for all intents and purposes.
 
It *should* only affect NAT, not any rules using connection tracking (aka "keep state"). So, if done right, you can filter in the exact same way as before, if you like. It should only change the behavior if all you have is a NAT rule.
Jose & mickey, does this answer satisfy your objections? For sure I'm not in the mood to spend any thoughts & work into s/th that's not worth it.

Assuming it's worth going on: so this assertion would result in an external test, i.e. that goes into the CI devel/kyua framework? E.g. create (clone) the necessary network interfaces, and use netcat (nc(1)) or such to test/verify/asure that packets pass (block, resp.) on a reasonable simple pf.conf(5)? (& clean up after the test) Right? I don't see this could/should be tested/asserted internally in the code. Correct? Are there more appropriate tools to use other than netcat? Preferably in base?
Of course, with a simple configuration like from the handbook
Code:
block in all
pass out all keep state
you *expect* your firewall to block anything incoming except for direct answers to what's outgoing. If the patch would change this, it would be broken, no matter whether you use NAT or not.
But it's reasonable to expect something like
Code:
nat on tun0 from $internal_net to any -> (tun0)
to do a "best effort" approach of routing (by rewriting) as many packets as possible.
Dito. External tests?
Just had a look at the "goto"s introduced by the patch. They're fine, following your typical "goto cleanup"/"goto failed" idiom. A lot of C code needs this kind of goto for a clean and readable structure, possible alternatives are much worse.
Yes, I know. Nevertheless, I'll try harder to understand & verify that it's ok to leave out the skipped code.
I don't think it's that simple. My understanding is that the filtering rules are evaluated only if there is no matching state entry. And from what pf.conf(5) tells, such states are created automatically from translation aka NAT rules:
Code:
TRANSLATION
     Translation rules modify either the source or destination address of the
     packets associated with a stateful connection.  A stateful connection is
     automatically created to track packets matching such a rule as long as
     they are not blocked by the filtering section of pf.conf.
The interesting question is what does that mean with regard to RFC4787 section 5 - Filtering behaviour? In particular the passage that states: "Having the filtering behavior being an option configurable by the administrator of the NAT ensures that a NAT can be used in the widest variety of deployment scenarios."

So how would one go about - in the context of a pf.conf(5) file - actually configuring the required filtering behaviour of the NAT? As I sure as hell want an Address and Port-dependent Filtering for all intents and purposes.
IIUC the manpage pf.conf(5) is unambiguous here: "A stateful connection is automatically created [...] as long as [the packets] are not blocked by the filtering section of pf.conf." I.e., the blocking filtering rules overrule NAT's packet translation. Again, we could/should create an external test (or set of tests) to ensure this? EDIT Yes, and additionally this could go into an code-internal assertion. My understanding is that the filters are applied 1st, then the NAT rules, then maybe additional filter rules? Are there such? In ipfw(4), the rules are numbered. How is the ordering handled in pf(4)? Or does the admin have to use netgraph(4) to apply stacking of rules?/EDIT

Do you agree we should start with tests & assertions on the existing NAT? For sure we'll run into greenhorn traps; this would help to correct these, and we'll have an initial set of tests that will asure that the patch does not break the existing code. We can flag the tests that we think should be changed or disabled for the patch.
 
  • Kristof Provost wants tests, there are none. Do we take that job? Are we qualified? I'm not, unless you help me.
There are ... I won't say extensive, but there are already a fair number of tests for pf: https://cgit.freebsd.org/src/tree/tests/sys/netpfil/pf

  • Kristof Provost states that he didn't have the time "to examine the implications in sufficient detail." FMLU, this could be things like: the patch accidently disables vital codepaths, variables don't get initialized that were w/o the patch, ... what else?
Just about everything. The patch could potentially introduce bugs, out-of-bounds memory accesses, vectors for denial of service (e.g. memory leaks), ...

  • The author claims to have corrected some of the style(9) issues, but there are still many. These are minor issues that even a trained codemonkey can fix easily?
Those are by far the least significant part of the work. Don't bother until and unless everything else is sorted.

  • There's a goto in the patch. Usually that should trigger extra attention?
Sometimes, but goto is a very common error handling pattern in kernel C, and likely used that way here. That's usually fine.

  • The patch is several years old, thus it's not clear if it will run-through on current 14-CURRENT sources.
That's probably the second easiest bit of the task. I don't think the NAT code evolved a great deal, and this is likely just a mechanical resolving of merge conflicts. It needs to be done, but it's likely trivial.

  • I consider "to demonstrate a use case for the patch" as lower priority, because simply throwing in the terms VoIP, SIP, WebRTC triggers enough attention?
Strong disagree here. The first thing to accomplish with any patch is to convince people that what it tries to do makes things better. Once that's established we can argue about how to get there.
Throwing around terms doesn't accomplish that at all, unless you mean to claim that VoIP/SIP/WebRTC currently don't work (they do...).
 
There are [tests] ... I won't say extensive, but there are already a fair number of tests for pf: https://cgit.freebsd.org/src/tree/tests/sys/netpfil/pf
Thx for the hint. Didn't have a look into these; I meant code-internal KASSERT(9)s & CTASSERT(9)s. There are a few, but IIRC no new ones. IIUC a KASSERT(9) would crash the whole kernel intentionally; isn't it possible to just crash the kmod instead?
Just about everything. The patch could potentially introduce bugs, out-of-bounds memory accesses, vectors for denial of service (e.g. memory leaks), ...
Oh, to insert bounds checking & other assertions in C code is one of my most beloved hobbies.
Strong disagree here. The first thing to accomplish with any patch is to convince people that what it tries to do makes things better. Once that's established we can argue about how to get there.
And rightly so. 100% agreed.
Throwing around terms doesn't accomplish that at all, unless you mean to claim that VoIP/SIP/WebRTC currently don't work (they do...).
Yes, of course, right. My assertion that the current implementation might be suboptimal, might be wrong.

OK, I'll try harder to understand that the assertion that the RFC4787 fixes a problem, is justified. If there is no problem -> that RFC4787 is bogus (at least does not apply to FreeBSD's pf-NAT implementation), and the patch "fixes" a non-existent issue. Maybe it's that with endpoint-independent mapping NAT, some usually complex setups are much easier? Damn, that RFC4787 claims: "Network Address Translators (NATs) are well known to cause very significant problems with applications that carry IP addresses in the payload (see [RFC3027]). Applications that suffer from this problem include Voice Over IP and Multimedia Over IP (e.g., SIP [RFC3261] and H.323 [ITU.H323]), as well as online gaming.".
 
Thx for the hint. Didn't have a look into these; I meant code-internal KASSERT(9)s & CTASSERT(9)s. There are a few, but IIRC no new ones. IIUC a KASSERT(9) would crash the whole kernel intentionally; isn't it possible to just crash the kmod instead?
No. Any assertion will stop the kernel. Also bear in mind that assertions are only executed on kernels with INVARIANTS set. They're not checked on production builds.
 
  • Thanks
Reactions: a6h
Jose & mickey, does this answer satisfy your objections?
No. NATed connections means pretty much every connection in a SOHO setup. This change will essentially affect the global behavior of pf(4) for those setups.

I've been trying to think of ways to exploit static source port NAT*, and one thing that occurred to me is that you could create a peer-to-peer botnet using a rogue STUN server. That botnet would be resilient to losing the STUN server which presumably would also be the control server. You could have peers become the control server at random or through some distributed algorithm. You would wind up with a distributed and resilient botnet which is frankly terrifying.

* I coined this term. "Asymmetric" and "full-cone" don't make any sense to me.
 
Strong disagree here. The first thing to accomplish with any patch is to convince people that what it tries to do makes things better. Once that's established we can argue about how to get there.
Throwing around terms doesn't accomplish that at all, unless you mean to claim that VoIP/SIP/WebRTC currently don't work (they do...).
[…] Damn, that RFC4787 claims: "Network Address Translators (NATs) are well known to cause very significant problems with applications that carry IP addresses in the payload (see [RFC3027]). Applications that suffer from this problem include Voice Over IP and Multimedia Over IP (e.g., SIP [RFC3261] and H.323 [ITU.H323]), as well as online gaming.".
No generic solution will be able to solve the problem with IP addresses in payload. Specific "protocol helpers" were an idea, but are useless as soon as encryption is used. The only way to solve THIS is to be able to configure the "external address" in the application (which I had to do e.g. for SIP over IPv4-NAT).

Still, NAT can be improved, so you don't need to configure "port forwarding" for everything incoming. That's why I assume ISPs doing CGNAT will definitely want that improvement (but probably use different solutions, not pf on FreeBSD). It helps NAT the way NAT was meant: Best effort to handle multiple machines when you only have one public address for them.

Indeed, if the patch changes pf more globally (so, "keep state" for filtering with tracking of connections is affected), this is a problem. It shouldn't work this way, because it's definitely not what you expect when trying to filter traffic (actual firewalling).
 
I don't think it's that simple. My understanding is that the filtering rules are evaluated only if there is no matching state entry. And from what pf.conf(5) tells, such states are created automatically from translation aka NAT rules:
Code:
TRANSLATION
     Translation rules modify either the source or destination address of the
     packets associated with a stateful connection.  A stateful connection is
     automatically created to track packets matching such a rule as long as
     they are not blocked by the filtering section of pf.conf.
This is kind of hard to interpret. It makes sense to not evaluate any rules if a packet matches an existing state entry, otherwise "keep state" couldn't work with blocking everything incoming.

The question is: Look at the scenario that a packet arrives from a so far unknown remote host on a port that HAS a mapping. Does the patch do the sane thing here, rewrite this packet, but still evaluate the rules (cause with the unknown remote host, it doesn't really match a state entry)? If yes, it would still be blocked if you have e.g. a "block all" rule, but would be routed and rewritten correctly if no filter rule blocks it.

Sure, this is one thing you must review when reviewing the patch. It should NOT introduce a hole in the stateful filtering mechanisms, and I'd say if it does, it is broken.
 
Back
Top