ssh keys

From OpenVZ Virtuozzo Containers Wiki
Jump to: navigation, search

OpenSSH has several authentication mechanisms. The most known one is then you type in the password, which is then checked against the password at the remote system. While this is straightforward and does not usually require any additional setup, it is not convenient to enter the password each time.

This article describes how to set up a passwordless ssh login, using ssh key pairs. This can be convenient e. g. in cases when you use live migration.

Theory

OpenSSH uses several assymmetric cryptography algorithms, where a pair of keys are generated. Those keys are known as public key and private key. Public keys can then be uploaded to a remote system which you want a passwordless access to. See more at wikipedia: Public-key cryptography.

Your OpenSSH public keys are usually stored in ~/.ssh/id*.pub files, and your private keys are stored in the ~/.ssh/id* files (the ones without .pub suffix).

If you want to let user Joe at host One to log in as user Bar at host Two, you should put Joe@One's public keys into Bar@Two's ~/.ssh/authorized_keys* files. This process can be automated using the following script.

The script

The following script can be used to automate a process of generating ssh key pairs and putting the public keys to an account on a remote host. Place the script to /usr/local/bin or your ~/bin and enable its execution (i. e. do chmod a+x ssh-keyput).

#!/bin/bash
#
# ssh-keyput -- set up passwordless openssh login.
#
# Copyright (C) 2001, 2002, 2006 by SWsoft.
# Author: Kir Kolyshkin
#
# This script is used to put your public ssh keys to another host's
# authorized_keys[2], so you will be able to ssh login without entering
# a password. Key pairs are generated if needed, and connectivity
# is checked after putting the keys.

PROGNAME=`basename $0`

function usage()
{
	echo "Usage: $PROGNAME [user@]IP [[user@]IP ...]" 1>&2
	exit 0
}

# Check for correct number of parameters
test $# -gt 0 || usage;

SSH_KEYGEN=`which ssh-keygen`
if test $? -ne 0; then
	# Error message is printed by 'which'
	exit 1
fi

SSH_DIR=~/.ssh
if ! test -d $SSH_DIR; then
	mkdir $SSH_DIR
fi
chmod 700 $SSH_DIR


if [ ! -f $SSH_DIR/identity ] || [ ! -f $SSH_DIR/identity.pub ]; then
	echo "Generating ssh1 RSA keys - please wait..."
	rm -f $SSH_DIR/identity $SSH_DIR/identity.pub
	$SSH_KEYGEN -t rsa1 -f $SSH_DIR/identity -P ''
	if [ $? -ne 0 ]; then
		echo "Command \"$SSH_KEYGEN -t rsa1 -f $SSH_DIR/identity" \
			 "-P ''\" failed" 1>&2
		exit 1
	fi
else
	echo "ssh1 RSA key is present"
fi

if [ ! -f $SSH_DIR/id_dsa ] || [ ! -f $SSH_DIR/id_dsa.pub ]; then
	echo "Generating ssh2 DSA keys - please wait..."
	rm -f $SSH_DIR/id_dsa $SSH_DIR/id_dsa.pub
	$SSH_KEYGEN -t dsa -f $SSH_DIR/id_dsa -P ''
	if test $? -ne 0; then
		echo "Command \"$SSH_KEYGEN -t dsa -f $SSH_DIR/id_dsa" \
			 "-P ''\" failed" 1>&2
		exit 1
	fi
else
	echo "ssh2 DSA key is present"
fi

SSH1_RSA_KEY=`cat $SSH_DIR/identity.pub`
SSH2_DSA_KEY=`cat $SSH_DIR/id_dsa.pub`

for IP in $*; do
	echo "You will now be asked for password for $IP"
#	set -x
	ssh -oStrictHostKeyChecking=no $IP "mkdir -p ~/.ssh; chmod 700 ~/.ssh; \
		echo \"$SSH1_RSA_KEY\" >> ~/.ssh/authorized_keys; \
		echo \"$SSH2_DSA_KEY\" >> ~/.ssh/authorized_keys2; \
		chmod 600 ~/.ssh/authorized_keys ~/.ssh/authorized_keys2"
#	set +x
	if test $? -eq 0; then
		echo "Keys were put successfully"
	else
		echo "Error putting keys to $IP" 1>&2
	fi
done

for IP in $*; do
	for ver in 1 2; do
		echo -n "Checking $IP connectivity by ssh$ver... "
		ssh -q -oProtocol=${ver} -oBatchMode=yes \
		  -oStrictHostKeyChecking=no $IP /bin/true
		if [ $? -eq 0 ]; then
			echo "OK"
		else
			echo "failed" 1>&2
		fi
	done
done