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:

  1. 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:

  1. Connect via SSH from the remote container to your local computer

  2. 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.

Security precaution

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:

  1. Use SSH keys so that the capability of the container to create the connection can be easily and quickly turned off

  2. Restrict the command that the connection from container can invoke. This can be cone by prefixing command="/bin/cat to the public ssh key when it is added to the authorized_keys on the local computer. This ensures that SSH connection is only usable for the remote ports it forwards

Full recipe

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/

On the LOCAL: Add the remote public key to local authorised keys but restrict to the trivial command /bin/cat:

export remotekey="INSERT THE REMOTE KEY HERE"
echo command=\"/bin/cat\" $remotekey  >> ~/.ssh/authorized_keys

# Also print the local public key
cat ~/.ssh/

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

On the LOCAL: And finally do the forward connection:

ssh -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" root@localhost -p 9922