Skip to contentSkip to conversation

openssh: Fix key generation with systemd

PATCH New André Draszik 1 participant 1 message Oct 6, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 openssh: Fix key generation with systemd

From: Joshua Watt <[email protected]>

106b59d9 broke SSH host key generation when systemd and a read-only root file system are in use because there isn't a way for systemd to get the optional weak assigment of SYSCONFDIR from /etc/default/sshd and still provide a default value if it is not specified. Instead, move the logic for determining if keys need to be created to a helper script that both the SysV init script and the systemd unit file can reference.

This does mean that the systemd unit file can't check for file existence to know if it should start the service, but it wasn't able to do that correctly anyway anymore. This should be a problem since the serivce is only run once per power cycle by systemd, and should exit quickly if the keys already exist

(cherry picked from commit 7e49c5879862253ae1b6a26535d07a2740a95798)
---
 meta/recipes-connectivity/openssh/openssh/init     | 69 +---------------------
 .../openssh/openssh/sshd_check_keys                | 64 ++++++++++++++++++++
 .../openssh/openssh/sshdgenkeys.service            | 16 +----
 meta/recipes-connectivity/openssh/openssh_7.4p1.bb |  8 +++
 4 files changed, 76 insertions(+), 81 deletions(-)
 create mode 100644 meta/recipes-connectivity/openssh/openssh/sshd_check_keys
meta/recipes-connectivity/openssh/openssh/init +3 -66
index 386628afc8..34ba0f8460 100644
@@ -19,25 +19,6 @@ fi
 [ -z "$SYSCONFDIR" ] && SYSCONFDIR=/etc/ssh
 mkdir -p $SYSCONFDIR
 
-parse_sshd_opts() {
-    set -- ${SSHD_OPTS} --
-    sshd_config=/etc/ssh/sshd_config
-    while true ; do
-        case "$1" in
-        -f*) if [ "$1" = "-f" ] ; then
-                 sshd_config="$2"
-                 shift
-             else
-                 sshd_config="${1#-f}"
-             fi
-             shift
-             ;;
-        --) shift; break;;
-        *) shift;;
-        esac
-    done
-}
-
 check_for_no_start() {
     # forget it if we're trying to start, and /etc/ssh/sshd_not_to_be_run exists
     if [ -e $SYSCONFDIR/sshd_not_to_be_run ]; then
@@ -58,57 +39,13 @@ check_config() {
 	/usr/sbin/sshd -t $SSHD_OPTS || exit 1
 }
 
-check_keys() {
-	# parse location of keys
-	local HOST_KEY_RSA
-	local HOST_KEY_DSA
-	local HOST_KEY_ECDSA
-	local HOST_KEY_ED25519
-
-	parse_sshd_opts
-	HOST_KEY_RSA=$(grep ^HostKey "${sshd_config}" | grep _rsa_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_RSA}" ] && HOST_KEY_RSA=$(grep HostKey "${sshd_config}" | grep _rsa_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_RSA}" ] && HOST_KEY_RSA=$SYSCONFDIR/ssh_host_rsa_key
-	HOST_KEY_DSA=$(grep ^HostKey "${sshd_config}" | grep _dsa_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_DSA}" ] && HOST_KEY_DSA=$(grep HostKey "${sshd_config}" | grep _dsa_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_DSA}" ] && HOST_KEY_DSA=$SYSCONFDIR/ssh_host_dsa_key
-	HOST_KEY_ECDSA=$(grep ^HostKey "${sshd_config}" | grep _ecdsa_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_ECDSA}" ] && HOST_KEY_ECDSA=$(grep HostKey "${sshd_config}" | grep _ecdsa_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_ECDSA}" ] && HOST_KEY_ECDSA=$SYSCONFDIR/ssh_host_ecdsa_key
-	HOST_KEY_ED25519=$(grep ^HostKey "${sshd_config}" | grep _ed25519_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_ED25519}" ] && HOST_KEY_ED25519=$(grep HostKey "${sshd_config}" | grep _ed25519_ | tail -1 | awk ' { print $2 } ')
-	[ -z "${HOST_KEY_ED25519}" ] && HOST_KEY_ED25519=$SYSCONFDIR/ssh_host_ed25519_key
-
-	# 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
-	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
-	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
-	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
-	fi
-}
-
 export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
 
 case "$1" in
   start)
 	check_for_no_start
 	echo "Starting OpenBSD Secure Shell server: sshd"
-	check_keys
+	@LIBEXECDIR@/sshd_check_keys
 	check_privsep_dir
 	start-stop-daemon -S -p $PIDFILE -x /usr/sbin/sshd -- $SSHD_OPTS
         echo "done."
@@ -121,7 +58,7 @@ case "$1" in
 
   reload|force-reload)
 	check_for_no_start
