11

I have an unreliable network connection between two machines: sometimes active TCP connections get dropped for reasons beyond my control. I want to establish a reliable TCP connection between the two machines.

If the network was reliable, I'd just run ssh -L 1234:localhost:1234 remotehost, with the server listening on port 1234 on remotehost, and point the client at localhost:1234. But if the ssh connection dies, so will the forwarded connection. How can I arrange to automatically restore the connection between the client and the server?

Non-solutions:

  • This isn't for interactive applications, so screen does not apply.
  • This isn't just about reconnecting an SSH tunnel automatically, � la autossh. I want to continue using the same tunneled TCP connection, not start a new one.
  • In principle, a VPN would do the trick. But it seems overkill when I just want one TCP connection, and I'd like a solution that works even if I don't have root permissions on either side.

I have a dim memory of a program called rocks that did just that, but it seems to have fallen off the face of the web. I'm mostly interested in Linux on both sides (though I'd expect a program at this level to be portable to other unices), but if you know of a program that works between QNX and VMS, all the better.

  • Gilles, are you using tcp keepalives with your ssh connections? If not, try this first... some NAT implementations time connections out quickly – Mike Pennington May 30 '11 at 23:12
  • @Mike: Thanks for the tip. I don't have an immediate need, but I've faced both situations where some intermediate route came and went (so TCP keepalives did more harm than good) and situations where a NAT overloaded and dropped me (so TCP keepalives might help). TCP keepalives wouldn't matter for a continuous stream anyway (e.g. scp), would they? In any case I'd like to keep this general: next time I'm faced with a flaky network of whatever flavor, what can I do? – Gilles 'SO- stop being evil' May 30 '11 at 23:19
  • Gilles, the solutions are different for constant streams like `scp`. I was responding w/ ssh keepalives based on your port-forwarding example. Re: flaky downstream hop, there isn't much you can do, other than create an ssh session with keepalives that are *more* tolerant (i.e. allow more dropped keepalives with `ServerAliveInterval > 0` and `ServerAliveCountMax > 3`). NAT requires lower keepalives intervals. The key issue is to identify what the problem is and tailor accordingly. Put the options in `.ssh/config` so they are always there for you – Mike Pennington May 30 '11 at 23:26
  • @Mike: One of my use cases includes the client getting its IP from an overloaded NAT than randomly drops even active connections (think more P2P than there should be). After a few seconds, the client manages to reconnect but might get a different IP address. There's no way the TCP connection will survive in that case. Rocks copes, but I'd prefer something that compiles out of the box on today's systems. – Gilles 'SO- stop being evil' May 30 '11 at 23:31
  • in the case of the NAT giving you new IPs, there isn't much you can do than get the NAT fixed or hope for another `rocks` implementation... although this is obviously a real kludge – Mike Pennington May 30 '11 at 23:36

4 Answers4

6

Is the old an unmaintained Reliable Sockets (Rocks) what you're looking for ?

user9517
  • 114,104
  • 20
  • 206
  • 289
2

The only standard protocol I know of with this capability is MPTCP. It is transparent to the application layer, so SSH on top of MPTCP should just work. It can run the underlying TCP connections over different paths with different IPs, so in principle it could be used to migrate your SSH connection in and out of the VPN connection depending on whether the VPN connection is up.

I don't know much about the maturity of MPTCP implementations, but the design of the protocol looks quite robust.

It should protect your SSH connections from getting lost due to flaky network connectivity. It won't protect you against a mitm who wants to break your SSH connection. A mitm can still inject corrupted data, which SSH will detect and break the connection.

An MPTCP like reconnect method build into the SSH protocol would be the method I could imagine keeping a connection alive for the longest possible time. But I don't think such a feature has been designed for the SSH protocol.

kasperd
  • 29,894
  • 16
  • 72
  • 122
0

You could use daemontools to keep the ssh port forward up; it won't necessarily keep programs depending on the connection alive while it's down (as presumably when ssh disconnects the local port will start refusing their connections), but it's a start.

I suspect there are some iptables tricks, like causing that port to DROP packets as soon as the ssh forward goes away, so the connecting programs just know that packets are disappearing, not being refused. I'm just learning daemontools myself (again) so I'm not sure if you can run a custom script when a service dies, but I suspect you can.

-2

TCP does this automatically. You need only disable or weaken the typical practical cleanup hacks used to kill moribund TCP connections. Disable TCP keepalive for your connection, and greatly increase the limit for excessive retransmissions. On Linux, for example, write a large number into /proc/sys/net/ipv4/tcp_retries2.

However, in a modern network a stateful packet inspection firewall is likely to forget about a TCP connection which fails to exchange packets regularly, so it may rain on your parade.

aecolley
  • 943
  • 4
  • 15
  • 1
    It is true that TCP can handle the situation, as long as each endpoint has a static IP address and there are no stateful middleboxes. The question mentions `reasons beyond my control`, which I read as dynamic IP or stateful middleboxes. In such scenarios TCP keepalive can help a little bit. But no matter how you configure TCP keepalive, it won't be enough to keep the connection alive when a middlebox lose state due to being restarted. – kasperd Aug 16 '14 at 12:52
  • @kasperd I agree. However, it's futile to try to keep a TCP connection open in those cases. Therefore, I assumed the questioner is not facing those particular challenges. – aecolley Aug 16 '14 at 14:34
  • It is not futile if you control both endpoints and can upgrade them to a stack with MPTCP support. Additionally an application layer solution could be implemented on top of TCP without needing MPTCP. – kasperd Aug 16 '14 at 14:40