Remote login/copy without giving a password

The applications ssh and scp for remote login and remote copy, respectively, allow you to communicate with a remote host without giving a password. This requires that you follow an authentication procedure like the one described below. By client we mean the machine your are sitting on and by server we mean the machine you want to log onto without giving a password. The steps of the authentication procedure are:
  1. Run ssh-keygen to generate private and public keys, unless this is already done on your machine. These are stored in files in $HOME/.ssh.
  2. Append the contents of the public key file to the file $HOME/.ssh/authorized_keys or $HOME/.ssh/authorized_keys2 on the server.
There are three different types of authentication protocols. You specify the type when running ssh-keygen:
  1. SSH protocol version 1, RSA1: this is the default choice and results in files identity (private key, should take chmod 0700 to ensure that this file is not readable for others) and identity.pub (public key).
  2. SSH protocol version 1, RSA: this is obtained by running ssh-keygen -t rsa and results in files id_rsa (private key) and id_rsa.pub (public key)
  3. SSH protocol version 1, DSA: this is obtained by running ssh-keygen -t dsa and results in files id_dsa (private key) and id_dsa.pub (public key)
When running ssh-keygen you can rely on default answers (implying that you do not give a passphrase). This makes the whole set-up simple, but also insecure.

You can specify the type of keys to be used by an option to ssh; ssh -1 forces use of RSA1 keys (protocol version 1), whereas ssh -2 forces ssh to try RSA or DSA keys only (protocol version 2). In the examples below, we generate and install RSA1 and DSA keys on the remote host such that you have more flexibility. You can make a config file in your .ssh directory with the line

Protocol 1,2
This makes ssh try an RSA1 (protocol version 1) connection before RSA/DSA (protocol version 2).

Using RSA1 keys

remote=user@remotehost   # fill in correct user and remotehost names
cd $HOME/.ssh
# create .ssh on remote host if it is non-existing:
ssh $remote 'if [ ! -d .ssh ]; then mkdir .ssh; fi' 
# copy RSA1 key: 
scp identity.pub ${remote}:.ssh
ssh $remote "cd .ssh; cat identity.pub >> authorized_keys"

Using DSA keys

remote=user@remotehost   # fill in correct user and remotehost names
cd $HOME/.ssh
# create .ssh on remote host if it is non-existing:
ssh $remote 'if [ ! -d .ssh ]; then mkdir .ssh; fi' 
# copy DSA key: 
scp id_dsa.pub ${remote}:.ssh
ssh $remote "cd .ssh; cat id_dsa.pub >> authorized_keys2"
This is all you have to do if you did not use a passphrase when generating the keys. You can test the connection by running ssh $remote and see if you can log in without giving a password (you may need to use -1 or -2 as options to ssh). The procedure can, of course, be repeated for any machine you want to log onto.

If you did use a passphrase, you will have to run the program ssh-agent to start a special shell, followed by ssh-add to register your key/passphrase combination with sshd. See the man pages for these programs for more information.

A script for automating password-free connections: ssh-no-password.sh

#!/bin/sh

# create ssh connections without giving a password

if [ $# -lt 1 ]; then
  echo Usage: $0 username@remotehost
  exit
fi
remote="$1"  # 1st command-line argument is the user@remotehost address
this=$HOST   # name of client host

# first check if we need to run ssh-keygen for generating
# $HOME/.ssh with public and private keys:
if [ ! -d $HOME/.ssh ]; then
  echo "just type RETURN for each question:" # no passphrase - unsecure!!
  # generate RSA1, RSA and DSA keys:
  echo; echo; echo
  ssh-keygen
  echo; echo; echo
  ssh-keygen -t rsa
  echo; echo; echo
  ssh-keygen -t dsa
else
  # we have $HOME/.ssh, but check that we have all types of
  # keys (RSA1, RSA, DSA):
  if [ ! -f $HOME/.ssh/identity ]; then
     # generate RSA1 keys:
     echo "just type RETURN for each question:" # no passphrase - unsecure!!
     ssh-keygen
  fi
  if [ ! -f $HOME/.ssh/id_rsa ]; then
     # generate RSA keys:
     echo "just type RETURN for each question:" # no passphrase - unsecure!!
     ssh-keygen -t rsa
  fi
  if [ ! -f $HOME/.ssh/id_rsa ]; then
     # generate DSA keys:
     echo "just type RETURN for each question:" # no passphrase - unsecure!!
     ssh-keygen -t dsa
  fi
fi


cd $HOME/.ssh

if [ ! -f config ]; then
  # make ssh try ssh -1 (RSA1 keys) first and then ssh -2 (DSA keys)
  echo "Protocol 1,2" > config
fi

# copy public keys (all three types) to the destination host:

echo; echo; echo
# create .ssh on remote host if it's not there:
ssh $remote 'if [ ! -d .ssh ]; then mkdir .ssh; fi' 
# copy RSA1 key: 
scp identity.pub ${remote}:.ssh/${this}_rsa1.pub
# copy RSA key:
#scp id_rsa.pub ${remote}:.ssh/${this}_rsa.pub
# copy DSA key:
scp id_dsa.pub ${remote}:.ssh/${this}_dsa.pub
# make authorized_keys(2) files on remote host:

echo; echo; echo
# this one copies all three keys:
#ssh $remote "cd .ssh; touch authorized_keys authorized_keys2; cat ${this}_rsa1.pub >> authorized_keys; cat ${this}_rsa.pub >> authorized_keys2; cat ${this}_dsa.pub >> authorized_keys2;"
# this one copies RSA1 and DSA keys:
ssh $remote "cd .ssh; touch authorized_keys authorized_keys2; cat ${this}_rsa1.pub >> authorized_keys; cat ${this}_dsa.pub >> authorized_keys2;"

echo; echo; echo
echo "try an ssh $remote"