| #! /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 |
| fi |
| |
| [ -z "$SYSCONFDIR" ] && SYSCONFDIR=/etc/ssh |
| mkdir -p $SYSCONFDIR |
| |
| # parse sshd options |
| 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 |
| |
| # parse location of keys |
| 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..." |
| generate_key $HOST_KEY_RSA rsa |
| fi |
| if [ ! -f $HOST_KEY_ECDSA ]; then |
| echo " generating ssh ECDSA key..." |
| generate_key $HOST_KEY_ECDSA ecdsa |
| fi |
| if [ ! -f $HOST_KEY_DSA ]; then |
| echo " generating ssh DSA key..." |
| generate_key $HOST_KEY_DSA dsa |
| fi |
| if [ ! -f $HOST_KEY_ED25519 ]; then |
| echo " generating ssh ED25519 key..." |
| generate_key $HOST_KEY_ED25519 ed25519 |
| fi |
| |