如何将自己的公钥添加到Vagrant VM?

时间:2015-05-06 11:31:14

标签: ssh vagrant public-key

我在向Vagrant VM添加ssh密钥时遇到了问题。基本上我在这里的设置工作正常。创建虚拟机后,我可以通过-endUpdates访问它们,用户“vagrant”存在,并且vagrant ssh文件中有该用户的ssh密钥。

我现在要做的是:能够通过authorized_keysssh连接到这些虚拟机。因此,我只需要将scp中的公钥添加到id_rsa.pub - 就像我使用authorized_keys一样。

有没有办法在设置过程中告诉Vagrant应该包含我的公钥?如果没有(根据我的谷歌搜索结果可能),有没有办法在流浪汉设置过程中轻松附加我的公钥?

12 个答案:

答案 0 :(得分:59)

您可以使用Ruby的核心文件模块,如下所示:

2.1.2 :021 > old_cart.bars
 => #<ActiveRecord::Associations::CollectionProxy [#<Bar id: 3, avatar: nil, created_at: "2015-07-01 05:57:47", updated_at: "2015-07-01 05:57:47", foo_id: 1>]> 

2.1.2 :022 > new_cart.bars
 => #<ActiveRecord::Associations::CollectionProxy [#<Bar id: 4, avatar: nil, created_at: "2015-07-01 05:59:07", updated_at: "2015-07-01 05:59:07", foo_id: 1>]> 

此工作示例将 config.vm.provision "shell" do |s| ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip s.inline = <<-SHELL echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys echo #{ssh_pub_key} >> /root/.ssh/authorized_keys SHELL end 附加到vagrant和root用户的~/.ssh/id_rsa.pub,这将允许您使用现有的SSH密钥。

答案 1 :(得分:37)

复制所需的公钥将完全属于provisioning阶段。确切的答案取决于您想要使用的配置(shell,Chef,Puppet等)。最简单的是密钥的file供应商,其中包括:

config.vm.provision "file", source: "~/.ssh/id_rsa.pub", destination: "~/.ssh/me.pub"

嗯,实际上你需要附加到authorized_keys,使用真正的配置器,如Puppet。例如,请参阅Managing SSH Authorized Keys with Puppet

答案 2 :(得分:33)

有一个更优雅的&#34;完成你想做的事的方式。您可以找到现有的私钥并使用它,而不是在添加公钥时遇到麻烦。

按以下步骤查看现有私钥的路径(请参阅下面的 IdentityFile ):

运行

 vagrant ssh-config 

结果:

$ vagrant ssh-config
Host magento2.vagrant150
  HostName 127.0.0.1
  User vagrant
  Port 3150
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile "/Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key"
  IdentitiesOnly yes
  LogLevel FATAL

然后你可以像这样使用私钥,还要注意关闭密码认证的开关

ssh -i /Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key -o PasswordAuthentication=no vagrant@127.0.0.1 -p 3150

答案 3 :(得分:9)

我最终使用的代码如下:

config.ssh.forward_agent    = true
config.ssh.insert_key       = false
config.ssh.private_key_path =  ["~/.vagrant.d/insecure_private_key","~/.ssh/id_rsa"]
config.vm.provision :shell, privileged: false do |s|
  ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
  s.inline = <<-SHELL
     echo #{ssh_pub_key} >> /home/$USER/.ssh/authorized_keys
     sudo bash -c "echo #{ssh_pub_key} >> /root/.ssh/authorized_keys"
  SHELL
end

请注意,我们不应硬编码/home/vagrant/.ssh/authorized_keys的路径,因为有些流浪盒不使用vagrant用户名。

答案 4 :(得分:8)

user76329

rejected Suggested Edit添加了这个优秀的答案

扩展Meow's example,我们可以复制本地pub / private ssh密钥,设置权限,并使内联脚本具有幂等性(运行一次,只有在测试条件失败时才会重复,因此需要配置):< / p>

config.vm.provision "shell" do |s|
  ssh_prv_key = ""
  ssh_pub_key = ""
  if File.file?("#{Dir.home}/.ssh/id_rsa")
    ssh_prv_key = File.read("#{Dir.home}/.ssh/id_rsa")
    ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
  else
    puts "No SSH key found. You will need to remedy this before pushing to the repository."
  end
  s.inline = <<-SHELL
    if grep -sq "#{ssh_pub_key}" /home/vagrant/.ssh/authorized_keys; then
      echo "SSH keys already provisioned."
      exit 0;
    fi
    echo "SSH key provisioning."
    mkdir -p /home/vagrant/.ssh/
    touch /home/vagrant/.ssh/authorized_keys
    echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys
    echo #{ssh_pub_key} > /home/vagrant/.ssh/id_rsa.pub
    chmod 644 /home/vagrant/.ssh/id_rsa.pub
    echo "#{ssh_prv_key}" > /home/vagrant/.ssh/id_rsa
    chmod 600 /home/vagrant/.ssh/id_rsa
    chown -R vagrant:vagrant /home/vagrant
    exit 0
  SHELL
