Hosted, dynamic containerised environments such as Google Colab are highly efficient and useful for many ad-hoc experiments and shorter data analyses. For many people the plain Jupyter Notebook-based + Google Drive interface will be fine.
Sometimes, however, a faster or more automated way of interfacing is needed. A general purpose SSH connection allows such flexible access (e.g., you can use emacs!) and here it is how it can be done without use of any third party services.
An important note first:
- You should determine for yourself if access to the container via SSH is acceptable use of whatever service you are using
The basic approach is simple:
Connect via SSH from the remote container to your local computer
Use port forwarding over this reverse connection to connect from your local computer to the remote container
This approach distinguishes it from others that are easily found on the internet which use third party services such as NGROK. A drawback of course is that your local computer or another you have access to has a internet-visible IP.
We need to enable an SSH connection from the container to the local computer. Since the container perhaps can not be trusted it is necessary to carefully restrict this connection:
Use SSH keys so that the capability of the container to create the connection can be easily and quickly turned off
Restrict the command that the connection from container can invoke. This can be cone by prefixing
command="/bin/catto the public ssh key when it is added to the
authorized_keyson the local computer. This ensures that SSH connection is only usable for the remote ports it forwards
On the REMOTE: In the Jupyter container install SSH and create a ssh key pair:
# Install and enable SSH server ! apt-get install -qq -o=Dpkg::Use-Pty=0 openssh-server > /dev/null ! mkdir -p /var/run/sshd ! echo "PermitRootLogin yes" >> /etc/ssh/sshd_config get_ipython().system_raw('/usr/sbin/sshd -D &') # Create a *remote* ssh key pair to allow a connection to local computer ! ssh-keygen -P "" -f /root/.ssh/id_rsa # Print the remote public key !cat /root/.ssh/id_rsa.pub
On the LOCAL: Add the remote public key to local authorised keys
but restrict to the trivial command
export remotekey="INSERT THE REMOTE KEY HERE" echo command=\"/bin/cat\" $remotekey >> ~/.ssh/authorized_keys # Also print the local public key cat ~/.ssh/id_rsa.pub
On the REMOTE: Add the local public key to remote authorised hosts, and set up the reverse SSH connection:
!cat "INSERT LOCAL PUBLIC SSH KEY HERE" >> /root/.ssh/authorized_keys # Note we are forwarding port # 9922 from localhost back to port 22 on remote !ssh -o "StrictHostKeyChecking no" -i /root/.ssh/id_rsa -R 9922:localhost:22 email@example.com
On the LOCAL: And finally do the forward connection:
ssh -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" root@localhost -p 9922