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 [email protected]

OR

ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

OR

ssh-copy-id -i ~/.ssh/id_dsa.pub [email protected]

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

ssh-copy-id -i /path/key/file.pub "[email protected] -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 [email protected]

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 [email protected] "umask 077; mkdir .ssh"
cat $HOME/.ssh/id_rsa.pub | ssh [email protected] "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:

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 [email protected] 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.

  4. To do this on a non standard port the best is to use this:

    ssh-copy-id -i /path/key.pub “[email protected] -p 2222”

    Cheers

    1. [email protected]:~/.ssh# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] -p 2222″
      ssh: connect to host server port 22: Connection refused

      Not works

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

        ssh-copy-id -i ~/.ssh/id_rsa.pub “[email protected] -p 2222”

        Now try logging into the machine, with “ssh ‘[email protected] -p 2222′”, and check in:

        .ssh/authorized_keys

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

  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