如何将自己的公钥添加到 Vagrant VM?
Posted
技术标签:
【中文标题】如何将自己的公钥添加到 Vagrant VM?【英文标题】:How do I add my own public key to Vagrant VM? 【发布时间】:2015-07-16 12:20:59 【问题描述】:我在向 Vagrant VM 添加 ssh 密钥时遇到问题。基本上我在这里的设置工作正常。创建虚拟机后,我可以通过vagrant ssh
访问它们,用户“vagrant”存在并且authorized_keys
文件中有该用户的ssh 密钥。
我现在想做的是:能够通过ssh
或使用scp
连接到这些虚拟机。所以我只需要将我的公钥从id_rsa.pub
添加到authorized_keys
- 就像我对ssh-copy-id
所做的那样。
有没有办法在设置过程中告诉 Vagrant 应该包含我的公钥?如果不是(根据我的谷歌结果,这很可能),有没有办法在 vagrant 设置期间轻松附加我的公钥?
【问题讨论】:
【参考方案1】:您可以使用 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
附加到vagrant 和root 用户的~/.ssh/authorized_keys
,这将允许您使用现有的SSH 密钥。
【讨论】:
很好,它可以工作,但它会在每个规定中添加一行,可能会执行多次。 我投票拒绝major addition to this answer - 因为应该添加该添加作为它自己的答案。 @user76329(如果您回来阅读此内容)应将其添加为单独的答案。 @sekrett 如果您希望 shell 供应商只运行一次,这里有一个解决方案:blog.ouseful.info/2015/07/27/… 基本上您创建一个文件标志来标记供应已经发生。 我需要添加等效的:mkdir ~/.ssh && touch authorized_keys @sekrett 对于幂等性,Ansible 为您提供更好的服务,shell 只能做这么多。 docs.ansible.com/ansible/latest/modules/…【参考方案2】:复制所需的公钥将直接进入provisioning 阶段。确切的答案取决于您喜欢使用的配置(shell、Chef、Puppet 等)。最简单的方法是为密钥提供 file
供应商,类似以下内容:
config.vm.provision "file", source: "~/.ssh/id_rsa.pub", destination: "~/.ssh/me.pub"
好吧,实际上您需要附加到授权密钥。使用 shell 配置器,如下所示:
Vagrant.configure(2) do |config|
# ... other config
config.vm.provision "shell", inline: <<-SHELL
cat /home/vagrant/.ssh/me.pub >> /home/vagrant/.ssh/authorized_keys
SHELL
# ... other config
end
您还可以使用真正的供应商,例如Puppet。例如参见Managing SSH Authorized Keys with Puppet。
【讨论】:
感谢您的回答 - 这是我需要的推动:) 我认为 Vagrant 可能会提供一些东西,但通过配置它是可能的。也许有点“丑陋”,但它就像一个魅力。基本上我只是按照您的建议复制文件,然后使用 shell 配置程序附加密钥。virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
@tehK 上面的评论中隐藏了 unicode 字符(i
s 之前)可能会毁了你的下午 - 这是一个固定的副本/可粘贴版本virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
这个解决方案效果很好!非常感谢:)
对不起,我来晚了。什么是 config.vm.provision?
不要硬编码~/.ssh/id_rsa.pub
。而是从ssh-add -L
获取密钥。【参考方案3】:
有一种更“优雅”的方式来完成您想做的事情。您可以找到现有的私钥并使用它,而不必费力添加公钥。
像这样继续查看现有私钥的路径(查看下面的 IdentityFile):
运行
vagrant ssh-config
结果:
$ vagrant ssh 配置 主机 magento2.vagrant150 主机名 127.0.0.1 用户无业游民 端口 3150 UserKnownHostsFile /dev/null StrictHostKeyChecking 否 密码验证无 身份文件“/Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key” 身份只有是 日志级别致命那你就可以这样使用私钥了,还要注意关闭密码认证的开关
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:连接被远程主机关闭。现在我什至无法在 vagrant up 上获得身份验证错误。它说在尚未准备好进行访客通信的机器上尝试了特定于访客的操作。这不应该发生,但应该报告。 确实非常漂亮。我会继续这样做。有些人可能会考虑使用 Include 语句将生成的 ssh 配置添加到他们的默认 ~/.ssh/config 中,以避免每次运行 ssh 时都使用 -i 和 -F 开关。明确地说, vagrant ssh-config > ~/.ssh/vagrant-ssh ; echo 包括 vagrant-ssh > ~/.ssh/config ;现在您可以毫不费力地 ssh yourvm。【参考方案4】:user76329 在rejected Suggested Edit 中添加了这个出色的答案
扩展Meow's example,我们可以复制本地的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
【讨论】:
对于那些配置到 OpenBSD 的用户,您需要grep -xsq
才能使 grep 命令正常工作。【参考方案5】:
更短更正确的代码应该是:
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 通常寿命短,所以不是大问题。
【讨论】:
我必须在第一行之后添加config.vm.provision 'shell', inline: "mkdir -p /root/.ssh"
,因为文件夹不存在
@geekQ 我使用ssh-copy-id
,所以它总是为我创建的,但为其他人创建它更正确。我会编辑,谢谢。【参考方案6】:
我最终使用如下代码:
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 box 不使用 vagrant
用户名。
【讨论】:
非常好的答案。帮了我很多。但是我有一些设置可以调整vagrant.d
目录的存储位置,所以我调整了你的配置来处理这样的情况。详情here.【参考方案7】:
这是一个很好的帖子,帮助我解决了与原始海报描述的类似情况。
虽然我最终使用了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
【讨论】:
【参考方案8】:虽然有些帖子很接近,但没有一篇旧帖子对我有用。我必须在终端中使用 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|
...
【讨论】:
【参考方案9】:对于内联 shell 配置程序 - 公钥包含空格、cmets 等是很常见的。因此请确保在扩展为公钥的 var 周围加上(转义)引号:
config.vm.provision 'shell', inline: "echo \"#ssh_pub_key\" >> /home/vagrant/.ssh/authorized_keys", privileged: false
【讨论】:
【参考方案10】:一个非常完整的例子,希望这对接下来访问的人有所帮助。将所有具体值移至外部配置文件。 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】: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 ~]$
【讨论】:
【参考方案12】:为vagrant身份验证生成rsa密钥对ssh-keygen -f ~/.ssh/vagrant
您可能还想将 vagrant 身份文件添加到您的 ~/.ssh/config
IdentityFile ~/.ssh/vagrant
IdentityFile ~/.vagrant.d/insecure_private_key
由于某种原因,我们不能只指定要插入的键,所以我们采用 一些额外的步骤来自己生成密钥。这样我们就可以得到安全和 确切知道我们需要哪个密钥(+ 所有 vagrant box 都将获得相同的密钥)
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
壳
【讨论】:
以上是关于如何将自己的公钥添加到 Vagrant VM?的主要内容,如果未能解决你的问题,请参考以下文章