Install / Append SSH Key In A Remote Linux / UNIX Servers Authorized_keys

Posted on in Categories , , , last updated February 14, 2015

How do I install my SSH public key ~/.ssh/id_rsa.pub onto a remote Linux and UNIX server automatically from Linux workstation or Apple OS X laptop without using scp and/or copy & paste method?

You need to use the ssh-copy-id script that uses ssh to log into a remote machine using a login password. The syntax is as follows:

ssh-copy-id user@server.example.com

OR

ssh-copy-id -i ~/.ssh/id_rsa.pub user@server1.cyberciti.biz

OR

ssh-copy-id -i ~/.ssh/id_dsa.pub user@server1.cyberciti.biz

OR use specific port on remote host such as tcp port # 4242:

ssh-copy-id -i /path/key/file.pub "user@server.example.com -p 4242"

Install ssh-copy-id on a OS X Unix systems

Type the following command:

brew install ssh-copy-id

Sample outputs:

Fig.01: Install ssh-copy-id on a OS X Unix systems
Fig.01: Install ssh-copy-id on a OS X Unix systems

Step # 1: Create the Keys

Type the following ssh-keygen command to generates, manages and converts authentication keys for your workstation / laptop:
ssh-keygen
Make sure you protect keys with the passphrase.

Step # 2: Install the public key

Install key in a remote server called www-03.nixcraft.in, enter:
ssh-copy-id -i ~/.ssh/id_rsa.pub username@www-03.nixcraft.in

Note: If ssh-copy-id command not found on your system, try the following commands to append/install the public key on remote host:
ssh username@www-03.nixcraft.in "umask 077; mkdir .ssh"
cat $HOME/.ssh/id_rsa.pub | ssh username@www-03.nixcraft.in "cat >> .ssh/authorized_keys"

Step #3: Use keychain for password less login

OpenSSH offers RSA and DSA authentication to remote systems without supplying a password. keychain is a special bash script designed to make key-based authentication incredibly convenient and flexible (see how to install keychain script on unix). Add following lines to your ~/.bash_profile or shell login file:

/usr/bin/keychain $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOSTNAME-sh

Save and close the file.

References:

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

