I don’t think I’ve ever seen it done successfully and have often wondered if it’s for a lack of use cases or due to its bad success rate and complexity compared to UDP hole punching.
That said, I really wish there was a standardized way to do it. Some sort of explicit (or at least implicit but unambiguous) indicator to all firewalls that a connection from a given host/port pair is desired for the next few seconds. Basically a lightweight, in-band port mapping protocol.
It could have well been an official recommendation to facilitate TCP hole punching, but I guess it’s too late now, as firewall behaviors have had decades to evolve into different directions.
Honestly ISPs really missed an opportunity to essentially provide IPv6-only as a service and add an IPv4 compatibility layer to that (IPv6 already has a mechanism built in for this but grandma’s old laptop might not fully support it so you might need a local router provided by the ISP to give you native local IPv4 that allows you to access the internet) instead of CGNAT. But they chose to go with duct tape, spit, paper clips, and hope instead of investing in the correct solution. Shame on them and too bad for us.
And it's simply not true that there is no NAT in the wild with IPv6: every OPNsense installation with two uplinks and the need for anything better than an "arbitrary and uncontrollable" choice of the correct uplink for each outbound connection needs network prefix translation, as the residential dual-homing story for IPv6 is vaporware otherwise. NPT is used not for address space conservation, but to defer the decision about the correct source address to the router that has the knowledge of the correct policy.
And in this sense, IPv6 is worse than IPv4: there are too many people assuming no firewall and no NAT for IPv6, and designing their applications based on these almost-working (but de-facto now broken) premises. The correct premises are the same as for IPv4.
It might work better with UDP but I don't think those firewalls boxes tear down the mapping immediately on getting an RST - they wait until it times out.
NAT Behavioural Requirements for Unicast UDP, https://datatracker.ietf.org/doc/html/rfc4787
NAT Behavioural Requirements for TCP, https://datatracker.ietf.org/doc/html/rfc5382
TIL, thank you! I've been looking for this for quite a while after hearing it indirectly referenced recently, but only found host-side specifications for TCP simultaneous open.
Do you happen to know if common firewalls and NATs support it? If they do, I really wonder why TCP hole punching isn't more common.
- can't decide on a port in the same message
- don't suffer from NAT port randomization
I'm not saying it will never happen, but the Venn diagram of this being the minimum complexity solution just doesn't seem very large?
It is precisely this point that has flummoxed me when connecting my p2p wireguard config[1] with a friend that uses a pfsense router, no matter what we tried, pfsense always chooses a random source port.
But in the simple case this blog outlines, if both ends use the same source port, this method punches through 2 firewalls effortlessly:
This hs a good diagram to understand the options
https://rajsinghtech.github.io/claude-diagrams/diagrams/netw...
You can scope it to just your IPsec service, or whatever it is your hosting, or you can enable full cone for the whole subnet.
It is not DNAT, nor is it port forwarding. If you host a SIP proxy, SBC or peer to peer gaming, it will enable these use cases as well.
https://docs.netgate.com/pfsense/en/latest/nat/outbound.html
> Don't post generated comments or AI-edited comments. HN is for conversation between humans.
The most plausible output might be correct, or it might be utter bullshit hallucinations that only sound correct; the only way to tell is to actually try it or cross-reference primary sources. Unless you do, the AI answer is worthless.
The reason why they're getting so good at code now is that they can check their output by running and testing it; if you're just prompting questions into a chatbot and then copying their output verbatim to a comment, you're not adding any meaningful value.
But to the point of this thread: If you can't validate their output at all, why would you choose to share it? This was even recently added to this site's guidelines, I believe.
"Seems plausible".... Can you please read up about the ways LLM generate their output?
To be clear, I use LLMs to gut check ideas all the time, but the absolute minimum required to share their output, in my view, is verification (can you vouch for the generated answer based on your experience or understanding), curation (does this output add anything interesting to the conversation people couldn't have trivially prompted themselves and are missing in their comments), and adding a disclaimer if you're at all unsure about either (thanks for doing that).
But you can't skip any of these, or you're just spreading slop.
In this era where AI is eating away at how deterministic computers are, I really appreciate reading about an elegant solution to a real problem using deterministic logic.
Of course there’s still plenty of deterministic software you can run… for now.
I wrote little paper on this technique in school and did some practical tests, at the time I was actually unable to find an example of consumer grade router that it didn't work on! But my resources were rather limited, they certainly do exist.
Even in the presence of a conntrack entry created by an earlier outbound SYN,!ACK ?
Got a source?
I don't have a convenient source though.
> Plenty of setups block incoming SYN,!ACK packets
Nowhere close to being "plenty". It's doable, but this is extremely niche.
I can't really imagine why you would do it for NAT'd v4 since you can't avoid the connection tracking overhead, but you certainly could, and I don't doubt OP has run into it in the wild. I've seen much weirder firewall rules :)
What are the obvious reasons? If you're protecting a client system, you don't want to allow in any bare SYNs. (And for that matter, if you're protecting a server, you probably want to discard ill-targeted bare SYNs without consulting conntrack anyway, just as a matter of avoiding extra CPU work.)
All inbound packets are matched against existing sessions. In this case none will turn up, so the packet will go through the "new session" flow and be subject to the same filtering as a bare SYN. Look up how connection tracking works, e.g. in the Linux kernel, it's rather simple and logical.
Do you find this works reliably outside routers that preserve source ports? My understanding was that TCP punching tends to depend heavily on NAT behavior.
NAT is effectively your router doing DHCP with a 17-bit suffix (16-bit port + 1 bit for UDP vs TCP) to each of your applications and then not telling you the address it gave you or how long it is good for (which is what a regular DHCP lease does). This is in addition to it, most likely, already doing regular DHCP and allocating you a IP address that it does tell you about, but which is basically worthless since routing to just that prefix without the hidden suffix goes into a black hole.
If you could just ask your router for a lease on a chunk of IP+NAT addresses that you could allocate to your applications and rotate them as they expire, you would not need this horrifying mess.
The router would just need to maintain the last-leg routing table (what a concept, a router doing routing with routing tables) just like it already does DHCP.
The applications would have short-term stable addresses that they could just tell their peers and just directly tell the router/firewall to block anybody except the desired peer short-term address.
The “just” is doing a lot of lifting there. I’m glad the various port mapping protocols didn’t really take off and it looks like IPv6 is going to actually make it instead. Much less complexity in most parts of the stack and network.
I am pointing out how the problem NAT “solves” is just dynamic address configuration. They have implemented a N+K bit address where the N-bit prefix is routed and allocated using IP and the low K-bits are routed and allocated like a custom fever dream.
You can just do it all the same way instead of doing it differently and worse for the low bits.
To be clear, the router should rewrite zero bits in the packet under the scheme I am describing just like how routers have no need to rewrite any bits when routing to a specific globally-routable IP address.
You get a lease for a /N+K address. /N routes to your router which routes the last K bits just like normal as if it had a /N-M to a /N route. This is a generic description of homogenous hierarchical routing.
This still sounds like a very bad mixing of layers, even if done in a perfectly standardized and uniform way.
> It is always a mystery how people just randomly misinterpret what I write.
If this is intended literally and not as a general complaint: My main problem of understanding your suggestion is that I don't know what you mean by "IP+NAT address". NAT is a translation scheme, not an address.
Maybe it would be clearer if you could provide an example?
> You get a lease for a /N+K address. /N routes to your router which routes the last K bits just like normal as if it had a /N-M to a /N route.
> This still sounds like a very bad mixing of layers, even if done in a perfectly standardized and uniform way.
No, I am describing a generalization of IP to arbitrary concatenated routing prefixs.
NAT has the same problems as if we lived in a alternate world where we decomposed IPv4 into 4 8-bit layers and then used a different protocol for each layer. That is obviously stupid because the subdivision of a /8 into /16s and a /16 into /24s is fractally similar. You can just use the same protocol 4 times. Or even better, use one protocol (i.e IP) that just handles arbitrary subdivision.
In the IPv4 (no NAT) world your application has a 49-bit address. Your router is running a DHCPv4 server and allocates your computer a /32 and your computer is “running” a DHCPvPort server that allocates a 17-bit prefix to your applications.
In the IPv4+NAT world your application has a 49-bit address. Your router is “running” a DHCPv4+Port server and allocates your applications a /49, but only tells them their /32 and then rewrites the packets because the applications do not know their address because the stupid router did not tell them.
In good world your application has a 49-bit address. Your router is “running” a DHCPv4+Port server and allocates your applications a /49 and tells them their /32 prefix and 17-bit segment. No packet rewriting is necessary.
Your router could also choose to allocate your computer a /32 subnet and leave DHCPvPort to your computer. Or it could give your computer a /31 if you have 8 interfaces. Or a /34 as a /32 subnet with 2-bit port prefix. Each node routes as much or as little routing prefix as it understands/cares about.
This is a generalization of IP that can handle arbitrary-length, arbitrarily-concatenated routing in a completely uniform manner and all the pieces are basically already there, just over-specialized.
If you are tying to work around your firewall because it isn’t yours, that’s not a legitimate use.
Take mobile data connections, for example: Most people don't want to pay for metered (by the byte) inbound traffic they didn't ask for that also drains their battery, but do want to be able to establish P2P connections for lower latency VoIP etc.
This is a firewall that's definitionally "not theirs", but that still also serves their interests, yet usually doesn't offer any user-accessible management interface.
So may I please traverse this firewall now, or is my use case still illegitimate?
If you are buying firewall as a service then request a user interface or change your service provider.
What provider would you suggest somebody wanting to make VoIP calls on their smartphone switch to that allows port forwarding of the kind you describe? And which popular VoIP app would support statically forwarded ports like that?
On the other hand, there is plenty of badly written networked software. I bet most of the networked software developers have no idea how to correctly plumb their software. They just open whatever connection, e.g. sockets, their OS provides and just run with it without care of the underlying layers. The OSI model theory in fact encourages this ignorance.
At least with IPv6 this crap becomes a little easier because you no longer have randomized source ports (which this article just ignores because some devices indeed maintain the same source port) and the IP address contains all the routing information you need. A simple simultaneous open is all you need.
We could have a standard for doing that directly at the NAT box level instead of relying on a third party STUN server, it simply didn't happen (and in fairness, the benefits would be quite minimal).
> my grandmother had a cookie jar collection and I always thought it was weird until I realized she was basically running a primitive NFT gallery except the tokens were actually useful because they contained cookies
Hardly the case in even half of typical deployment cases.
>Many home routers try to preserve the source port in external mappings. This is a property called “equal delta mapping” – it won’t work on all routers but for our algorithm we’re sacrificing coverage for simplicity.
So to what percentage is this coverage sacrificed exactly? No idea. Not as useful if the percentage is high, as you are implying.