Wie füge ich Vagrant VM meinen eigenen öffentlichen Schlüssel hinzu?

82

Ich habe ein Problem beim Hinzufügen eines SSH-Schlüssels zu einer Vagrant-VM. Grundsätzlich funktioniert das Setup, das ich hier habe, gut. Sobald die VMs erstellt sind, kann ich über auf sie zugreifen vagrant ssh, der Benutzer "vagrant" existiert und es gibt einen SSH-Schlüssel für diesen Benutzer in der authorized_keysDatei.

Was ich jetzt tun möchte, ist: eine Verbindung zu diesen VMs herstellen sshoder diese verwenden zu können scp. Also brauchte ich nur meine öffentlichen Schlüssel hinzufügen , id_rsa.pubum die authorized_keys- genau wie ich mit machen würde ssh-copy-id.

Gibt es eine Möglichkeit, Vagrant während des Setups mitzuteilen, dass mein öffentlicher Schlüssel enthalten sein soll? Wenn nicht (was laut meinen Google-Ergebnissen wahrscheinlich ist), gibt es eine Möglichkeit, meinen öffentlichen Schlüssel während des Vagrant-Setups einfach anzuhängen?

tehK
quelle

Antworten:

55

Das Kopieren des gewünschten öffentlichen Schlüssels würde direkt in die Bereitstellungsphase fallen . Die genaue Antwort hängt davon ab, welche Bereitstellung Sie verwenden möchten (Shell, Chef, Puppet usw.). Am trivialsten wäre ein fileProvisioner für den Schlüssel, etwas in dieser Richtung:

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

Nun, eigentlich müssen Sie an authorized_keys anhängen. Verwenden Sie den Shell-Provisioner wie folgt:

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

Sie können auch einen echten Provisioner wie Puppet verwenden . Siehe beispielsweise Verwalten von SSH-autorisierten Schlüsseln mit Puppet .

Remus Rusanu
quelle
8
Vielen Dank für Ihre Antwort - das war der Anstoß, den ich brauchte :) Ich dachte, Vagrant würde vielleicht etwas liefern, aber mit der Bereitstellung ist es möglich. Vielleicht ein bisschen "hässlich", aber es funktioniert wie ein Zauber. Grundsätzlich kopiere ich die Datei nur wie von Ihnen vorgeschlagen und verwende dann den Shell-Provisioner, um den Schlüssel anzuhängen. virtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
Der
6
In @ tehKs Kommentar oben (vor dem is) sind Unicode-Zeichen versteckt , die Ihren Nachmittag ruinieren können - hier ist eine feste Kopie / pastable Versionvirtualhost.vm.provision "shell", inline: "cat ~vagrant/.ssh/me.pub >> ~vagrant/.ssh/authorized_keys"
Aidan Kane
Diese Lösung hat wunderbar funktioniert! Vielen Dank :)
Samir Patel
Entschuldigung, ich bin zu spät zum Spiel. Was ist config.vm.provision?
user2568374
5
Nicht fest codieren ~/.ssh/id_rsa.pub. Holen Sie sich ssh-add -Lstattdessen die Schlüssel von .
Timur
72

Sie können Rubys Kernmodul "Datei" wie folgt verwenden:

  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

Dieses Arbeitsbeispiel wird sowohl an den Benutzer des Vagabunden als auch an den Root-Benutzer angehängt ~/.ssh/id_rsa.pub, sodass ~/.ssh/authorized_keysSie Ihren vorhandenen SSH-Schlüssel verwenden können.

