我怎么能ssh到google colaboratory VM?

时间:2018-01-26 10:44:43

标签: ssh google-colaboratory

我如何ssh到谷歌合作VM?有没有比从jupyter笔记本到远程服务器创建ssh隧道更直接的方法呢?

5 个答案:

答案 0 :(得分:8)

这是另一种解决方案-本质上与@tamlyn提出的解决方案相同,但更短。有一个colab-ssh连接器,可自动执行该过程。您要做的就是在ngrok上注册一个免费帐户。然后,您需要复制auth token。现在,在目标Colab笔记本中:

# Install colab_ssh
!pip install colab_ssh --upgrade

from colab_ssh import launch_ssh
launch_ssh('YOUR_NGROK_AUTH_TOKEN', 'SOME_PASSWORD')

您应该获得连接参数(注意端口)。 现在,您可以使用提供的详细信息连接到Colab VM,例如:ssh -p 15892 root@0.tcp.ngrok.io,其中15892是您需要更改的随机端口号。当然,系统会提示您输入先前设置的密码。

这显然受到免费的ngrok帐户限制的限制,但对于小任务来说就足够了。

如果您获得IndexError: list index out of range,请不要担心。根据我的经验,它将仍然有效-您可以从ngrok active tunnels list获取端口和地址。

答案 1 :(得分:5)

尝试将以下内容粘贴到单元格中并运行它(受this gist的启发):

import random, string, urllib.request, json, getpass

#Generate root password
password = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(20))

#Download ngrok
! wget -q -c -nc https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
! unzip -qq -n ngrok-stable-linux-amd64.zip

#Setup sshd
! apt-get install -qq -o=Dpkg::Use-Pty=0 openssh-server pwgen > /dev/null

#Set root password
! echo root:$password | chpasswd
! mkdir -p /var/run/sshd
! echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
! echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
! echo "LD_LIBRARY_PATH=/usr/lib64-nvidia" >> /root/.bashrc
! echo "export LD_LIBRARY_PATH" >> /root/.bashrc

#Run sshd
get_ipython().system_raw('/usr/sbin/sshd -D &')

#Ask token
print("Copy authtoken from https://dashboard.ngrok.com/auth")
authtoken = getpass.getpass()

#Create tunnel
get_ipython().system_raw('./ngrok authtoken $authtoken && ./ngrok tcp 22 &')

#Get public address and print connect command
with urllib.request.urlopen('http://localhost:4040/api/tunnels') as response:
  data = json.loads(response.read().decode())
  (host, port) = data['tunnels'][0]['public_url'][6:].split(':')
  print(f'SSH command: ssh -p{port} root@{host}')

#Print root password
print(f'Root password: {password}')

ngrok用于创建到计算机的隧道,并为其提供可公开访问的主机名。您将需要注册,复制身份验证令牌,并在出现提示时将其提供给Colab笔记本。

完成后,它将打印出您的连接详细信息,例如:

SSH command: ssh -p12312 root@0.tcp.ngrok.io
Root password: abcdeLMh6vpNViGHQbXi

如果最后一步失败,请尝试再次运行该单元或仅使用以下内容创建一个新单元,并读取JSON输出以查找主机名和端口。

! curl -s http://localhost:4040/api/tunnels

答案 2 :(得分:1)

您可以使用!在笔记本中执行shell命令,例如:

!echo "Echo in shell"

目前不支持通过SSH直接连接到后端。

答案 3 :(得分:0)

This jupyter notebook说明了如何使用ssh反向隧道来做到这一点。

与先前的答案相比,ssh反向隧道方法具有以下差异:

  • 在colab VM上不需要ngrok
  • 仅当本地计算机上没有公共IP时,才需要在本地计算机上(您要从其上发送)ngrok
  • 需要在本地计算机上使用sshd

答案 4 :(得分:0)

从此gist

import random, string, urllib.request, json, getpass

#Generate root password
password = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(20))

#Download ngrok
! wget -q -c -nc https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
! unzip -qq -n ngrok-stable-linux-amd64.zip

#Ask token
print("Copy authtoken from https://dashboard.ngrok.com/auth")
authtoken = getpass.getpass()

#Create tunnel
get_ipython().system_raw('./ngrok authtoken $authtoken && ./ngrok tcp 22 &')

因此,现在已经建立了您的ngrok隧道(希望如此)。现在尝试安装ssh服务器。这注定要失败,但还是要这样做。

#Setup sshd
! sudo apt-get install openssh-server

由于上述命令失败,请运行此命令。

# if install fail run this, uncomment and run the below line
! sudo apt-get install openssh-server --fix-missing

现在运行此命令,这将对ssh config进行基本更改,以确保您能够在colab中进行远程登录。

#Set root password
! echo root:$password | chpasswd
! mkdir -p /var/run/sshd
! echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
! echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
! echo "LD_LIBRARY_PATH=/usr/lib64-nvidia" >> /root/.bashrc
! echo "export LD_LIBRARY_PATH" >> /root/.bashrc

现在,我们将尝试运行ssh-daemon

get_ipython().system_raw('/usr/sbin/sshd -D &')
# to check if ssh is running on port 22 or not or installed or not
! sudo apt install net-tools
! netstat -plant | grep ssh
! which sshd

最后两个命令的输出应为

/usr/bin/sshd 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN 1008/sshd

获取ssh配置和凭据

# get_ipython().system_raw('./ngrok authtoken $authtoken && ./ngrok tcp 22 &')
with urllib.request.urlopen('http://localhost:4040/api/tunnels') as response:
  data = json.loads(response.read().decode())
  (host, port) = data['tunnels'][0]['public_url'][6:].split(':')
  print(f'SSH command: ssh -p{port} root@{host}')
#Print root password
print(f'SSH password: {password}')

如果由于某种原因上述命令失败,请再次运行该命令,直到它生效