-	check_keys
+	@LIBEXECDIR@/sshd_check_keys
 	check_config
         echo -n "Reloading OpenBSD Secure Shell server's configuration"
 	start-stop-daemon -K -p $PIDFILE -s 1 -x /usr/sbin/sshd
@@ -129,7 +66,7 @@ case "$1" in
 	;;
 
   restart)
-  	check_keys
+	@LIBEXECDIR@/sshd_check_keys
 	check_config
         echo -n "Restarting OpenBSD Secure Shell server: sshd"
 	start-stop-daemon -K -p $PIDFILE --oknodo -x /usr/sbin/sshd
meta/recipes-connectivity/openssh/openssh/sshd_check_keys new file +64 -0

64 lines not on this page · raw message

meta/recipes-connectivity/openssh/openssh/sshdgenkeys.service +1 -15
index 148e6ad63a..603c33787f 100644
@@ -1,22 +1,8 @@
 [Unit]
 Description=OpenSSH Key Generation
 RequiresMountsFor=/var /run
-ConditionPathExists=!/var/run/ssh/ssh_host_rsa_key
-ConditionPathExists=!/var/run/ssh/ssh_host_dsa_key
-ConditionPathExists=!/var/run/ssh/ssh_host_ecdsa_key
-ConditionPathExists=!/var/run/ssh/ssh_host_ed25519_key
-ConditionPathExists=!/etc/ssh/ssh_host_rsa_key
-ConditionPathExists=!/etc/ssh/ssh_host_dsa_key
-ConditionPathExists=!/etc/ssh/ssh_host_ecdsa_key
-ConditionPathExists=!/etc/ssh/ssh_host_ed25519_key
 
 [Service]
-Environment="SYSCONFDIR=/etc/ssh"
-EnvironmentFile=-/etc/default/ssh
-ExecStart=@BASE_BINDIR@/mkdir -p $SYSCONFDIR
-ExecStart=@BINDIR@/ssh-keygen -q -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' -t rsa
-ExecStart=@BINDIR@/ssh-keygen -q -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' -t dsa
-ExecStart=@BINDIR@/ssh-keygen -q -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' -t ecdsa
-ExecStart=@BINDIR@/ssh-keygen -q -f ${SYSCONFDIR}/ssh_host_ed25519_key -N '' -t ed25519
+ExecStart=@LIBEXECDIR@/sshd_check_keys
 Type=oneshot
 RemainAfterExit=yes
meta/recipes-connectivity/openssh/openssh_7.4p1.bb +8 -0
index c8093d4e2b..e501eadd63 100644
@@ -25,6 +25,7 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
            file://openssh-7.1p1-conditional-compile-des-in-cipher.patch \
            file://openssh-7.1p1-conditional-compile-des-in-pkcs11.patch \
            file://fix-potential-signed-overflow-in-pointer-arithmatic.patch \
+           file://sshd_check_keys \
            "
 
 PAM_SRC_URI = "file://sshd"
@@ -124,7 +125,13 @@ do_install_append () {
 	sed -i -e 's,@BASE_BINDIR@,${base_bindir},g' \
 		-e 's,@SBINDIR@,${sbindir},g' \
 		-e 's,@BINDIR@,${bindir},g' \
+		-e 's,@LIBEXECDIR@,${libexecdir}/${BPN},g' \
 		${D}${systemd_unitdir}/system/sshd.socket ${D}${systemd_unitdir}/system/*.service
+
+	sed -i -e 's,@LIBEXECDIR@,${libexecdir}/${BPN},g' \
+		${D}${sysconfdir}/init.d/sshd
+
+	install -D -m 0755 ${WORKDIR}/sshd_check_keys ${D}${libexecdir}/${BPN}/sshd_check_keys
 }
 
 do_install_ptest () {
@@ -139,6 +146,7 @@ FILES_${PN}-scp = "${bindir}/scp.${BPN}"
 FILES_${PN}-ssh = "${bindir}/ssh.${BPN} ${sysconfdir}/ssh/ssh_config"
 FILES_${PN}-sshd = "${sbindir}/sshd ${sysconfdir}/init.d/sshd ${systemd_unitdir}/system"
 FILES_${PN}-sshd += "${sysconfdir}/ssh/moduli ${sysconfdir}/ssh/sshd_config ${sysconfdir}/ssh/sshd_config_readonly ${sysconfdir}/default/volatiles/99_sshd ${sysconfdir}/pam.d/sshd"
+FILES_${PN}-sshd += "${libexecdir}/${BPN}/sshd_check_keys"
 FILES_${PN}-sftp = "${bindir}/sftp"
 FILES_${PN}-sftp-server = "${libexecdir}/sftp-server"
 FILES_${PN}-misc = "${bindir}/ssh* ${libexecdir}/ssh*"
Signature · 1 line
2.14.2