Miau
quelle
2
Gut und es funktioniert, aber es wird bei jeder Bestimmung eine Zeile hinzugefügt, die möglicherweise mehrmals ausgeführt wird.
sekrett
2
Ich stimme dafür, eine wichtige Ergänzung zu dieser Antwort abzulehnen - da diese Ergänzung als eigene Antwort hinzugefügt werden sollte. @ user76329 (falls Sie jemals zurückkommen, um dies zu lesen) sollte es stattdessen als separate Antwort hinzufügen.
HPierce
1
@sekrett Wenn Sie möchten, dass der Shell-Provisoner nur einmal ausgeführt wird, finden Sie hier eine Lösung: blog.ouseful.info/2015/07/27/… Grundsätzlich erstellen Sie ein Dateiflag , um zu markieren, dass die Provisonierung bereits stattgefunden hat.
Rszalski
Ich musste ein Äquivalent hinzufügen von: mkdir ~ / .ssh && autorisierte_Tasten berühren
Douglas Denhartog
@sekrett Für Idempotenz sind Sie mit Ansible besser bedient, Shell kann nur so viel. docs.ansible.com/ansible/latest/modules/…
MGP
38

Es gibt eine "elegantere" Möglichkeit, das zu erreichen, was Sie tun möchten. Sie können den vorhandenen privaten Schlüssel finden und verwenden, anstatt sich die Mühe zu machen, Ihren öffentlichen Schlüssel hinzuzufügen.

Gehen Sie folgendermaßen vor, um den Pfad zum vorhandenen privaten Schlüssel anzuzeigen (siehe unten für IdentityFile ):

Lauf

 vagrant ssh-config 

Ergebnis:

$ vagrant ssh-config
Host magento2.vagrant150
  Hostname 127.0.0.1
  Benutzer vagabundierend
  Port 3150
  UserKnownHostsFile / dev / null
  StrictHostKeyChecking No.
  PasswordAuthentication No.
  IdentityFile "/Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key"
  IdentitätenNur ja
  LogLevel FATAL

Dann können Sie den privaten Schlüssel wie folgt verwenden. Beachten Sie auch den Schalter zum Ausschalten der Kennwortauthentifizierung

ssh -i /Users/madismanni/m2/vagrant-magento/.vagrant/machines/magento2.vagrant150/virtualbox/private_key -o PasswordAuthentication = no [email protected] -p 3150
Madis Maenni
quelle
Got: ssh_exhange_identification: Verbindung vom Remote-Host geschlossen. Jetzt kann ich nicht einmal einen Authentifizierungsfehler bei Vagrant Up erhalten. Es heißt, dass gästespezifische Vorgänge auf einem Computer versucht wurden, der nicht für die Gastkommunikation bereit ist. Dies sollte nicht passieren und sollte aber gemeldet werden.
user2568374
13

Diese hervorragende Antwort wurde von user76329 in einem abgelehnten Änderungsvorschlag hinzugefügt

Wenn wir das Beispiel von Meow erweitern , können wir die lokalen Pub / Private SSH-Schlüssel kopieren, Berechtigungen festlegen und das Inline-Skript idempotent machen (wird einmal ausgeführt und nur wiederholt, wenn die Testbedingung fehlschlägt und daher eine Bereitstellung erforderlich ist):

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
Stevie Howard
quelle
11

Ein kürzerer und korrekterer Code sollte sein:

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

Andernfalls gehört der Benutzer dem .ssh/authorized_keysRoot-Benutzer.

Es wird immer noch eine Zeile bei jedem Bereitstellungslauf hinzugefügt, aber Vagrant wird zum Testen verwendet und eine VM hat normalerweise eine kurze Lebensdauer, also kein großes Problem.

sekrett
quelle
1
Ich musste config.vm.provision 'shell', inline: "mkdir -p /root/.ssh"nach der ersten Zeile hinzufügen , da Ordner nicht existierte
geekQ
@geekQ Ich benutze ssh-copy-id, daher wird es immer für mich erstellt, aber es ist korrekter, es für andere zu erstellen. Ich werde bearbeiten, danke.
sekrett
9

Am Ende verwende ich Code wie:

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

