1. 103
  1.  

  2. 21

    This is hands down the best article I have ever read on NAT traversal. I’ve spent years of my life dealing with all of the fun issues that come up (for example, some UPnP implementations care about the Case-Sensitivity of the headers sent in the faux-HTTP request, and they don’t all agree!), and I still learned things reading it.

    1. 10

      Thank you! In return, I’ve just learned that some UPnP implementations care about header case. Thanks, I hate it!

      But seriously, that’s great intel and TIL :). If you have references for what empirical behaviors you discovered, I’m interested!

      1. 5

        I don’t have any references, but I can say that I’ve also seen:

        1. Routers may or may not like SOAPAction header value double quoted.
        2. Routers may reject have multiple mappings to the same internal port, even with distinct destination IPs. For example, if you have a mapping for external port 8080 to internal address 192.168.1.100:7070, it will reject adding a mapping for external port 8181 to internal address 192.168.1.200:7070 because the internal port “collides”.

        I think that’s all I can remember, and I don’t remember any data about how often these things occurred. Consumer routers are amazing creatures.

        1. 5

          Amazing creatures indeed. Thanks for the tips! So far, it seems that, thankfully, most routers these days that offer UPnP IGD also offer NAT-PMP or PCP. UPnP does grab a teeny bit more of the long tail, but you can sort of get away with ignoring UPnP in a lot of cases.

    2. 16

      I just want to make a meta point here…this article is very much content marketing for Tailscale. Normally I flag this on principle.

      But. But. But.

      The amount of effort and detail put into this, the explicit “this is how you would implement a competitor or an alternative to what we provide”, and the educational tone of “here is an amazingly detailed list of stuff we had to overcome in the course of shipping our product” instead of “oh this is all Very Scary and you should just buy our product and not worry about it” is what makes it different for me.

      This is the new gold standard in my opinion–if somebody kvetches about their content spam getting flagged, I will point to this article and ask “were you this useful?”.

      1. 7

        Thank you :). This is exactly the balance I was shooting for when writing the article. Yes it’s indirectly marketing for Tailscale, in a “btw we make a thing so you don’t have to think about any of this” way. But like you, I hate content marketing that runs on a platform of “you’re not equipped to understand this problem, just trust us.” I’m glad that I apparently managed to thread that needle :)

        My litmus test when writing was: if I remove all mention of Tailscale in the article, is it still the thing I would personally read to remember the nasty details of how to do NAT traversal? At some point I’ll crosspost this to my personal blog for safekeeping, and I don’t want it to feel out of place there.

      2. 4

        Hey, this article is pretty cool, however would it be possible for you to use the well-defined documentation IP addresses next time? Those can freely be used without running the danger of misdirecting bots to innocent websites.

        1. 8

          An early draft of this article used the documentation ranges. Unfortunately, unless you breathe BGP configurations for a living, the documentation ranges are really hard to read, especially when you’re trying to convey to/from and packet transformations. It made the whole article much harder to follow.

          In the end, I decided to go with easier to read addresses, on the reasoning that this isn’t software documentation, so the primary risk of crosstalk (people copy/pasting config snippets) doesn’t apply. That said, it’s obviously a compromise that I’m not super happy with.

          The article evolved a bunch from the early draft, let me see how readable it is now if I swap in the documentation ranges…

        2. 3

          To me, one of the most appealing things about IPv6 is you get to avoid most of this junk. If only we could assume it was always available…

          1. 3

            [cgNAT] is a run of the mill double-NAT, and so as we covered above it’s mostly okay

            Huh? I was under the impression that cgNAT (NAT444) is completely impenetrable.. nothing could traverse the cgNAT on my previous ISP.

            1. 4

              CGNAT isn’t by itself harder than regular NATs, but CGNATs can have characteristics that make them harder to traverse. They might do endpoint-dependent mapping (which any NAT can do), they probably don’t support hairpinning (which breaks connectivity between two different subscribers of the same ISP), and sometimes break the port mapping protocols (in fairness, to avoid confusing software that’s a bit too naive about the realities of NAT traversal).

              Overall, CGNATs are still bad news for p2p connectivity, but they’re not automatically the death of all p2p connectivity. Tailscale successfully traverses a fair number of CGNATs that are “well enough” behaved.