end

答案 5 :(得分:7)

更短更正确的代码应该是:

ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
config.vm.provision 'shell', inline: 'mkdir -p /root/.ssh'
config.vm.provision 'shell', inline: "echo #{ssh_pub_key} >> /root/.ssh/authorized_keys"
config.vm.provision 'shell', inline: "echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys", privileged: false

否则用户的.ssh/authorized_keys将属于root用户。

仍然会在每次提供运行时添加一行,但是Vagrant用于测试,而VM通常寿命很短,所以这不是一个大问题。

答案 6 :(得分:1)

对于内联shell配置程序 - 公钥通常包含空格,注释等。因此,请确保在扩展为公钥的var周围放置(转义)引号:

config.vm.provision 'shell', inline: "echo \"#{ssh_pub_key}\" >> /home/vagrant/.ssh/authorized_keys", privileged: false

答案 7 :(得分:1)

尽管有些职位差一点,但没有一个较旧的职位为我工作。我必须在终端中使用keygen来制作rsa密钥,然后使用自定义密钥。换句话说,由于使用Vagrant的键而失败。

截至本文发布之日,我使用的是Mac OS Mojave。我在一个Vagrantfile中设置了两个Vagrant框。我正在显示所有第一个方框,以便新手可以看到上下文。我将.ssh文件夹与Vagrant文​​件放在同一文件夹中,否则使用user9091383设置。

此解决方案的信用额为this coder.

Vagrant.configure("2") do |config|
  config.vm.define "pfbox", primary: true do |pfbox|
        pfbox.vm.box = "ubuntu/xenial64"
        pfbox.vm.network "forwarded_port", host: 8084, guest: 80
        pfbox.vm.network "forwarded_port", host: 8080, guest: 8080
        pfbox.vm.network "forwarded_port", host: 8079, guest: 8079
        pfbox.vm.network "forwarded_port", host: 3000, guest: 3000
        pfbox.vm.provision :shell, path: ".provision/bootstrap.sh"
        pfbox.vm.synced_folder "ubuntu", "/home/vagrant"
        pfbox.vm.provision "file", source: "~/.gitconfig", destination: "~/.gitconfig"
        pfbox.vm.network "private_network", type: "dhcp"
        pfbox.vm.network "public_network"
        pfbox.ssh.insert_key = false
        ssh_key_path = ".ssh/"  # This may not be necessary.  I may remove.
        pfbox.vm.provision "shell", inline: "mkdir -p /home/vagrant/.ssh"
        pfbox.ssh.private_key_path = ["~/.vagrant.d/insecure_private_key", ".ssh/id_rsa"]
        pfbox.vm.provision "file", source: ".ssh/id_rsa.pub", destination: ".ssh/authorized_keys"
        pfbox.vm.box_check_update = "true"
        pfbox.vm.hostname = "pfbox"
        # VirtualBox
          config.vm.provider "virtualbox" do |vb|
            # vb.gui = true
            vb.name = "pfbox" # friendly name for Oracle VM VirtualBox Manager
            vb.memory = 2048 # memory in megabytes 2.0 GB
            vb.cpus = 1 # cpu cores, can't be more than the host actually has.
          end
  end
  config.vm.define "dbbox" do |dbbox|
        ...

答案 8 :(得分:0)

这是一个很好的主题,帮助我解决了原始海报所描述的类似情况。

虽然我最终使用了smartwjw’s回答中提供的设置/逻辑,但由于我使用VAGRANT_HOME环境变量将核心vagrant.d目录内容保存在外部,因此我遇到了麻烦我的一个开发系统上的硬盘驱动器。

所以这是我在Vagrantfile中使用的调整后的代码,以适应正在设置的VAGRANT_HOME环境变量; “神奇”发生在这一行vagrant_home_path = ENV["VAGRANT_HOME"] ||= "~/.vagrant.d"

config.ssh.insert_key = false
config.ssh.forward_agent = true
vagrant_home_path = ENV["VAGRANT_HOME"] ||= "~/.vagrant.d"
config.ssh.private_key_path = ["#{vagrant_home_path}/insecure_private_key", "~/.ssh/id_rsa"]
config.vm.provision :shell, privileged: false do |shell_action|
  ssh_public_key = File.readlines("#{Dir.home}/.ssh/id_rsa.pub").first.strip
  shell_action.inline = <<-SHELL
    echo #{ssh_public_key} >> /home/$USER/.ssh/authorized_keys
  SHELL
