Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save shadiakiki1986/4aa8f128d816f31203e05fb8fbc2fabf to your computer and use it in GitHub Desktop.
Save shadiakiki1986/4aa8f128d816f31203e05fb8fbc2fabf to your computer and use it in GitHub Desktop.
ssh reverse tunnel into colab VM.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "ssh reverse tunnel into colab VM.ipynb",
"provenance": [],
"collapsed_sections": [],
"authorship_tag": "ABX9TyN6wTZ5owaJGgw+kx7loePb",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/shadiakiki1986/4aa8f128d816f31203e05fb8fbc2fabf/ssh-reverse-tunnel-into-colab-vm.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "wYEvw5BrRhFf",
"colab_type": "text"
},
"source": [
"This notebook illustrates how to use a ssh reverse tunnel [1] in order to ssh into a google colab VM.\n",
"It was inspired by the ssh forward tunnel idea from [2].\n",
"\n",
"ssh'ing into a google colab VM is useful to monitor GPU usage with `nvtop` while some GPU-based code is running.\n",
"Of course, it's also useful for running stuff in parallel in different screen sessions with `screen`,\n",
"but that's not really the goal of colab, and you're better off just renting your own VM on AWS.\n",
"\n",
"\n",
"Figure 1 shows what the configuration looks like for a forward tunnel\n",
"\n",
"```\n",
"Fig 1\n",
"colab ---> ngrok + sshd ---> public IP\n",
" ^\n",
" |\n",
" |--- ssh <--- local machine\n",
"```\n",
"\n",
"Figure 2 shows what the configuration looks like for a reverse tunnel\n",
"\n",
"```\n",
"Fig 2\n",
"colab ---> sshd + ssh reverse tunnel ----|-|\n",
" | |\n",
" v ^\n",
" public IP <--- sshd+ssh <--- local machine\n",
"```\n",
"\n",
"If local machine does not already have a public IP, then use ngrok or equivalent to get one.\n",
"\n",
"Note that this requires sshd to be running on the local machine as well.\n",
"\n",
"References:\n",
"\n",
"[1] https://www.howtogeek.com/428413/what-is-reverse-ssh-tunneling-and-how-to-use-it/\n",
"\n",
"[2] https://stackoverflow.com/questions/48459804/how-can-i-ssh-to-google-colaboratory-vm#48465924"
]
},
{
"cell_type": "code",
"metadata": {
"id": "20oFfIHGTLss",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 751
},
"outputId": "8e5ccce2-8627-424f-f3c1-1786b2ca4871"
},
"source": [
"#Setup sshd\n",
"# Will yield the below messages, but doesn't matter since we launch sshd manually below\n",
"# > invoke-rc.d: could not determine current runlevel\n",
"# > invoke-rc.d: policy-rc.d denied execution of start.\n",
"! apt-get install -qq -o=Dpkg::Use-Pty=0 openssh-server > /dev/null\n",
"\n",
"#Set root password\n",
"! mkdir -p /var/run/sshd\n",
"! echo \"PermitRootLogin yes\" >> /etc/ssh/sshd_config\n",
"\n",
"# some configurations for GPU stuff\n",
"! echo \"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64-nvidia\" >> /root/.bashrc\n",
"! echo \"export LD_LIBRARY_PATH\" >> /root/.bashrc\n",
"\n",
"#Run sshd\n",
"!/usr/sbin/sshd # will daemonize\n",
"!ssh-keygen -f ~/.ssh/id_rsa -t rsa -N \"\"\n",
"print(\"\"\"Copy below public key to local machine with:\n",
"echo '...' >> .ssh/authorized_keys (replace ellipsis with value below)\"\"\")\n",
"!cat ~/.ssh/id_rsa.pub\n",
"input(\"Press Enter to continue...\")\n",
"\n",
"# get local machine public key\n",
"!echo \"Copy public key from local machine (cat ~/.ssh/id_rsa.pub)\"\n",
"import getpass\n",
"local_pubkey = getpass.getpass()\n",
"!echo $local_pubkey >> /root/.ssh/authorized_keys\n",
"\n",
"# get local machine public IP and username\n",
"!echo \"Public URL for local machine:\"\n",
"local_puburl = input()\n",
"!echo \"Username for local machine:\"\n",
"local_username = input()\n",
"sshcmd = \"ssh -fN -R 43022:localhost:22 -T -o StrictHostKeyChecking=no $local_username@$local_puburl\"\n",
"get_ipython().system_raw(sshcmd)\n",
"\n",
"print(\"\"\"You can ssh into colab VM from the local machine with:\n",
"ssh -p 43022 root@localhost\n",
"\n",
"Note that 'root' is the username on the colab VM, not on the local machine\n",
"\"\"\")"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"\n",
"Creating config file /etc/ssh/sshd_config with new version\n",
"Creating SSH2 RSA key; this may take some time ...\n",
"2048 SHA256:oCYF7Dh1VNX+vMuz+hFEq1pX1HEwLh49PVp3RAjr6nA root@1b9999f733b0 (RSA)\n",
"Creating SSH2 ECDSA key; this may take some time ...\n",
"256 SHA256:v9lN+ZewaJ6M3PRbA5jQyshEBTCpZ+Ndr+RPwbjcsc8 root@1b9999f733b0 (ECDSA)\n",
"Creating SSH2 ED25519 key; this may take some time ...\n",
"256 SHA256:yulUjevATlpCnQkQNn81mIY7oFDaDiZtgsHVjtBp2L8 root@1b9999f733b0 (ED25519)\n",
"Created symlink /etc/systemd/system/sshd.service → /lib/systemd/system/ssh.service.\n",
"Created symlink /etc/systemd/system/multi-user.target.wants/ssh.service → /lib/systemd/system/ssh.service.\n",
"invoke-rc.d: could not determine current runlevel\n",
"invoke-rc.d: policy-rc.d denied execution of start.\n",
"Generating public/private rsa key pair.\n",
"Created directory '/root/.ssh'.\n",
"Your identification has been saved in /root/.ssh/id_rsa.\n",
"Your public key has been saved in /root/.ssh/id_rsa.pub.\n",
"The key fingerprint is:\n",
"SHA256:Xk0XVs81HnDddZOJ/Yk0juBCwYJ9rxdvH8hzRFJ4WiY root@1b9999f733b0\n",
"The key's randomart image is:\n",
"+---[RSA 2048]----+\n",
"| o ... oo**@|\n",
"| . o + . E Xo*X|\n",
"| + o . & +.=|\n",
"| . + = = ..|\n",
"| S = + |\n",
"| o o * o |\n",
"| o . + . |\n",
"| . |\n",
"| |\n",
"+----[SHA256]-----+\n",
"MANUALLY copy below public key to local machine with:\n",
"echo '...' >> .ssh/authorized_keys (replace ellipsis with value below)\n",
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvHGAUhNaIoSLocLBgIh0fxQB3YqoS+1MeEAkCeafrRTBgKqsCSu69q9c4l2fjJ2bgt+rTwTuk3l7z4/GhWIdaZbyENPSZmpj3XOxpwuMV9n1Jw6YIbcCdoNBXnUoDcrMQJCVn/vi4AnIGnBo3p9z+sUWgV/uS1kNjvMtk9JoY6vUWfPXDd/c3B+OfEoP2dIH463N4kQwqF8Be83Y8b0wfYMmpKlIQS2yPwiUMP1/ZvFa0QMb5rZb0uN4oRCftHCVUrcv8JOx0Vx+A/t9HYa8YkldY3EBq9p+US1GUG9wjP5dnTJlBHNtNSLoLZx2up0eMGIxOc18Y3A36ty8+0zJZ root@1b9999f733b0\n",
"Press Enter to continue...\n",
"MANUALLY copy public key from local machine (cat ~/.ssh/id_rsa.pub)\n",
"··········\n",
"Public URL for local machine:\n",
"bioinfo.lau.edu.lb\n",
"Username for local machine:\n",
"shady.akiki\n",
"You can ssh into colab VM from the local machine with:\n",
"ssh -p 43022 root@localhost\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "jG8uMRYKU-hs",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 68
},
"outputId": "285a61b3-7bec-449a-fecf-675ae4c0a293"
},
"source": [
"# kill some daemon processes if needed to restart them\n",
"#!kill -9 855\n",
"#!ps aux|grep ssh\n",
"#!ps aux|grep ngrok\n",
"#!ps aux|grep sshd"
],
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"text": [
"root 695 0.0 0.0 95524 5144 ? Ss 05:34 0:00 /usr/sbin/sshd\n",
"root 1160 0.0 0.0 39192 6544 ? S 05:56 0:00 /bin/bash -c ps aux|grep ssh\n",
"root 1162 0.0 0.0 38572 5024 ? S 05:56 0:00 grep ssh\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "gwmygh_ve9Ya",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 198
},
"outputId": "10ed9f45-472f-4db3-cc23-4df2e407a5d5"
},
"source": [
"# run \"top\" in ssh session and see usage\n",
"for i in range(1, 1000000000):\n",
" pass"
],
"execution_count": 11,
"outputs": [
{
"output_type": "error",
"ename": "KeyboardInterrupt",
"evalue": "ignored",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-11-d776bd0c47e6>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# run \"top\" in ssh session and see usage\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1000000000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment