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


81

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

我现在想做的是:能够通过ssh或使用连接到这些VM scp。因此,我只需要将公钥从添加id_rsa.pubauthorized_keys-就像使用那样ssh-copy-id

有没有办法在设置过程中告诉Vagrant我的公钥应该包括在内?如果没有(根据我的Google搜索结果,这很可能),有没有办法在流浪汉安装过程中轻松地附加我的公钥?

Answers:


53

复制所需的公钥将直接进入供应阶段。确切的答案取决于您喜欢使用哪种配置(shell,Chef,Puppet等)。最简单的是file密钥的预配器,与此类似:

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

好吧,实际上您需要附加到authorized_keys。使用shell供应器,如下所示:

config.vm.provision "shell", inline: <<-SHELL
  cat /home/vagrant/.ssh/me.pub >> /home/vagrant/.ssh/authorized_keys
SHELL
end

您还可以使用真正的供应商,例如Puppet。例如,请参阅使用Puppet管理SSH授权密钥


8
感谢您的回答-这就是我需要的轻推:)我想也许Vagrant会提供一些东西,但是通过配置是可能的。也许有点“丑陋”,但是它就像一个魅力。基本上,我只是按照您的建议复制文件,然后使用Shell Provisioner附加密钥。 virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
2015年

6
@tehK在上面的注释中(在is之前)隐藏了unicode字符,它们可能会破坏您的下午-这是固定的副本/可粘贴版本virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
Aidan Kane

该解决方案效果很好!非常感谢您:)
Samir Patel

抱歉,我迟到了。什么是config.vm.provision?
user2568374

5
不要硬编码~/.ssh/id_rsa.pub。从那里获取密钥ssh-add -L
帖木儿

72

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

  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

此工作示例同时附加~/.ssh/id_rsa.pub~/.ssh/authorized_keys无业游民和root用户的,这将允许您使用现有的SSH密钥。


2
好的,它可以工作,但是会在每条规定上添加一行,这可能会执行多次。
sekrett '16

2
我投票拒绝对该答案进行重大补充-因为应该将其添加为自己的答案。@ user76329(如果您再次读过此书)应改为将其添加为单独的答案。
HPierce '16

1
@sekrett如果只想让Shell provisoner运行一次,这是一个解决方案:blog.ouseful.info/2015/07/27/…基本上,您创建一个文件标记来标记已经发生了provison。
rszalski

我需要添加以下内容:
mkdir〜

@sekrett对于幂等,Ansible可以更好地为您服务,shell只能做很多事情。 docs.ansible.com/ansible/latest/modules/…–
MGP

38

有一种更“优雅”的方式来完成您想做的事情。您可以找到现有的私钥并使用它,而不必麻烦添加公钥。

像这样继续以查看现有私钥的路径(在下面查看IdentityFile):

 流浪者ssh-config 

结果:

$ vagrant ssh-config
主机magento2.vagrant150
  主机名127.0.0.1
  用户无业游民
  港口3150
  UserKnownHostsFile / dev / null
  StrictHostKeyChecking否
  密码验证否
  IdentityFile“ /Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key”
  身份只有
  LogLevel致命

然后,您可以像这样使用私钥,还请注意用于关闭密码验证的开关

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

得到:ssh_exhange_identification:连接被远程主机关闭。现在我什至无法获得关于流浪汉的身份验证错误。它表示在尚未准备好进行来宾通信的计算机上尝试了特定于来宾的操作。这不应该发生,但是应该报告。
user2568374

13

user76329拒绝的“建议的编辑”中添加了这个出色的答案

Meow的示例上进行扩展,我们可以复制本地pub / private ssh密钥,设置权限并使内联脚本幂等(仅运行一次,并且仅在测试条件失败时才会重复,因此需要配置):

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

11

较短且更正确的代码应为:

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通常寿命很短,因此不是大问题。


1
config.vm.provision 'shell', inline: "mkdir -p /root/.ssh"由于文件夹不存在,我不得不在第一行之后添加
geekQ

@geekQ我使用ssh-copy-id,所以总是为我创建它,但是为其他人创建它更正确。我会编辑,谢谢。
sekrett

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用户名。


真的很好的答案。对我有很大帮助。但是我有一些设置可以调整vagrant.d目录的存储位置,因此我调整了配置以处理类似情况。详细信息在这里
Giacomo1968 '17

2

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

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

该解决方案的功劳归功于该编码器。

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|
        ...

1

这是一个极好的线索,可帮助我解决原始海报所描述的类似情况。

尽管我最终使用了smartwjw答案中提供的设置/逻辑,但由于使用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

1

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

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

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

-1

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 ~]$

-2

生成用于流浪身份验证的rsa密钥对 ssh-keygen -f ~/.ssh/vagrant

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

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

由于某些原因,我们不能只指定要插入的密钥,因此我们需要采取一些额外的步骤来自己生成密钥。这样,我们就可以获得安全性并确切地知道我们需要哪个密钥(+所有无用的盒子都将获得相同的密钥)

无法使用不安全的私钥(vagrant 1.7.2)SSH到vagrant VMs 如何将自己的公钥添加到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

贝壳

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.