42

I have a cluster of 3 VMs. Here is the Vagrantfile:

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


hosts = {
  "host0" => "192.168.33.10",
  "host1" => "192.168.33.11",
  "host2" => "192.168.33.12"
}

Vagrant.configure("2") do |config|
  config.vm.box = "precise64"
  config.vm.box_url = "http://files.vagrantup.com/precise64.box"
  config.ssh.private_key_path = File.expand_path('~/.vagrant.d/insecure_private_key')

  hosts.each do |name, ip|
    config.vm.define name do |machine|
      machine.vm.hostname = "%s.example.org" % name
      machine.vm.network :private_network, ip: ip
      machine.vm.provider "virtualbox" do |v|
          v.name = name
      #    #v.customize ["modifyvm", :id, "--memory", 200]
      end
    end
  end
end

This used to work until I upgraded recently:

ssh -i ~/.vagrant.d/insecure_private_key vagrant@192.168.33.10

Instead, vagrant asks for a password.

It seems that recent versions of vagrant (I'm on 1.7.2) create a secure private key for each machine. I discovered it by running

vagrant ssh-config

The output shows different keys for each host. I verified the keys are different by diffing them.

I tried to force the insecure key by setting in Vagrantfile the config.ssh.private_key_path, but it doesn't work.

The reason I want to use the insecure key for all machines is that I want to provision them from the outside using ansible. I don't want to use the Ansible provisioner, but treat the VMs as remote servers. So, the Vagrantfile is just used to specify the machines in the cluster and then provisioning will be done externally.

The documentation still says that by default machines will use the insecure private key.

How can I make my VMs use the insecure private key?

Pyramid Newbie
  • 6,865
  • 3
  • 24
  • 28

5 Answers5

49

Vagrant changed the behaviour between 1.6 and 1.7 versions and now will insert auto generated insecure key instead of the default one.

You can cancel this behaviour by setting config.ssh.insert_key = false in your Vagrantfile.

Vagrant shouldn't replace insecure key if you specify private_key_path like you did, however the internal logic checks if the private_key_path points to the default insecure_private_key, and if it does, Vagrant will replace it.

More info can be found here.

m1keil
  • 4,515
  • 22
  • 26
  • 1
    My question is now: why did they change it? For security reasons? Why then replace it with an auto generated key? – gitaarik Mar 17 '15 at 23:54
  • Yep, security reasons. It won't save you in the long run, but it's just a bit more secure then shipping every box in the world with the same key pair. – m1keil Apr 08 '15 at 07:13
  • My VM is immutable, how does it try to regenerate a key, if my etc files wouldn't allow it? – CMCDragonkai Jun 02 '15 at 16:07
  • 1
    In this case, you should disable this behaviour. – m1keil Jun 22 '15 at 16:06
28

When Vagrant creates a new ssh key it's saved with the default configuration below the Vagrantfile directory at .vagrant/machines/default/virtualbox/private_key.

Using the autogenerated key you can login with that from the same directory as the Vagrantfile like this:

ssh -i .vagrant/machines/default/virtualbox/private_key -p 2222 vagrant@localhost

To learn about all details about the actual ssh configuration of a vagrant box use the vagrant ssh-config command.

# vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/babo/src/centos/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
ababo
  • 460
  • 5
  • 5
  • 3
    Discovered that the location of the identity file changed for me for my latest box installation to a location off my home directory, e.g. `/Users/babo/.vagrant.d/boxes/centos/0/virtualbox/vagrant_private_key` Fortunately executing `vagrant ssh-config` exposed the correct location. – bhfailor Aug 26 '16 at 15:29
14

Adding config.ssh.insert_key = false to the Vagrantfile and removing the new vm private key .vagrant/machines/default/virtualbox/private_key vagrant automatically updates vagrant ssh-config with the correct private key ~/.vagrant.d/insecure_private_key. The last thing I had to do was ssh into the vm and update the authorized keys file on the vm. curl https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub > ~/.ssh/authorized_keys

Andrew
  • 3,733
  • 1
  • 35
  • 36
  • 2
    Really helpfull! Thanks! I had VM with wrong key placed in authorized_keys, so vagrant could not connect to it. Your method helped me to solve this issue! – Brazhnyk Yuriy Sep 10 '15 at 09:45
  • 2
    Thanks for the idea. renamed the `.vagrant/machines/default/virtualbox/private_key` into `private_key_old` and vagrant created everything. – Salyangoz Sep 21 '15 at 07:26
3

tldr;

ssh vagrant@127.0.0.1 -p2222 -i/~/www/vw/vw-environment/.vagrant/machines/default/virtualbox/private_key

I couldn't get this to work, so in the end I added the following to the ssh.rb ruby script (/opt/vagrant/embedded/gems/gems/vagrant-1.7.1//lib/vagrant/util/ssh.rb)

print(*command_options)

just before this line that executes the ssh call

SafeExec.exec("ssh", *command_options)

So that prints out all the command options passed to the ssh call, from there you can work out something that works for you based on what vagrant calculates to be the correct ssh parameters.

chim
  • 8,407
  • 3
  • 52
  • 60
  • 1
    `ssh vagrant@127.0.0.1 -p2222 -i/~/www/vw/vw-environment/.vagrant/machines/default/virtualbox/private_key` works for me. – micmia Jun 01 '16 at 22:59
0

If you are specifically using Ansible (not the Vagrant Ansible provisioner), you might want to consider using the vagrant dynamic inventory script from Ansible's repo:

Alternatively, you'd can handcraft your own script and dynamically build your own vagrant inventory file:

SYSTEMS=$(vagrant status | grep running | cut -d ' '  -f1)

echo '[vagrant_systems]' > vagrant.ini

for SYSTEM in ${SYSTEMS}; do
  SSHCONFIG=$(vagrant ssh-config ${SYSTEM})
  IDENTITY_FILE=$(echo "${SSHCONFIG}" | grep -o "\/.*${SYSTEM}.*")
  PORT=$(echo "${SSHCONFIG}" | grep -oE '[0-9]{4,5}')
  echo "${SYSTEM} ansible_ssh_host=127.0.0.1 ansible_ssh_port=${PORT} ansible_ssh_private_key_file=${IDENTITY_FILE}" >> vagrant.ini
done

Then use ansible-playbook -i=vagrant.ini

If you try to use the ~/.ssh/config, you'll have to dynamically create or edit existing entries, as the ssh ports can change (due to the collision detection in Vagrant).