See all GNU/Linux related FAQ
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:
Advertisement

ssh-copy-id user@server.example.com[donotprint]

Tutorial details
Difficulty level Easy
Root privileges No
Requirements None
Est. reading time 2 minutes
[/donotprint]

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:
This entry is 22 of 23 in the Linux/Unix OpenSSH Tutorial series. Keep reading the rest of the series:
  1. Top 20 OpenSSH Server Best Security Practices
  2. How To Set up SSH Keys on a Linux / Unix System
  3. OpenSSH Config File Examples For Linux / Unix Users
  4. Audit SSH server and client config on Linux/Unix
  5. How to install and upgrade OpenSSH server on FreeBSD
  6. Ubuntu Linux install OpenSSH server
  7. Install OpenSSH server on Alpine Linux (including Docker)
  8. Debian Linux Install OpenSSH SSHD Server
  9. Configure OpenSSH To Listen On an IPv6 Address
  10. OpenSSH Server connection drops out after few minutes of inactivity
  11. Display banner/message before OpenSSH authentication
  12. Force OpenSSH (sshd) to listen on selected multiple IP address only
  13. OpenSSH Change a Passphrase With ssh-keygen command
  14. Reuse SSH Connection To Speed Up Remote Login Process Using Multiplexing
  15. Check Syntax Errors before Restarting SSHD Server
  16. Change the ssh port on Linux or Unix server
  17. OpenSSH Deny or Restrict Access To Users and Groups
  18. Linux OpenSSH server deny root user access / log in
  19. Disable ssh password login on Linux to increase security
  20. SSH ProxyCommand example: Going through one host to reach server
  21. OpenSSH Multiplexer To Speed Up OpenSSH Connections
  22. Install / Append SSH Key In A Remote Linux / UNIX Servers Authorized_keys
  23. Use ssh-copy-id with an OpenSSH Server Listening On a Different Port

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

9 comments… add one
  • Nei McLeish May 7, 2010 @ 12:47

    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!"
    
  • Anonymous May 7, 2010 @ 13:13

    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
  • Juan Giordana May 9, 2010 @ 21:03

    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.

  • Juan Francisco Giordana May 9, 2010 @ 21:07

    Host remote.server.tld
    Port 2222

  • Cokegen May 18, 2011 @ 23:03

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

    ssh-copy-id -i /path/key.pub “user@host -p 2222”

    Cheers

    • Jordi Jul 8, 2011 @ 8:36

      xxx@server:~/.ssh# ssh-copy-id -i ~/.ssh/id_rsa.pub “xxx@server -p 2222″
      ssh: connect to host server port 22: Connection refused

      Not works

      • Jordi Jul 8, 2011 @ 9:22

        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.

  • NoSiL May 22, 2014 @ 17:37

    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.

  • h.amiri Jan 5, 2016 @ 17:44
    #!/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 Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.