This is no better than ssh in a loop, which is trivially done by a shell script - no systemd needed.
However, when you have shitty NAT routers (SonicWall, any AT&T fiber device, for instance), the connections will be timed out or will die and there'll be long periods where you're waiting for the next iteration of the loop, and/or sometimes it'll get stuck and never try again.
autossh deals with this by actually passing traffic and taking action if traffic doesn't move.
This approach works very well. I've had dozens of extremely remote systems hooked up this way for about 8 years. The only problem I've seen is that occasionally the server ssh process will get stuck, so you have to log in to the server and kill it. It seems to happen when a remote goes offline and reconnects without closing the old connection first.
If I were doing it now, I'd probably use wireguard, probably. This is simpler to set up and works great.
> The only problem I've seen is that occasionally the server ssh process will get stuck, so you have to log in to the server and kill it.
You also need ClientAliveInterval on the server side (in addition to ServerAliveInterval on the client). In other words, both the client and the server need to be configured to monitor the connection. With this setup I had no issues with reconnections.
systemd's RuntimeMaxSec should help in this case but I've never had trouble with sshd personally
To add more context I use the above service to ssh from my phone to my laptop via my desktop PC. The service runs on my laptop and binds port 22 of my laptop to port 7070 of my PC but wiregaurd would probably work similarly
This is not very dissimilar from how the RIPE Atlas software probe (debian package) maintains a persistent SSH command/control session to the anchors and RIPE infrastructure. As I recall it installs itself as a systemd service.
No passphrase for the key?
What about spotty connection? Doesn't WantedBy block startup on this starting properly? (I'm pretty sure I've been soft locked out of my computer when Comcast decides to do Comcast things.
Ok now how to tell if the connection is running in the systemd status output? Cos this will show as active even when the connection is down or trying to reconnect.
exits (and so restarts) every 20min, e.g ensuring there's no hung sshd on the other side for longer than that.
IIRC if there's an active connection on the forwarding thingy, that ssh command won't exit until the forwarded connection is closed, so this won't interrupt an active forwarded connection every 20min.
It doesn't by default, but you can set the AUTOSSH_GATETIME environment variable to 0 so that autossh retries even if the first connection attempt fails.
14 years ago, i was using auto ash to keep SSH tunnels up; but at some point (quite far back - perhaps 2016?) ssh gained everything needed to do this internally except the restart.
At this point I configure all of the keep alive and retry options in ssh_config and sshd_config, and use
While true; do ssh user@host ; sleep 10; done
To get the same effect, but with much more flexibility - e.g. alternating connection addresses on a multihomed host, add logging, run from daemontools or systemd unit instead of a loop and let them track the process and restart, etc.
mosh is for interactive sessions, to keep them working when the connection is flaky.
autossh is for keeping unattended ssh tunnels alive, if the connection is flaky or one end is only intermittently available. So for using tunnels for the sort of thing you might otherwise use a VPN for.
If your concern is to have secure tunnels between hosts, you should probably use spiped rather than SSH, since it uses a separate TCP connection for each pipe -- this avoids the "connection dropped" problem and also the "multiplexing many connections over one TCP connection" performance hit.
Also, spiped is way simpler and more secure than SSH. (On my servers, I tunnel SSH over spiped, to protect the sshd from attacks.)
The last time I used autossh it was on a client site to keep 2 layers of ssh tunnels open to jump through their network isolation hoops.
In general, when flexibility is possible, such a use-case nowadays would often be better served by deploying WireGuard. Grouchy, out-of-touch corporate net admins probably don't even know what it is and insist on their antiquated Cisco VPNs.
However, when you have shitty NAT routers (SonicWall, any AT&T fiber device, for instance), the connections will be timed out or will die and there'll be long periods where you're waiting for the next iteration of the loop, and/or sometimes it'll get stuck and never try again.
autossh deals with this by actually passing traffic and taking action if traffic doesn't move.
The `ServerAliveInterval` option above achieves this.
If there are ServerAliveIntevalMaxCount (defaults to 3) attempts that fail, the ssh connection will drop. And systemd will restart it.
Today you learned. Nice. I've dropped autossh for years and you can too, even on flaky connections.
If I were doing it now, I'd probably use wireguard, probably. This is simpler to set up and works great.
So something like that would solve that
[Unit] Description=look ma, no autossh After=network.target
[Service] Type=exec ExecStart=/usr/bin/ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -Nn -R 7070:localhost:22 pc 'sleep 20m' Restart=always RestartSec=20 RuntimeMaxSec=30m
[Install] WantedBy=default.target
You also need ClientAliveInterval on the server side (in addition to ServerAliveInterval on the client). In other words, both the client and the server need to be configured to monitor the connection. With this setup I had no issues with reconnections.
systemd's RuntimeMaxSec should help in this case but I've never had trouble with sshd personally
To add more context I use the above service to ssh from my phone to my laptop via my desktop PC. The service runs on my laptop and binds port 22 of my laptop to port 7070 of my PC but wiregaurd would probably work similarly
https://atlas.ripe.net/docs/howtos/software-probes.html
you want ServerAliveCountMax too but default is 3.
IIRC if there's an active connection on the forwarding thingy, that ssh command won't exit until the forwarded connection is closed, so this won't interrupt an active forwarded connection every 20min.
autossh() {
Dead Comment
At this point I configure all of the keep alive and retry options in ssh_config and sshd_config, and use
To get the same effect, but with much more flexibility - e.g. alternating connection addresses on a multihomed host, add logging, run from daemontools or systemd unit instead of a loop and let them track the process and restart, etc.https://mosh.org/
autossh is for keeping unattended ssh tunnels alive, if the connection is flaky or one end is only intermittently available. So for using tunnels for the sort of thing you might otherwise use a VPN for.
https://github.com/blinksh/blink/discussions/1526
Deleted Comment
Also, spiped is way simpler and more secure than SSH. (On my servers, I tunnel SSH over spiped, to protect the sshd from attacks.)
This will set up a tunnel only when needed, and seems to play nicely with my browser.
In general, when flexibility is possible, such a use-case nowadays would often be better served by deploying WireGuard. Grouchy, out-of-touch corporate net admins probably don't even know what it is and insist on their antiquated Cisco VPNs.