youatwork@officepc$ autossh -R 12345:localhost:22 notroot@serverpc
Later:
you@homepc$ autossh -L 23456:localhost:12345 notroot@serverpc
you@homepc$ ssh youatwork@localhost -p 23456
What you could do is this: in step 1 forward a remote port from the office PC to the server (12345
is used as an example, any port >1024 should do). Now connecting to 12345 on the server should connect you to port 22 on officepc.
In step 2, forward the port 23456 from your home machine to 12345 on the server (whence it gets forwarded to officepc:22, as set up in step 1)
In step 3, you connect to the local port 23456 with your office PC login. This is forwarded by step 2 to port 12345 on your server, and by step 1 to your office PC.
Note that I'm using autossh for the forwardings, as it's a ssh wrapper which automatically reconnects the tunnel should it be disconnected; however normal ssh would work as well, as long as the connection doesn't drop.
There is a possible vulnerability: anyone who can connect to localhost:12345 on serverpc can now connect to officepc:22, and try to hack into it. (Note that if you're running a SSH server, you should anyway secure it above the basic protections which are on by default; I recommend at least disabling root login and disabling password authentication - see e.g. this)
Edit: I have verified this with the same config, and it works. GatewayPorts no
only affects the ports that are open to the world at large, not local tunnels. This is what the forwarded ports are:
homepc:
outgoing ssh to serverpc:22
listening localhost:23456 forwarded through ssh tunnel
serverpc:
listening ssh at *:22
incoming localhost ssh tunnel (from homepc) forwarded to localhost:12345
listening localhost ssh tunnel (from officepc) forwarded from localhost:12345
officepc:
outgoing ssh to serverpc:22
incoming localhost through ssh tunnel (from serverpc) forwarded to localhost:22
So, as far as the network stack is concerned, it's all local traffic on the respective loopback interfaces (plus ssh connections to serverpc); therefore, GatewayPorts
is not checked at all.
There is, however, the directive AllowTcpForwarding
: if that is no
, this setup will fail as no forwarding is allowed at all, not even across the loopback interface.
Caveats:
if using autossh and recent ssh, you may want to use ssh's ServerAliveInterval
and ServerAliveCountMax
for keeping the tunnel up. Autossh has a built-in check, but apparently it has some issues on Fedora. -M0
disables that, and -oServerAliveInterval=20 -oServerAliveCountMax=3
checks if the connection is up - tries each 20 sec, if it fails 3x in a row, stops ssh (and autossh makes a new one):
autossh -M0 -R 12345:localhost:22 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
autossh -M0 -L 23456:localhost:12345 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
it might be useful to restart ssh tunnel if the forward fails, using -oExitOnForwardFailure=yes
- if the port is already bound, you might get a working SSH connection, but no forwarded tunnel.
using ~/.ssh/config
for the options (and ports) is advisable, else the command lines get too verbose. For example:
Host fwdserverpc
Hostname serverpc
User notroot
ServerAliveInterval 20
ServerAliveCountMax 3
ExitOnForwardFailure yes
LocalForward 23456 localhost:12345
Then you can use just the server alias:
autossh -M0 fwdserverpc
on Home server (tunnel from third party to home):
ssh -R 20000:127.0.0.1:22 thirdparty.org
This connects your home box to the third party shell, and then starts to forward any connections to port 20000 on the third party shell to port 22 on your home box (the SSH port).
On remote computer (tunnel from remote to third party):
ssh -L 20000:127.0.0.1:20000 thirdparty.org
This connections your remote box to the third party shell, and then starts to foward port 20000 on the remote box to port 20000 on the third party shell.
and then on remote computer (connect over tunnels):
ssh 127.0.0.1:20000
and enter in credentials for your home server
This will attempt to ssh to port 20000 on the remote box. Since we set up a tunnel to the third party, the #2 command effectively forwards this connection attempt to 127.0.0.1:20000 on the third party shell. Then, the first command fowards the connection again to port 22 on your home box, at which point the ssh server picks up the connection.
Best Answer
You can do it easily, without any expense.
1) At home, get a (free) dns from no-ip.com. You will be given a name like
2) Set it up, either on your router or on your pc; this way, even if your ISP changes your IP address, the moniker above always points to your home. The site no-ip.com has instructions on how to do this.
3) in your router, forward ports 6521 and a port for ssh (2222?) to your pc.
4) At work: set up a reverse tunnel to the moniker above, at first with ssh, and just check it works;
5) now download autossh for your distro, a small wrapper which uses port 6521 (that's why!) to check that the connection is still active, and if it is not it kills the running instance of ssh and starts a new one.
Typically, I write an executable called auto with this content:
This sets up a passwordless ssh connection (see the use of the cryptographic key **id_rsa) without terminal (-N), in protocol 2 (-2), using port 6521 to check that the connection is still active, and redirecting to my home port 22 all that is sent to port 8400 at work.
I put this line
to execute the executable file auto in /etc/rc.local automatically at boot, as myself instead of root. I can now connect to my work pc with the command:
where I now have to use the passwordless key for work. I have found that this connection is always, always up. Truly satisfactory.