Як додати свій власний відкритий ключ до Vagrant VM?


82

У мене виникла проблема з додаванням ключа ssh до віртуальної машини Vagrant. В основному налаштування, які я маю тут, чудово працюють. Після створення віртуальних машин я можу отримати до них доступ vagrant ssh, існує "vagrant" користувача і у authorized_keysфайлі є ключ ssh для цього користувача .

Що я хотів би зробити зараз, це мати можливість підключатися до цих віртуальних машин через sshабо використовувати scp. Тож мені потрібно було б лише додати свій відкритий ключ від id_rsa.pubдо authorized_keys- так само, як і з цим ssh-copy-id.

Чи є спосіб повідомити Vagrant під час налаштування, що мій містити мій відкритий ключ? Якщо ні (що, швидше за все, згідно з результатами мого Google), чи є спосіб легко додати мій відкритий ключ під час встановлення бродяги?

Відповіді:


55

Копіювання бажаного відкритого ключа буде прямо потрапляти у фазу забезпечення . Точна відповідь залежить від того, яке забезпечення ви бажаєте використовувати (оболонка, шеф-кухар, лялька тощо). Найбільш тривіальним буде fileпровізор для ключа, щось у цьому:

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

Ну, насправді вам потрібно додати до авторизованих ключів. Використовуйте провайдер оболонки приблизно так:

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

Ви також можете використовувати справжнього провізора, такого як Лялька . Наприклад, див. Керування авторизованими ключами SSH за допомогою маріонетки .


8
Дякую за вашу відповідь - це був підштовх, який мені потрібен :) Я думав, можливо, Vagrant щось надасть, але з наданням можливостей. Можливо, трохи «потворний», але це працює як шарм. В основному я просто копіюю файл, як ви запропонували, а потім використовую провайдер оболонки, щоб додати ключ. virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
техК

6
У коментарі @ tehK вище (перед is) є приховані символи унікоду, які можуть зіпсувати ваш день - ось виправлена ​​версія / копіювана версіяvirtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
Айдан Кейн,

Це рішення працювало чудово! Щиро дякую :)
Самір Патель

Вибачте, я спізнився на гру. Що таке config.vm.provision?
user2568374

5
Не жорстко кодуйте ~/.ssh/id_rsa.pub. Дістаньте ключі ssh-add -Lзамість цього.
Тимур

72

Ви можете використовувати основний модуль файлів Ruby, наприклад:

  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обох бродячого і кореневого користувача, що дозволить вам використовувати ваш існуючий ключ SSH.


2
Добре, і це працює, але він додасть рядок до кожного положення, яке може бути виконане кілька разів.
секретар

2
Я голосую за те, щоб відхилити основне доповнення до цієї відповіді - адже це доповнення має бути додане як власна відповідь. @ user76329 (якщо ви коли-небудь повернетесь читати це) повинен додати його як окрему відповідь.
HPierce

1
@sekrett Якщо ви хочете, щоб провайдер оболонки запускався лише один раз, ось одне рішення: blog.ouseful.info/2015/07/27/… В основному ви створюєте файл-прапор, щоб позначити, що підготовка вже відбулася.
rszalski

Мені потрібно було додати еквівалент: mkdir ~ / .ssh && touch санкціоновані_клавіші
Дуглас Денхартог,

@sekrett Для ідемпотенції вам краще послужити Ansible, оболонка може зробити лише стільки. docs.ansible.com/ansible/latest/modules/…
MGP

38

Існує більш "елегантний" спосіб досягнення того, що ви хочете зробити. Ви можете знайти існуючий приватний ключ і використовувати його, замість того, щоб переживати проблеми додавання свого відкритого ключа.

Продовжуйте так, щоб побачити шлях до існуючого приватного ключа (див. Нижче IdentityFile ):

бігти

 бродяга ssh-config 

результат:

$ vagrant ssh-config
Ведучий magento2.vagrant150
  Ім'я хосту 127.0.0.1
  Користувач-бродяга
  Порт 3150
  UserKnownHostsFile / dev / null
  StrictHostKeyCheck no
  Пароль Аутентифікаційний номер
  IdentityFile "/Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key"
  Тільки так
  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

Отримав: ssh_exhange_identification: З’єднання закрито віддаленим хостом. Тепер я навіть не можу отримати помилку автентифікації при бродяжництві. У ньому йдеться про спроби гостьових операцій на машині, яка не готова до гостьового зв'язку. Це не повинно відбуватися, а про це слід повідомляти.
user2568374

13

Це відмінний відповідь був доданий user76329 в відкинутого РЕКОМЕНДОВАНИЙ Edit

Розширивши приклад 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належатимуть кореневому користувачеві.

Тим не менше, він буде додавати рядок при кожному запуску забезпечення, але Vagrant використовується для тестування, і віртуальна машина зазвичай має короткий термін служби, тому не велика проблема.


1
Мені довелося додати config.vm.provision 'shell', inline: "mkdir -p /root/.ssh"після першого рядка, оскільки папка не існувала
geekQ

@geekQ я використовую ssh-copy-id, тому він завжди створюється для мене, але правильніше створювати його для інших. Редагуватиму, дякую.
секретар

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

2

Жоден зі старих постів не працював у мене, хоча деякі з них були близькі. Мені довелося зробити rsa-ключі з кейгеном у терміналі та користуватися власними ключами. Іншими словами, переможений від використання ключів Вагранта.

Станом на дату цього повідомлення я працюю в Mac OS Mojave. Я встановив два коробки Vagrant в одному файлі 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матеріалів каталогу на зовнішньому жорсткому диску в одній із моїх систем розробки.

Отже, ось скоригований код, який я використовую у своєму файлі Vagrant для розміщення 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

Для вбудованих постачальників оболонки - загальноприйнятим для відкритого ключа є пробіли, коментарі тощо. Тож переконайтеся, що навколо 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

Відповідь Мадіса Маєнні є найближчим до найкращого рішення:

просто зробіть:

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

З якоїсь причини ми не можемо просто вказати ключ, який ми хочемо вставити, тому ми робимо кілька додаткових кроків, щоб генерувати ключ самостійно. Таким чином ми отримуємо безпеку та знання, який саме ключ нам потрібен (+ усі бродяжні ящики отримають той самий ключ)

Не вдається ssh виграбувати віртуальні машини за допомогою незахищеного приватного ключа (vagrant 1.7.2) Як додати власний відкритий ключ до 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

ОБОРУДОВАТИ

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.