Beachten Sie, dass wir den Pfad nicht fest codieren sollten, /home/vagrant/.ssh/authorized_keysda einige vagabundierende Felder den vagrantBenutzernamen nicht verwenden .

smartwjw
quelle
Wirklich gute Antwort. Hat mir viel geholfen. Aber ich habe Setups, die anpassen, wo das vagrant.dVerzeichnis gespeichert wird, also habe ich Ihre Konfiguration angepasst, um solche Fälle zu behandeln. Details hier .
Giacomo1968
2

Keiner der älteren Beiträge hat für mich funktioniert, obwohl einige nahe kamen. Ich musste rsa-Schlüssel mit keygen im Terminal erstellen und mit benutzerdefinierten Schlüsseln arbeiten. Mit anderen Worten, besiegt von Vagrants Schlüsseln.

Ich bin unter Mac OS Mojave zum Datum dieses Beitrags. Ich habe zwei Vagrant-Boxen in einer Vagrant-Datei eingerichtet. Ich zeige die gesamte erste Box, damit Neulinge den Kontext sehen können. Ich habe den .ssh-Ordner im selben Ordner wie die Vagrant-Datei abgelegt, andernfalls verwende ich das user9091383-Setup.

Der Kredit für diese Lösung geht an diesen Codierer.

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|
        ...
Preston
quelle
1

Dies ist ein ausgezeichneter Thread, der mir geholfen hat, eine ähnliche Situation zu lösen, wie sie im Originalposter beschrieben wird.

Während ich letztendlich die Einstellungen / Logik verwendet habe, die in der Antwort von smartwjw dargestellt sind , bin ich auf ein Problem gestoßen , da ich die VAGRANT_HOMEUmgebungsvariable verwende, um das vagrant.dKernverzeichnismaterial auf einer externen Festplatte auf einem meiner Entwicklungssysteme zu speichern .

Hier ist also der angepasste Code, den ich in meiner Vagrant-Datei verwende, um eine VAGRANT_HOMEUmgebungsvariable aufzunehmen, die gesetzt wird. Die "Magie" geschieht in dieser Zeile 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
Giacomo1968
quelle
1

Für die Inline-Shell-Provisioner enthält ein öffentlicher Schlüssel häufig Leerzeichen, Kommentare usw. Stellen Sie daher sicher, dass die Variable, die zum öffentlichen Schlüssel erweitert wird, in Anführungszeichen gesetzt wird:

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

Ein ziemlich vollständiges Beispiel, hoffe, dies hilft jemandem, der als nächstes besucht. Alle konkreten Werte wurden in externe Konfigurationsdateien verschoben. Die IP-Zuweisung dient nur zum Ausprobieren.

# -*- 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
Faisal K.
quelle
-1

Die Antwort von Madis Maenni kommt der besten Lösung am nächsten:

mach einfach:

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

dann kannst du einfach über den hostnamen ssh.

Um eine Liste der in ~ / .ssh / config konfigurierten Hostnamen zu erhalten

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

Mein Beispiel:

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

Generieren Sie ein RSA-Schlüsselpaar für die vagabundierende Authentifizierung ssh-keygen -f ~/.ssh/vagrant

Möglicherweise möchten Sie auch die vagabundierenden Identitätsdateien zu Ihrer hinzufügen ~/.ssh/config

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

Aus irgendeinem Grund können wir nicht einfach den Schlüssel angeben, den wir einfügen möchten, sodass wir einige zusätzliche Schritte unternehmen, um selbst einen Schlüssel zu generieren. Auf diese Weise erhalten wir Sicherheit und wissen genau, welchen Schlüssel wir benötigen (+ alle Vagabundboxen erhalten denselben Schlüssel).

Kann nicht mit dem unsicheren privaten Schlüssel (vagrant 1.7.2) zu vagabundierenden VMs ssh. Wie füge ich Vagrant VM meinen eigenen öffentlichen Schlüssel hinzu?

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

SCHALE

user9091383
quelle