openssh: Atomically generate host keys

Generating the host keys atomically prevents power interruptions during the
first boot from leaving the key files incomplete, which often prevents users
from being able to ssh into the device.

[YOCTO #11671]

(From OE-Core rev: d532735e608e32ef1f5a7307c344e528e8fa2f01)

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit 43fc3d8e180c168dbe5dd5faa577e69a279bd1bd)
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Joshua Watt 2018-02-28 12:30:32 -06:00 committed by Richard Purdie
parent aba0f52dc1
commit ff5bedcaf0
1 changed files with 34 additions and 8 deletions

View File

@ -1,5 +1,35 @@
#! /bin/sh
generate_key() {
local FILE=$1
local TYPE=$2
local DIR="$(dirname "$FILE")"
mkdir -p "$DIR"
ssh-keygen -q -f "${FILE}.tmp" -N '' -t $TYPE
# Atomically rename file public key
mv -f "${FILE}.tmp.pub" "${FILE}.pub"
# This sync does double duty: Ensuring that the data in the temporary
# private key file is on disk before the rename, and ensuring that the
# public key rename is completed before the private key rename, since we
# switch on the existence of the private key to trigger key generation.
# This does mean it is possible for the public key to exist, but be garbage
# but this is OK because in that case the private key won't exist and the
# keys will be regenerated.
#
# In the event that sync understands arguments that limit what it tries to
# fsync(), we provided them. If it does not, it will simply call sync()
# which is just as well
sync "${FILE}.pub" "$DIR" "${FILE}.tmp"
mv "${FILE}.tmp" "$FILE"
# sync to ensure the atomic rename is committed
sync "$DIR"
}
# /etc/default/ssh may set SYSCONFDIR and SSHD_OPTS
if test -f /etc/default/ssh; then
. /etc/default/ssh
@ -43,22 +73,18 @@ HOST_KEY_ED25519=$(grep ^HostKey "${sshd_config}" | grep _ed25519_ | tail -1 | a
# create keys if necessary
if [ ! -f $HOST_KEY_RSA ]; then
echo " generating ssh RSA key..."
mkdir -p $(dirname $HOST_KEY_RSA)
ssh-keygen -q -f $HOST_KEY_RSA -N '' -t rsa
generate_key $HOST_KEY_RSA rsa
fi
if [ ! -f $HOST_KEY_ECDSA ]; then
echo " generating ssh ECDSA key..."
mkdir -p $(dirname $HOST_KEY_ECDSA)
ssh-keygen -q -f $HOST_KEY_ECDSA -N '' -t ecdsa
generate_key $HOST_KEY_ECDSA ecdsa
fi
if [ ! -f $HOST_KEY_DSA ]; then
echo " generating ssh DSA key..."
mkdir -p $(dirname $HOST_KEY_DSA)
ssh-keygen -q -f $HOST_KEY_DSA -N '' -t dsa
generate_key $HOST_KEY_DSA dsa
fi
if [ ! -f $HOST_KEY_ED25519 ]; then
echo " generating ssh ED25519 key..."
mkdir -p $(dirname $HOST_KEY_ED25519)
ssh-keygen -q -f $HOST_KEY_ED25519 -N '' -t ed25519
generate_key $HOST_KEY_ED25519 ed25519
fi