9 comment

  1. Hi all.
    Unfortunately, ssh-copy-id does not exist under OS X, so here is a script that does the same job.
    When I can remember where I got it from, I will add the relevant credit to its author.

    Best regards,

    Neil.

    #!/bin/sh
    
    KEY="$HOME/.ssh/id_dsa.pub"
    
    if [ ! -f ~/.ssh/id_dsa.pub ];then
        echo "private key not found at $KEY"
        echo "* please create it with "ssh-keygen -t dsa" *"
        echo "* to login to the remote host without a password, don't give the key you create with ssh-keygen a password! *"
        exit
    fi
    
    if [ -z $1 ];then
        echo "Please specify user@host.tld as the first switch to this script"
        exit
    fi
    
    echo "Putting your key on $1... "
    
    KEYCODE=`cat $KEY`
    ssh -q $1 "mkdir ~/.ssh 2>/dev/null; chmod 700 ~/.ssh; echo "$KEYCODE" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"
    
    echo "done!"
    
  2. Here is what I’ve installed in my Debian Linux box:

    #!/bin/sh
    
    # Shell script to install your public key on a remote machine
    # Takes the remote machine name as an argument.
    # Obviously, the remote machine must accept password authentication,
    # or one of the other keys in your ssh-agent, for this to work.
    
    ID_FILE="${HOME}/.ssh/id_rsa.pub"
    
    if [ "-i" = "$1" ]; then
      shift
      # check if we have 2 parameters left, if so the first is the new ID file
      if [ -n "$2" ]; then
        if expr "$1" : ".*\.pub" > /dev/null ; then
          ID_FILE="$1"
        else
          ID_FILE="$1.pub"
        fi
        shift         # and this should leave $1 as the target name
      fi
    else
      if [ x$SSH_AUTH_SOCK != x ] && ssh-add -L >/dev/null 2>&1; then
        GET_ID="$GET_ID ssh-add -L"
      fi
    fi
    
    if [ -z "`eval $GET_ID`" ] && [ -r "${ID_FILE}" ] ; then
      GET_ID="cat ${ID_FILE}"
    fi
    
    if [ -z "`eval $GET_ID`" ]; then
      echo "$0: ERROR: No identities found" >&2
      exit 1
    fi
    
    if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
      echo "Usage: $0 [-i [identity_file]] [user@]machine" >&2
      exit 1
    fi
    
    { eval "$GET_ID" ; } | ssh ${1%:} "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys" || exit 1
    
    cat <<EOF
    Now try logging into the machine, with "ssh '${1%:}'", and check in:
    
      .ssh/authorized_keys
    
    to make sure we haven't added extra keys that you weren't expecting.
    
    EOF
  3. Hi Neil,

    Thanks for the tip. I’ve been playing with ssh and keygen yesterday and missed this useful command.

    Here are my two cents:

    1 – Since there is no way to specify a port from the command line to this command one can add the following to their ~/.ssh/config

    Host remote.server.tld
    Port 2222

    And remove the line afterwards (see 3).

    2 – Change the permissions of ~/.ssh/authorized_key to 600

    3 – Hash the known_hosts file: This replaces all hostnames and addresses with hashed representations
    ssh-keygen -H -f ~/.ssh/known_hosts

    Regards.

      1. Sorry, I repeated the command again, and worked well! Thanks!

        ssh-copy-id -i ~/.ssh/id_rsa.pub “user@server -p 2222”

        Now try logging into the machine, with “ssh ‘user@server -p 2222′”, and check in:

        .ssh/authorized_keys

        to make sure we haven’t added extra keys that you weren’t expecting.

  4. I found a bug:
    cat $HOME/.ssh/id_rsa.pub | ssh username@www-03.nixcraft.in cat >> .ssh/authorized_keys
    should be
    cat $HOME/.ssh/id_rsa.pub | ssh username@www-03.nixcraft.in ‘cat >> .ssh/authorized_keys’
    It won’t work without quotes as intended.

    Also, the “ssh-keygen” followed by the piped “cat” command is sufficient to get password-less access enabled. Do both on your machine, “www-03.nixcraft.in” in the example is the remote computer you want to access.

  5. #!/usr/bin/env bash
    clear
    HOST=$1
    U=$2
    P=$3 
    in=3
    E_BADARGS=65
    
    cat </dev/null`" ]&& echo -e "\033[5;1;31m PING 		$HOST is failed \033[0m" 
    #[ ! "`ssh $U@$HOST 2>/dev/null`" ]&& echo -e "\033[5;1;31m SSH to 	$HOST is failed \033[0m" && exit
    
    mkd(){
      echo "Creating $U/.ssh On Host $HOST"
      ssh -p $P $U@$HOST "mkdir ~/.ssh"  
      scp -P $P  ~/.ssh/id_rsa.pub $U@$HOST:~/.ssh/authorized_keys.tmp && echo "DONE"
    }
    
    web(){
      echo "Enter your ip and user address to upload key"
      read SERVER U_
      ssh -p $P $U_@$HOST wget -q $SERVER/dl/id_rsa.pub -O .ssh/authorized_keys.tmp
    }
    
    if [ ! -f ~/.ssh/id_rsa.pub ];then 
       echo "id_rsa.pub not found !"
       ssh-keygen -t rsa
    else
       
       read -sp "Do you want to generate new keys (y/n) ?" resp
    
       if [ $resp = "y" ];then
          echo -e "\033[1;33m GENERATING SSH KEY \033[0m"
          ssh-keygen -t rsa
       else
          echo -e "\033[1;32m Using old keys\033[0m"
       fi
    fi
    
    echo -e "\033[1;33m ...MAKING KEYS ON HOST $HOST for USER =$U 		\033[0m"
    scp -P $P ~/.ssh/id_rsa.pub $U@$HOST:~/.ssh/authorized_keys.tmp && echo "DONE" || mkd
    echo -e "\033[1;33m -------------------------------\033[0m"
    ssh -p $P $U@$HOST "cat ~/.ssh/authorized_keys.tmp >> ~/.ssh/authorized_keys"
    
    echo -e "\033[1;32m CHECKING THE PROCESS \033[0m"
    ssh -p $P $U@$HOST

    I wrote it in 2009 and i was noob ;)

Leave a Comment