Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 1 | #! /bin/sh |
| 2 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 3 | generate_key() { |
| 4 | local FILE=$1 |
| 5 | local TYPE=$2 |
| 6 | local DIR="$(dirname "$FILE")" |
| 7 | |
| 8 | mkdir -p "$DIR" |
| 9 | ssh-keygen -q -f "${FILE}.tmp" -N '' -t $TYPE |
| 10 | |
| 11 | # Atomically rename file public key |
| 12 | mv -f "${FILE}.tmp.pub" "${FILE}.pub" |
| 13 | |
| 14 | # This sync does double duty: Ensuring that the data in the temporary |
| 15 | # private key file is on disk before the rename, and ensuring that the |
| 16 | # public key rename is completed before the private key rename, since we |
| 17 | # switch on the existence of the private key to trigger key generation. |
| 18 | # This does mean it is possible for the public key to exist, but be garbage |
| 19 | # but this is OK because in that case the private key won't exist and the |
| 20 | # keys will be regenerated. |
| 21 | # |
| 22 | # In the event that sync understands arguments that limit what it tries to |
| 23 | # fsync(), we provided them. If it does not, it will simply call sync() |
| 24 | # which is just as well |
| 25 | sync "${FILE}.pub" "$DIR" "${FILE}.tmp" |
| 26 | |
| 27 | mv "${FILE}.tmp" "$FILE" |
| 28 | |
| 29 | # sync to ensure the atomic rename is committed |
| 30 | sync "$DIR" |
| 31 | } |
| 32 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 33 | # /etc/default/ssh may set SYSCONFDIR and SSHD_OPTS |
| 34 | if test -f /etc/default/ssh; then |
| 35 | . /etc/default/ssh |
| 36 | fi |
| 37 | |
| 38 | [ -z "$SYSCONFDIR" ] && SYSCONFDIR=/etc/ssh |
| 39 | mkdir -p $SYSCONFDIR |
| 40 | |
| 41 | # parse sshd options |
| 42 | set -- ${SSHD_OPTS} -- |
| 43 | sshd_config=/etc/ssh/sshd_config |
| 44 | while true ; do |
| 45 | case "$1" in |
| 46 | -f*) if [ "$1" = "-f" ] ; then |
| 47 | sshd_config="$2" |
| 48 | shift |
| 49 | else |
| 50 | sshd_config="${1#-f}" |
| 51 | fi |
| 52 | shift |
| 53 | ;; |
| 54 | --) shift; break;; |
| 55 | *) shift;; |
| 56 | esac |
| 57 | done |
| 58 | |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 59 | HOST_KEYS=$(sed -n 's/^[ \t]*HostKey[ \t]\+\(.*\)/\1/p' "${sshd_config}") |
| 60 | [ -z "${HOST_KEYS}" ] && HOST_KEYS="$SYSCONFDIR/ssh_host_rsa_key $SYSCONFDIR/ssh_host_ecdsa_key $SYSCONFDIR/ssh_host_ed25519_key" |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 61 | |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 62 | for key in ${HOST_KEYS} ; do |
| 63 | [ -f $key ] && continue |
| 64 | case $key in |
| 65 | *_rsa_key) |
| 66 | echo " generating ssh RSA host key..." |
| 67 | generate_key $key rsa |
| 68 | ;; |
| 69 | *_ecdsa_key) |
| 70 | echo " generating ssh ECDSA host key..." |
| 71 | generate_key $key ecdsa |
| 72 | ;; |
| 73 | *_ed25519_key) |
| 74 | echo " generating ssh ED25519 host key..." |
| 75 | generate_key $key ed25519 |
| 76 | ;; |
| 77 | esac |
| 78 | done |