Automating ssh-copy-id
Tags: tooling, performance, devops, bash
Published: 2020-11-13 00:43:00

---
title: Automating ssh-copy-id
published: true
date: 2020-11-13 00:15:00 UTC
tags: tooling, performance, devops, bash
canonical_url: https://www.benjaminrancourt.ca/automating-ssh-copy-id
cover_image: https://www.benjaminrancourt.ca/temp/automating-ssh-copy-id.jpeg
---
Last month, I receive a more recent laptop at my workplace and I needed to reinstall my distribution, [Manjaro](https://manjaro.org/), on it. 💻 Fortunately, I have a semiautomatic procedure to setup myself quickly, but there was a part that did not really strike a chord in me:

```bash
# Add my public key to the principal servers (one command at at a time) 
ssh-copy-id -i ~/.ssh/id_rsa.pub $USER@SERVER_1
ssh-copy-id -i ~/.ssh/id_rsa.pub $USER@SERVER_2
# ...
ssh-copy-id -i ~/.ssh/id_rsa.pub $USER@SERVER_22
```
<figcaption>Excerpt of my procedure</figcaption>

For those that do not know the useful [ssh-copy-id command](https://www.ssh.com/ssh/copy-id), it is a tool part of **[OpenSSH](https://www.openssh.com/)** that adds an SSH public key on a server as an authorized key. With that, you do not need to enter your password each time you log in at that server.

But it has a little (and normal) drawback: the first time you connect to the server to install a new SSH public key, **you need to enter your password**. 🔑 With more than 20 machines that I want to be able to connect without being prompting my password, I knew that I would need to enter the same amount of times my complicated password… And it was only the minimum, as I could get it wrong… ❌

So, I decide to try to add more **automation** to that part of my script. I looked up on the Internet, but I did not find a perfect solution for me. So I glued together some answers and I came with the Bash program below:

```bash
#!/bin/bash
# Script to automatically add our public key on a list of servers
# to remove the pain from typing each time our password
# when we want to access a server.
 
# [manual] If you want to copy your key to only one server
# ssh-copy-id -i ~/.ssh/id_rsa.pub SERVER
 
# Definition of the servers
SERVERS=(
  "benjaminrancourt.ca"
  "another-server.ca"
)

# Make sure we have your password
if [-z "$1"]; then
  echo "You must supply your password!"
  echo " ./ssh-copy-id-servers.sh 'PASSWORD'"
  exit
fi

# Export the password into an environment variable
export SSHPASS=$1
 
# Iterate over all servers
for SERVER in "${SERVERS[@]}"
do
  # Echo the server name
  echo $SERVER
   
  # Copy our key the first time to allow
  sshpass -e ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no $USER@$SERVER || echo "FAILED"
   
  # Clean the .ssh folder
  ssh $USER@$SERVER 'rm -rf .ssh'
   
  # Add back our key, as we have remove the former authorized keys, along with the new one!
  sshpass -e ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no $USER@$SERVER || echo "FAILED"
done
```
<figcaption>My <code>ssh-copy-id-servers.sh</code> script</figcaption>

To remove old public keys of previous installations, I also add the deletion of the **.ssh folder** on each server. It may be a brutal way, but I am sure they are no leftovers! 💀

By taking less than 30 minutes to come to this solution, I estimate that I save at least the same amount of time for myself for the next five years. My investment will pay off quicker if other people in my workplace use it! 🧹

By automating more and more of my procedure at each reinstallation, it becomes easier and easier! 🤖

I wish this script helps you!