如何在不实际运行“vagrant ssh”的情况下通过ssh连接vagrant?

185

我想在一个 shell 脚本中使用 ssh 命令来复制 Vagrant 登录虚拟机的方式,因此我创建了一个别名到我的 Vagrant 实例。

如何使用普通的 ssh 命令访问它?


你实际上在问什么,我看到有三个不同的问题被问到了,也许你可以扩展一下问题,然后标记为迁移。谢谢。 - Kev
3
默认情况下,虚拟机的SSH端口(即22号端口)将被转发到主机上的2222端口。我使用Putty连接127.0.0.1和2222端口进行SSH,连接成功了! - Vishal Biyani
8
如果你在运行多个盒子,那么端口号将会自动更改。你可以通过运行 vagrant ssh-config 命令来获取正确的端口号。 - Stefano Palazzo
16个回答

211

已经有很多答案了,但它们似乎都过于复杂,或者解决了提问者没有的问题。

简单来说:

# save the config to a file
vagrant ssh-config > vagrant-ssh

# run ssh with the file.
ssh -F vagrant-ssh default

2
太棒了。能否在.gitignore中添加vagrant-ssh文件? - sashaegorov
7
对于一些shell(如zsh),以下的单行命令可以工作:ssh -F =(vagrant ssh-config) default - liori
9
你可以将以下结果追加到你的 ssh 配置文件中:vagrant ssh-config >> ~/.ssh/config,这样你只需在系统中任何地方运行 ssh default,其中 default 是你可以像这里所示指定的虚拟机名称。 - adamczi
谢谢@adamczi,这是一种简化的方法,也适用于自动化解决方案,在其中添加额外的ssh参数“-F”不是直接的。 - laimison
3
通过按照@adamczi的建议在~/.ssh/config中添加一个条目,您可以使用Visual Studio Code Remote - SSH扩展程序连接到Vagrant VM并进行远程开发。只需按CMD-SHIFT-P,然后选择“Remote-SSH:Connect to Host...”,您刚刚添加的ssh .config条目会自动列出-您只需选择它,就可以将vscode连接到您的远程vagrant vm!如果没有配置条目方法,我不确定如何使用vscode完成此操作。 - abulka
非常好的答案。超级简单。我遇到的唯一问题是我的编码有误。但一个简单的修复就解决了这个问题。https://dev59.com/tLPma4cB1Zd3GeqPnkS5 - Chris

114

因为“vagrant ssh”命令的-c选项不能正确传递参数,我不得不重新实现它。下面基本上就是它的功能(可能还有更多,但这样就能正常工作)

#!/bin/sh
PORT=$(vagrant ssh-config | grep Port | grep -o '[0-9]\+')
ssh -q \
    -o UserKnownHostsFile=/dev/null \
    -o StrictHostKeyChecking=no \
    -i ~/.vagrant.d/insecure_private_key \
    vagrant@localhost \
    -p $PORT \
    "$@"

作为一行代码(感谢kgadek):

ssh $(vagrant ssh-config | awk 'NR>1 {print " -o "$1"="$2}') localhost

为了适应有多个vagrant主机的情况,这将选择所需的主机,并从配置中删除空行(使用sed):

HOST=name-of-my-host
ssh $(vagrant ssh-config $HOST | sed '/^[[:space:]]*$/d' |  awk 'NR>1 {print " -o "$1"="$2}') localhost

