This is an old revision of the document!
Loosely speaking, there are two types of IP addresses:
Public addresses can be uniquely identified in the Internet. Private addresses can't. Why not, you ask? Well… can you find the IP address assigned to your machine's network interface? Hint: ip addr show. That exact IP address is shared by millions of other devices, all across the world, in their respective local networks. When you initiate connections from your private network, the router performs a process called Network Address Translation (NAT) which uses a single Public IP to represent multiple Private IPs. Unless you have administrative access to said router (too add some custom configurations), clients outside your network will be unable to initiate contact with individual machines inside your network. And most times you don't…
In this exercise, we will set up what is called a reverse SSH tunnel. This tunnel is a persistent two-way communication channel between your computer and the gcloud instance. While this connection is initiated by you (from your private network, to a public server), someone on the other side can piggy back on this channel to initiate connections with you, in your private network. The reason for this is that it doesn't target your IP, specifically, in its request. In stead, it sends its request into the gcloud endpoint of the channel and it just so happens that the other endpoint is on your machine.
To get more specific, the goal is as follows:
If you don't do this, access from fep to your gcloud instance will be denied.
# create a public keypair on fep, if you don't already have one # create the .ssh directory (if not already there) [gcloud]$ mkdir -p ~/.ssh # print out your fep.grid.pub.ro public key and copy it [fep]$ cat ~/.ssh/id_rsa.pub # configure your fep.grid.pub.ro public key on gcloud instance [gcloud]$ vim ~/.ssh/authorized_keys
And now for the main part:
# create a reverse ssh tunnel from your computer to the cloud instance [localhost]$ ssh -T -N -R 43210:localhost:22 ${GCLOUD_USERNAME}@${GCLOUD_IP} # show tcp listeners (bound ports, processes, etc.) [gcloud]$ sudo netstat -tlpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:43210 0.0.0.0:* LISTEN 1931/sshd: ........ tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 448/systemd-resolve tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 893/sshd: /usr/sbin # test that the reverse ssh tunnel works [gcloud]$ ssh ${LOCALHOST_USERNAME}@localhost -p 43210 # connect from fep.grid.pub.ro to your localhost via gcloud instance [fep]$ ssh -J ${GCLOUD_USERNAME}@${GCLOUD_IP} ${LOCALHOST_USERNAME}@localhost -p 43210
Let's take a look at some of the arguments used in these commands:
ssh -T -N -R 43210:localhost:22 …
-T
: do not start a shell on the remote computer (we're not using the connection for that, remember?)-N
: do not execute one-shot commands either (combined with -T
, this makes ssh do nothing)-R 43210:localhost:22
: when logged in on the gcloud instance, writing data to port 43210 with itself (i.e.: localhost) intended as the destination, will ensure that the data actually ends up on whoever initiated the tunnel, on port 22 (the SSH server port).netstat -tlpn
t
: filter for TCP protocol (SSH actually runs over TCP)l
: show ports where processes are listening for new connectionsp
: show the PID and name of the program that is listeningn
: use numeric IP addresses in the outputssh -J ${GCLOUD_USERNAME}@${GCLOUD_IP} ${LOCALHOST_USERNAME}@localhost -p 43210
-J ${GCLOUD_USERNAME}@${GCLOUD_IP}
: create a SSH connection with google cloud as an intermediary hop; it acts like you'd SSH to google cloud, and there you would write another SSH command to your final destination.${LOCALHOST_USERNAME}@localhost
: “localhost” here is relative to the jump point (i.e.: google cloud instance), not to fep.-p 43210
: in stead of using the default SSH server port 22, pretend that it's in fact running on 43210.Reiterating over the last command, since it might still be a bit unclear:
-J
part)