diff --git a/bootstrapvz/common/assets/init.d/generate-ssh-hostkeys b/bootstrapvz/common/assets/init.d/generate-ssh-hostkeys index 297cf21..cb51e3d 100644 --- a/bootstrapvz/common/assets/init.d/generate-ssh-hostkeys +++ b/bootstrapvz/common/assets/init.d/generate-ssh-hostkeys @@ -1,36 +1,14 @@ #!/bin/sh -### BEGIN INIT INFO -# Provides: generate-ssh-hostkeys -# Required-Start: $local_fs -# Required-Stop: -# Should-Start: -# Should-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: -# Description: Generate ssh host keys if they do not exist -### END INIT INFO +# Kept for backward compatibility. OpenSSH Host Keys are generated +# by "ssh-generate-hostkeys.service" systemd unit or "ssh-generate-hostkeys" +# sysvinit script (#431). -prog=$(basename $0) -logger="logger -t $prog" +set -eu -rsa_key="/etc/ssh/ssh_host_rsa_key" -ecdsa_key="/etc/ssh/ssh_host_ecdsa_key" -ed25519_key="/etc/ssh/ssh_host_ed25519_key" - -# Exit if the hostkeys already exist -if [ -f $rsa_key -a -f $ecdsa_key -a -f $ed25519_key ]; then - exit +if [ -z "${1+x}" ] || [ -z "$1" ]; then + PAR="start" +else + PAR="$1" fi -# Generate the ssh host keys -[ -f $rsa_key ] || ssh-keygen -f $rsa_key -t rsa -C 'host' -N '' -[ -f $ecdsa_key ] || ssh-keygen -f $ecdsa_key -t ecdsa -C 'host' -N '' -[ -f $ed25519_key ] || ssh-keygen -f $ed25519_key -t ed25519 -C 'host' -N '' - -# Output the public keys to the console -# This allows user to get host keys securely through console log -echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" | $logger -ssh-keygen -l -f $rsa_key.pub | $logger -ssh-keygen -l -f $ecdsa_key.pub | $logger -ssh-keygen -l -f $ed25519_key.pub | $logger -echo "------END SSH HOST KEY FINGERPRINTS------" | $logger +exec /etc/init.d/ssh-generate-hostkeys "$PAR" diff --git a/bootstrapvz/common/assets/init.d/ssh-generate-hostkeys b/bootstrapvz/common/assets/init.d/ssh-generate-hostkeys new file mode 100644 index 0000000..b048555 --- /dev/null +++ b/bootstrapvz/common/assets/init.d/ssh-generate-hostkeys @@ -0,0 +1,36 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: ssh-generate-hostkeys +# Required-Start: $local_fs $syslog +# Required-Stop: +# X-Start-Before: ssh +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: Generate ssh host keys if they do not exist +# Description: Generate ssh host keys if they do not exist. +# This is part of bootstrap-vz: http://github.com/andsens/bootstrap-vz +# See https://github.com/andsens/bootstrap-vz/blob/master/LICENSE for +# legal notices and disclaimers. +### END INIT INFO + +set -e + +DAEMON=/usr/local/sbin/ssh-generate-hostkeys + +[ -x "$DAEMON" ] || exit 0 + +. /lib/lsb/init-functions + +case "$1" in + start) + $DAEMON + exit $? + ;; + stop|restart|reload|force-reload|status) + ;; + *) + echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 + exit 1 +esac + +exit 0 diff --git a/bootstrapvz/common/assets/ssh-generate-hostkeys b/bootstrapvz/common/assets/ssh-generate-hostkeys new file mode 100644 index 0000000..59c2402 --- /dev/null +++ b/bootstrapvz/common/assets/ssh-generate-hostkeys @@ -0,0 +1,19 @@ +#!/bin/sh + +set -eu + +prog="$(basename $0)" +logger="logger -t ${prog}" + +# Output the public keys to the console. +# This allows user to get host keys securely through console log. + +echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" | ${logger} +for key in ecdsa ed25519 rsa; do + keyfile="/etc/ssh/ssh_host_${key}_key" + if [ ! -f "${keyfile}" ]; then + /usr/bin/ssh-keygen -f "${keyfile}" -t "${key}" -C 'host' -N '' + fi + /usr/bin/ssh-keygen -l -f "${keyfile}.pub" | ${logger} +done +echo "------END SSH HOST KEY FINGERPRINTS------" | ${logger} diff --git a/bootstrapvz/common/assets/systemd/ssh-generate-hostkeys.service b/bootstrapvz/common/assets/systemd/ssh-generate-hostkeys.service new file mode 100644 index 0000000..8204c48 --- /dev/null +++ b/bootstrapvz/common/assets/systemd/ssh-generate-hostkeys.service @@ -0,0 +1,13 @@ +[Unit] +Description=OpenBSD Secure Shell server Host Key Generation +ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ecdsa_key +ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ed25519_key +ConditionFileNotEmpty=|!/etc/ssh/ssh_host_rsa_key +Before=ssh.service + +[Service] +ExecStart=/usr/local/sbin/ssh-generate-hostkeys +Type=oneshot + +[Install] +WantedBy=multi-user.target diff --git a/bootstrapvz/common/tasks/ssh.py b/bootstrapvz/common/tasks/ssh.py index 8458c5a..1c5c651 100644 --- a/bootstrapvz/common/tasks/ssh.py +++ b/bootstrapvz/common/tasks/ssh.py @@ -4,6 +4,7 @@ from ..tools import log_check_call import os.path from . import assets import initd +import shutil class AddOpenSSHPackage(Task): @@ -23,6 +24,7 @@ class AddSSHKeyGeneration(Task): @classmethod def run(cls, info): init_scripts_dir = os.path.join(assets, 'init.d') + systemd_dir = os.path.join(assets, 'systemd') install = info.initd['install'] from subprocess import CalledProcessError try: @@ -38,7 +40,29 @@ class AddSSHKeyGeneration(Task): elif info.manifest.release == jessie: install['generate-ssh-hostkeys'] = os.path.join(init_scripts_dir, 'jessie/generate-ssh-hostkeys') else: - install['generate-ssh-hostkeys'] = os.path.join(init_scripts_dir, 'generate-ssh-hostkeys') + install['ssh-generate-hostkeys'] = os.path.join(init_scripts_dir, 'ssh-generate-hostkeys') + + ssh_keygen_host_service = os.path.join(systemd_dir, 'ssh-generate-hostkeys.service') + ssh_keygen_host_service_dest = os.path.join(info.root, 'etc/systemd/system/ssh-generate-hostkeys.service') + + ssh_keygen_host_initscript = os.path.join(init_scripts_dir, 'generate-ssh-hostkeys') + ssh_keygen_host_initscript_dest = os.path.join(info.root, 'etc/init.d/generate-ssh-hostkeys') + + ssh_keygen_host_script = os.path.join(assets, 'ssh-generate-hostkeys') + ssh_keygen_host_script_dest = os.path.join(info.root, 'usr/local/sbin/ssh-generate-hostkeys') + + # Copy files over + shutil.copy(ssh_keygen_host_service, ssh_keygen_host_service_dest) + + shutil.copy(ssh_keygen_host_initscript, ssh_keygen_host_initscript_dest) + os.chmod(ssh_keygen_host_initscript_dest, 0755) + + shutil.copy(ssh_keygen_host_script, ssh_keygen_host_script_dest) + os.chmod(ssh_keygen_host_script_dest, 0750) + + # Enable systemd service + log_check_call(['chroot', info.root, 'systemctl', 'enable', 'ssh-generate-hostkeys.service']) + except CalledProcessError: import logging logging.getLogger(__name__).warn('The OpenSSH server has not been installed, '