5
这个回答的意思是,你不能从Vagrantfile目录外部使用普通的ssh命令连接到你的Vagrant。这也是我对问题的理解。 - sjy
那么,是什么使得该端口成为进入机器的途径?它的端口配置在哪里? - nroose
1
Vagrant选择一个未使用的端口,如果设置了auto_correct: true。这里有更多信息,介绍如何手动更改它。 (http://oddessay.com/development-notes/changing-vagrants-default-ssh-port-to-prevent-collision-when-resuming-a-suspended-instance) - Stefano Palazzo
1
我必须跳过第一行,即“Host”条目。修改后的命令是:ssh $(vagrant ssh-config | awk'NR>1 {print" -o"$1"="$2}')localhost - kgadek
这个一行代码正是我所需要的。我正在编写一个 tmuxinator 设置脚本,需要在多个窗格中登录到同一个 vagrant box,但 vagrant ssh 有一个全局锁 - 一次只能运行一个进程。ssh 本身没有这样的锁定,因此使用您的一行代码让我绕过了这个限制。 - henrebotha
显示剩余3条评论

71

在终端中运行

vagrant ssh

在另一个终端窗口/选项卡中运行

ps aux | grep ssh

在那里,您将看到Vagrant实际执行的命令,类似于这样:

ssh vagrant@127.0.0.1 -p 2222 -o Compression=yes -o DSAAuthentication=yes -o LogLevel=FATAL -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -i ~/.vagrant.d/less_insecure_private_key -o ForwardAgent=yes

如果您需要vagrant的主机进行其他操作,比如SQL GUI连接(例如Sequel Pro),以下是一个非常好的技巧。这个技巧真的帮了我大忙! - Atomox
1
所以你实际上只需要 ssh vagrant@IP -p PORT -i path/to/privatekey。这甚至比得票最高的答案还要简单。 - Aldian

20
只需将整个 vagrant ssh-config 作为配置文件传递给带有 -F configfile 参数的 ssh。要连接的主机别名在 vagrant ssh-config 的第一行中定义;Host default 表示您可以使用 ssh default 连接。
我看不到从标准输入读取配置文件的选项,所以选择了临时文件路线。以下是一个一行命令,还会清理临时的 $TMPDIR.vagrant-ssh-config 文件。假设您的 vagrant box 已经启动并正在运行,需要在与您的 Vagrantfile 相同的目录中执行该命令。
vagrant ssh-config > $TMPDIR.vagrant-ssh-config && ssh default -F $TMPDIR.vagrant-ssh-config ; rm $TMPDIR.vagrant-ssh-config

注意:在我的Mac OSX系统上,$TMPDIR会扩展为/var/folders/46/yltlhtgx8m5cg68_w95wgvy41324gn/T/(当前)。如果你的系统没有设置,请使用another variable或其他文件夹。

3
如果你正在使用bash或zsh,进程替换是将一个命令的输出传递给另一个命令的更简单的方法。bash: ssh -F <(vagrant ssh-config) zsh: zsh进程替换 ssh -F =(vagrant ssh-config) - myeeshen
根据@tyrion的回答(https://dev59.com/rGgv5IYBdhLWcg3wFsyl#20703044),在bash中,进程替换对于`ssh -F`不起作用-你提到的方法应该在zsh中有效。 - Joel Purra

18

我以非常简单的方式解决了这个问题: 当你启动vagrant box时,它会显示ssh地址,就像这样

SSH address: 127.0.0.1:2222

然后您可以使用vagrant用户、主机和端口连接到该框

ssh vagrant@127.0.0.1 -p 2222

3
好的!请注意,通常 vagrant 用户的密码是 vagrant - Brad Parks
只有在vagrant将ssh私钥添加到默认的ssh文件夹中,它才能正常工作,否则您将不得不在命令行中指定它。这将使类似于ssh vagrant@IP -p PORT -i /home/USER/WORKING_REP/.vagrant/machines/default/libvirt/private_key的东西。 - Aldian

11

您可以将vagrant主机配置添加到本地ssh配置中。

  1. vagrant ssh-config >> ~/.ssh/config

  2. ssh vagrant@{host}

例如:cat ~/.ssh/config

Host kmaster
  HostName 127.0.0.1
  User vagrant
  Port 2222..
  ....
  • ssh vagrant@kmaster

7

如果你不需要使用stdinssh(例如,你只想执行一个命令并退出),那么你可以使用:

vagrant ssh-config --host default | ssh -F /dev/stdin default

这个方法是在谷歌论坛上对一个类似问题提出的建议。

不幸的是,bash进程替换也不起作用(有关详细信息,请参见unix.stackexchange上的此问题)。

如果您想要一个交互式shell,则最好的选择是创建一个临时文件并将其与ssh -F一起使用,或者像其他答案所建议的那样使用awk


5
很多其他的回答都假设您已经安装了Vagrant。
我在Windows 10上已经安装了Vagrant,但是我无法使用“vagrant ssh”命令,因为我使用的是PuTTY作为我的SSH客户端,而Vagrant不支持它。
引用:“PATH中找到的ssh可执行文件是一个PuTTY Link SSH客户端。Vagrant只兼容OpenSSH SSH客户端。”
然而,在Windows 10中,我们也有适用于Ubuntu的Bash。因此,我只需使用以下命令:
ssh vagrant@127.0.0.1 -p2222 -i .vagrant/machines/default/virtualbox/private_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=Fatal

在Win10-Ubuntu上安装Vagrant很容易,但某些原因它还要求你安装Virtualbox,我不太想这样做。
注意:我已经尝试过使用“ssh默认-F vagrant-ssh-config”方法,但是我只得到“Permission denied (publickey, password)”错误提示。
我猜这是因为“IdentityFile”路径是Windows路径,而在Bash中,它应该以“/mnt/c/”开头。如果这对您更好的话,可以将文件写出并进行修改。

5

如果你只想设置使得你能使用普通的ssh命令行,以及scp等,你可以运行vagrant ssh-config并将输出附加到默认的ssh配置中。如果你用更详细的主机名替换“Host default”这一行,那么你就可以开始了。

vagrant ssh-config |sed -e "s/Host default/Host my_cool_dev_box/" >> ~/.ssh/config
ssh my_cool_dev_box

5
如果你只想使用最基本的命令连接到你的虚拟机,你需要知道它正在使用哪个端口(在执行“vagrant up”时打印,或者在执行“vagrant ssh-config”时可见),以及你的私钥位于何处(也可在执行“vagrant ssh-config”时看到)。
然后,只需要提供密钥和端口:
ssh -p 2222 -i $HOME/vagrantenv/.vagrant/machines/default/virtualbox/private_key vagrant@127.0.0.1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接