在vagrant + chef设置中使用带密码的ssh密钥

时间:2011-08-26 22:51:53

标签: git ssh chef vagrant

我有一个使用vagrant运行的vm,我正在使用Chef配置它。其中一个步骤涉及克隆git repo,但我的ssh-key(在我的主机上)上有一个密码。

当我运行vagrant up时,进程在git clone步骤失败,并出现以下错误:
Permission denied (publickey). fatal: The remote end hung up unexpectedly
(密钥已添加到主机上,带有密码)

我尝试使用ssh代理转发解决此问题,方法如下:
已将config.ssh.forward_agent = true添加到VagrantFile
在vm

上添加了Defaults env_keep = "SSH_AUTH_SOCK/etc/sudoers

现在,vagrant up在到达git clone部分时仍然失败,但如果我在此之后运行vagrant provision,它就会通过。我猜这是因为当vm启动并且没有重新加载时设置了ssh配置

我已经尝试在调整这两个设置后重新加载ssh,但这没有帮助。

知道如何解决这个问题吗?

感谢。

3 个答案:

答案 0 :(得分:10)

正如您所指出的那样,在初始运行期间更新sudoers为时已晚,无法有利于该运行,因为此时厨师已经在sudo下运行。

相反,我编写了一个hacky配方,找到要使用的相应ssh套接字并更新SSH_AUTH_SOCK环境以适应。它还会禁用严格的主机密钥检查,以便自动批准初始出站连接。

将此保存为在第一个ssh连接之前的任何时间执行的配方(使用Ubuntu进行测试但应与其他发行版一起使用):

Directory "/root/.ssh" do
  action :create
  mode 0700
end

File "/root/.ssh/config" do
  action :create
  content "Host *\nStrictHostKeyChecking no"
  mode 0600
end

ruby_block "Give root access to the forwarded ssh agent" do
  block do
    # find a parent process' ssh agent socket
    agents = {}
    ppid = Process.ppid
    Dir.glob('/tmp/ssh*/agent*').each do |fn|
      agents[fn.match(/agent\.(\d+)$/)[1]] = fn
    end
    while ppid != '1'
      if (agent = agents[ppid])
        ENV['SSH_AUTH_SOCK'] = agent
        break
      end
      File.open("/proc/#{ppid}/status", "r") do |file|
        ppid = file.read().match(/PPid:\s+(\d+)/)[1]
      end
    end
    # Uncomment to require that an ssh-agent be available
    # fail "Could not find running ssh agent - Is config.ssh.forward_agent enabled in Vagrantfile?" unless ENV['SSH_AUTH_SOCK']
  end
  action :create
end

或者创建一个包含sudoers update的框,并将未来的VM作为其基础。

答案 1 :(得分:3)

这可能不是您正在寻找的答案,但对此的一个简单解决方法是生成一个没有密码短语的专用部署ssh密钥。我更喜欢单独的专用部署密钥,而不是单个密钥用于多个应用程序。

答案 2 :(得分:2)

您可以使用Vagrant(即使是同一类型)运行多个配置程序,每个配置程序都可以在自己的SSH连接上执行。我通常使用在vm上将Added Defaults env_keep = "SSH_AUTH_SOCK"添加到/etc/sudoers的Shell配置程序来解决此问题。

这是我用来做的Bash脚本:

#!/usr/bin/env bash

# Ensure that SSH_AUTH_SOCK is kept
if [ -n "$SSH_AUTH_SOCK" ]; then
  echo "SSH_AUTH_SOCK is present"
else
  echo "SSH_AUTH_SOCK is not present, adding as env_keep to /etc/sudoers"
  echo "Defaults env_keep+=\"SSH_AUTH_SOCK\"" >> "/etc/sudoers"
fi

我没有使用Chef配置程序对此进行测试,只是使用了其他Shell配置程序......但据我所知,这对于您的用例应该是相同的。