Stumbling upon a great blog post that makes something click is always a pleasant experience.
Stumbling upon a great blog post that makes something click is always a pleasant experience.
UDP is connectionless, but typically a UDP communication is bidirectional. This means a NAT needs to inspect UDP packets and retain a mapping to direct incoming UDP packets to the right place. With no connection information this can only be done as an LRU cache or similar.
TCP is connection oriented, and a NAT might rapidly free up resources when a connection is closed (ie, when the final FIN has been ACKed). But if there's no FIN, the NAT is in the same case as it is with UDP. Making a lot of connections without closing them fills up NAT buffers.
When you have a home NAT and a carrier-grade NAT you may get an impedance mismatch of sorts. The CGNAT might have insufficient ports allocated to your service to keep up with your home NAT, resulting in timeouts or dropped mappings. Your home NAT will have one set of mappings and the CGNAT another, and the two sets probably won't be exactly the same. This means some portion of the mappings held in memory are useless.
As a specific example, many years ago Google Maps would routinely trigger failures. Using Maps would load many tile images, which could overwhelm a NAT or CGNAT. The result was a map with holes in it where some tiles failed to load.
Browsers have long had limits on concurrent connections per domain. Total concurrent connection limits are also old news, but are not quite as old as per-domain limits. You probably can't make a NAT choke with just simple web requests (even AJAX) any more. You might be able to do it using, eg, WebRTC APIs, though I would be surprised if those aren't also subject to limits.
I had the same SSH dropout problem, asked my ISP[1] to switch me from CGNAT to dedicated IPv4; they did, and it's fixed.
[1] Aussie Broadband, a smaller ISP in Australia renowned for good customer service.
I had the same problem and did the ~/.ssh/config trick years ago. Interested in contacting my ISP so that they fix the problem for all users (although it might be fixed now, idk).
This shouldn't make much difference for them. Most connections are closed within a few seconds anyways. Long lived connections with no traffic are rare.
With no data whatsoever, I'm guessing less that 1% increase in NAT table size.
[Edit: ] Or in this case, an ISP in Denmark that is trying to minimize ipv4 cost by using LSN (carrier grade nat) which also has many other drawbacks.
A SSH session does not generate any traffic
This does not have to be true. You can enable TCP keepalive in the server and client configuration.
Client via ~/.ssh/config:
TCPKeepAlive yes
ServerAliveInterval 60
ServerAliveCountMax 2
Server via /etc/ssh/sshd_config: TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 2
Why are the TCP keepalives only sent after 2 hours?Each OS has a default time set for keepalives. If you do not specify it in the ssh config, it will use the OS default. In Linux, you can set this in /etc/sysctl.conf:
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 2
After adding this, run sysctl -e -pYou can see the timers on your established connections with:
ss -emoian | grep tim
Note: TCP timers are not the same as ssh client and sshd server tcp keepalive packets. These are two distinctly different mechanisms that can accomplish the same thing. Not all applications support TCP socket keepalive. You can wrap applications with a library called libkeepalived to add support without code changes by using LD_PRELOAD.In Windows this is set in the registry [1] On mac this is set via sysctl similar to Linux.
After you have adjusted your client and server config, restarted sshd on the server, then ssh to your server using the flag -vv and you will see the keepalive packets.
[1] - https://serverfault.com/questions/735515/tcp-timeout-for-est...
Making my ISP fix the underlying issue - that their TCP connection idle-timeout is too short - will make sure all their customers won't have to encounter this problem.
Fix described here: https://bugs.launchpad.net/ubuntu/+source/appstream/+bug/157...
Why didn't they? What are the arguments against this solution?
You would have to upgrade the software and OS of systems using IPv4-only to understand the IPv6 IP header. (Which is much simpler than upgrading to support IPv6 AND assigning IPv6 addresses)
I guess the bigger problem is that all routers in the path between an IPv6-only host and an IPv4-only host would have to support IPv6 to parse the destination IPv4/IPv6 address and make the proper routing decision.
This would make "IPv6 to IPv4 and vice-versa" traffic only work for some, depending on which ISPs has upgraded their equipment to support IPv6, and which IPv4-only hosts has upgraded their software+OS to support IPv6. This could result in IPv6 getting a very bad reputation, further delaying adoption.
Anything I am missing?