"Invite" someone to ssh into your machine without port forwarding or firewall changes

If you want to let someone log into your machine or you want to log back into your machine from your server for some reason, normally you'd just set up port forwarding and connect to your IP.

But there is another way: you can use ssh to create a connection to a remote machine, which that person can then use to log into your machine.

Advantages:

  • No need to set up port forwarding if you're on a network.
  • No need to allow incoming connections in your firewall.
  • Works when you can't change router or firewall settings.
  • User can only log in when you start the connection (if it's blocked otherwise).
  • The other user doesn't need to know your IP (e.g. in case it's dynamic).

Disadvantages:

  • User can only log in when you start the connection.
  • You must be able to ssh log into the remote machine

It's not a replacement for normal ssh, but it's useful in some situations.

How to do it?

The first time:

  • Make sure an ssh server is installed on your machine, e.g.:
sudo apt-get install openssh-server
sudo service sshd restart
  • Make sure the server is properly secured - there's a lot of information online.
  • Make sure there is an account for the user to log into. Note you can log into your own machine to test:
ssh -l username localhost

To connect:

  • Open the connection to remote_machine that the other user will connect through:
ssh -R 2020:localhost:22 -l remote_username remote_machine

Here 2020 can be any port on the remote machine (<1024 are privileged though), which you can choose freely, but it should be the same in the next step. 22 is the local ssh server port, which is 22 by default but can be changed.

  • Log in to your machine from the remote machine:
ssh -l local_login -p 2020 localhost

Tunnel as jump node

Say you're on Desktop, you open a tunnel to JumpNode and want Server to log in to Desktop through JumpNode. An uncommon but useful scenario: Server is a backup server, for which you don't want to store login credentials on your Desktop in case it's compromised.

From the command line, you can do this directly from Server:

ssh -t JumpNode ssh Desktop

In this case, JumpNode needs to have an ssh IdentityFile for Desktop, or you need to enter a password.

If you want to do it in one command, e.g. so you can use scp or rsync, it works a bit differently. You need to edit ~/.ssh/config (or equivalent) on Server in one of two ways. For recent (7.3+) versions of openssh (ssh -V) you can use the easy ProxyJump way:

Host JumpNode
    Hostname jumpnode.domain.ext
    Port 22
    User jump_node_user
    IdentityFile ~/.ssh/keys/jumpnode

Host Desktop
    HostName localhost
    Port 2020
    User desktop_user
    ProxyJump JumpNode

For older versions, you can use ProxyCommand:

Host JumpNode
    # The same as above

Host Desktop
    Hostname localhost
    Port 2020
    User desktop_user
    ProxyCommand ssh -W %h:%p JumpNode
    IdentityFile ~/.ssh/keys/rafiki

Note that there's no need to use netcat, which is suggested on various websites.

A notable difference in this case, as compared to the command line one, is that the Server's IdentityFile for Desktop is used. Remember that before, JumpNode was the one that had to know how to get into Desktop.

The reason for this is that they work differently: the command line connects to JumpNode, then starts an ssh connection inside that which connects to Desktop, whereas ProxyCommand just establishes a connection from the Server through JumpNode to Desktop, through which another ssh session will then connect to Desktop. This is also why there is no username: authentication happens at the level of the final ssh connection, not the proxy level.

Let's hope ProxyJump will soon be available everywhere!

Comments

Mark

Added details about how to use the established tunnel in a jump node!

You need to be logged in to comment.