end

答案 9 :(得分:0)

Madis Maenni的答案最接近最佳解决方案:

只需:

vagrant ssh-config >> ~/.ssh/config
chmod 600 ~/.ssh/config

然后您可以通过主机名ssh。

获取〜/ .ssh / config中配置的主机名列表

grep -E '^Host ' ~/.ssh/config

我的例子:

$ grep -E '^Host' ~/.ssh/config
Host web
Host db
$ ssh web
[vagrant@web ~]$

答案 10 :(得分:0)

一个非常完整的示例,希望这对接下来访问的人有所帮助。将所有具体值移至外部配置文件。 IP分配仅供试用。

# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'
vmconfig = YAML.load_file('vmconfig.yml')

=begin
Script to created VMs with public IPs, VM creation governed by the provided
config file.
All Vagrant configuration is done below. The "2" in Vagrant.configure
configures the configuration version (we support older styles for
backwards compatibility). Please don't change it unless you know what
you're doing
Default user `vagrant` is created and ssh key is overridden. make sure to have
the files `vagrant_rsa` (private key) and `vagrant_rsa.pub` (public key) in the
path `./.ssh/`
Same files need to be available for all the users you want to create in each of
these VMs
=end

uid_start = vmconfig['uid_start']
ip_start = vmconfig['ip_start']
vagrant_private_key = Dir.pwd + '/.ssh/vagrant_rsa'
guest_sshkeys = '/' + Dir.pwd.split('/')[-1] + '/.ssh/'
Vagrant.configure('2') do |config|
  vmconfig['machines'].each do |machine|
    config.vm.define "#{machine}" do |node|
      ip_start += 1
      node.vm.box = vmconfig['vm_box_name']
      node.vm.box_version = vmconfig['vm_box_version']
      node.vm.box_check_update = false
      node.vm.boot_timeout = vmconfig['vm_boot_timeout']
      node.vm.hostname = "#{machine}"
      node.vm.network "public_network", bridge: "#{vmconfig['bridge_name']}", auto_config: false
      node.vm.provision "shell", run: "always", inline: "ifconfig #{vmconfig['ethernet_device']} #{vmconfig['public_ip_part']}#{ip_start} netmask #{vmconfig['subnet_mask']} up"
      node.ssh.insert_key = false
      node.ssh.private_key_path = ['~/.vagrant.d/insecure_private_key', "#{vagrant_private_key}"]
      node.vm.provision "file", source: "#{vagrant_private_key}.pub", destination: "~/.ssh/authorized_keys"
      node.vm.provision "shell", inline: <<-EOC
        sudo sed -i -e "\\#PasswordAuthentication yes# s#PasswordAuthentication yes#PasswordAuthentication no#g" /etc/ssh/sshd_config
        sudo systemctl restart sshd.service
      EOC
      vmconfig['users'].each do |user|
        uid_start += 1
        node.vm.provision "shell", run: "once", privileged: true, inline: <<-CREATEUSER
          sudo useradd -m -s /bin/bash -U #{user} -u #{uid_start}
          sudo mkdir /home/#{user}/.ssh
          sudo cp #{guest_sshkeys}#{user}_rsa.pub /home/#{user}/.ssh/authorized_keys
          sudo chown -R #{user}:#{user} /home/#{user}
          sudo su
          echo "%#{user} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/#{user}
          exit
        CREATEUSER
      end
    end
  end

答案 11 :(得分:-1)

为vagrant身份验证生成rsa密钥对ssh-keygen -f ~/.ssh/vagrant

您可能还想将流浪者身份文件添加到~/.ssh/config

IdentityFile ~/.ssh/vagrant
IdentityFile ~/.vagrant.d/insecure_private_key

出于某种原因,我们不能只指定我们要插入的键,所以我们采取了一个 我们自己生成密钥的额外步骤很少。这样我们就可以获得安全性 知道我们需要哪个密钥(+所有流浪盒将获得相同的密钥)

Can't ssh to vagrant VMs using the insecure private key (vagrant 1.7.2) How do I add my own public key to Vagrant VM?

config.ssh.insert_key = false
config.ssh.private_key_path = ['~/.ssh/vagrant', '~/.vagrant.d/insecure_private_key']
config.vm.provision "file", source: "~/.ssh/vagrant.pub", destination: "/home/vagrant/.ssh/vagrant.pub"
config.vm.provision "shell", inline: <<-SHELL
cat /home/vagrant/.ssh/vagrant.pub >> /home/vagrant/.ssh/authorized_keys
mkdir -p /root/.ssh
cat /home/vagrant/.ssh/authorized_keys >> /root/.ssh/authorized_keys

SHELL