4 Ways to Add SSH public key to Vagrant VM(Virtual Machine)?


Vagrant helped developers to create a very lightweight, portable development machine which can be destroyed and recreated on the fly. When it comes to starting a virtual machine onto your development environment vagrant helps you to spin up the virtual machine with very few lines of codes.

But while working with Vagrant on my development environment one day I had a need to copy my public ssh keys to one of my virtual machines which I started using vagrant.

Now you might be wondering, since it’s a virtual machine running in a development environment, why do I need to copy a public SSH key?

"Answer - Well I had Ansible playbook which I need to run after starting my virtual machine but ansible can’t communicate with my Virtual Machine unless I put my public SSH key into it."

So to achieve that I consolidated following ways -

  1. Use ssh-copy-id for copying public ssh key
  2. Using Ruby’s code File Module to copy public ssh key
  3. Copy public ssh key using file provisioner
  4. Using vagrant ssh-config and private key to ssh into vagrant without running vagrant ssh

1. Use ssh-copy-id for copying public ssh key

The easiest and one of the most effective ways is to use the ssh-copy-id for copying your public key residing at /home/username/.ssh/id_rsa.

But let’s first generate the public ssh key onto your local development environment. Here is the shell command for that -

1ssh-keygen -t rsa

After running the above command it will ask for the location where you want to save the public key.(By default it is going to save at /home/username/.ssh/id_rsa)

1Enter file in which to save the key (/home/vagrant/.ssh/id_rsa):

Once you enter the default location it is going to ask the passphrase for your public key. So you can input some passphrase or keep it blank as per your choice.

1Enter passphrase (empty for no passphrase):
2Enter same passphrase again:

And finally your terminal output should look like this -

 1Your identification has been saved in /home/vagrant/.ssh/id_rsa.
 2Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
 3The key fingerprint is:
 4SHA256:LWGasiSDAqf8eY3pz5swa/nUl2rWc1IFgiPuqFTYsKs vagrant@amaster
 5The key's randomart image is:
 6+---[RSA 2048]----+
 7|          .      |
 8|   .   . o . .   |
 9|. . = . + . . .  |
10|o+ o o = o     . |
11|+.o = = S .   .  |
12|. .*.++...  ..   |
13|  ooo*.o ..o.    |
14| E .oo* .oo+ .   |
15|    .oo*+.  +    |
16+----[SHA256]-----+

1.1 Copy the public key(/home/vagrant/.ssh/id_rsa) to the vagrant’s virtual machine

Copying part is fairly easy you simply need to run one command -

1ssh-copy-id vagrant@100.0.0.2

But there a few points which you should keep in mind -

  1. If you are using Vagrant then always use vagrant as your default user .e.g. vagrant@100.0.0.2
  2. 100.0.0.2 - Is the IP address of my virtual machine running using vagrant

2. Using Ruby’s code File Module to copy public ssh key

The second approach would be to use the Ruby’s core File module to copy the public ssh key to your vagrant box.

Since vagrant is using Ruby to write virtual machine configuration inside the Vagrantfile, it does make more sense to use inbuilt modules of Ruby to achieve it.

Here is a little vagrant configuration using Ruby which you can incorporate inside your Vagrantfile -

1config.vm.provision "shell" do |s|
2ssh_pub_key = File.readlines("/home/username/.ssh/id_rsa.pub").first.strip
3s.inline = <<-SHELL
4echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys
5echo #{ssh_pub_key} >> /root/.ssh/authorized_keys
6SHELL
7end

(Note - In the above code snippet I am assuming your public key exists at the location /home/your_username/.ssh and your public key name is id_rsa.pub)


3. Copy public ssh key using file provisioner

The third option we have is to copy the public ssh key using the file provisioner. So when you write your vagrant configuration inside your Vagrantfile then vagrant allows you to add file provisioner along with the two arguments src and destination.

In the src argument you can specify the location from where you want to copy the public ssh key and in the destination argument you can specify the location where you want to copy the public ssh key

Here is an example of a vagrant file provisioner -

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

4. Using vagrant ssh-config and private key to ssh into vagrant without running vagrant ssh

This approach is a little bit different and does not have to do anything with the public key but instead it relies on the private key of the Vagrant box.

Now the question comes how to use vagrant ssh-config?

  1. First off all you need to start your vagrant box using the command - $ vagrant up
  2. After starting the vagrant box you need to run the command -$ vagrant ssh-config

It should show following information -

 1Host testserver
 2HostName 127.0.0.1
 3User vagrant
 4Port 2222
 5UserKnownHostsFile /dev/null
 6StrictHostKeyChecking no
 7PasswordAuthentication no
 8IdentityFile /Users/rahul/myvagrantmachine/.vagrant/machines/elkserver/virtualbox/private_key
 9IdentitiesOnly yes
10LogLevel FATAL
  1. Now you can use the private_key information from step number 2 and ssh into your vagrant machine. Here is the command for that -
1ssh -i /Users/rahul/myvagrantmachine/.vagrant/machines/elkserver/virtualbox/private_key -o PasswordAuthentication=no vagrant@127.0.0.1 -p 3150

Since we are using the private key in the above command we do not need to provide the password, hence keeping the PasswordAuthentication=no

I hope this guide on handling ssh keys with vagrant will help you to copy the public onto your vagrant virtual machine.

Reference -

  1. GitHub - Adding ssh key to vagrant