Noticed on one of my FreeBSD appliances that there was an ability to control which SSH HostKey types get generated during service sshd start/stop. Looking into the init script on my Gentoo boxes, we unconditionally call "ssh-keygen -A" to generate all possible HostKey types, regardless if they are actually enabled in sshd_config or not. I also noticed there is an undocumented key type called "XMSS", which is an experimental post-quantum algorithm. It is not listed in the ssh-keygen manpages, and so by blindly calling ssh-keygen -A, this leads to /etc/ssh/ssh_host_xmss_key* files being created. Attached are two patches, one against $FILESDIR/sshd-r2.initd to highlight the changes to enable control of HostKey algorithms. The full script is also attached and can go in as $FILESDIR/sshd-r3.initd. A second patch is against $FILESDIR/sshd-r1.confd to highlight the five new rcvars, which are defaulted to "YES" and commented out (the init script also defaults them to YES). A fully-modified confd file is attached and can go in as $FILESDIR/sshd-r2.confd. These changes are only for the OpenRC init system. I don't have any experience working w/ systemd to craft a similar set of changes there. I did not add an ability to tweak the algo parameters of the HostKey generation, but that would be trivial to add.
Created attachment 763086 [details, diff] Patch against sshd-r2.initd to highlight core changes
Created attachment 763087 [details, diff] Patch against sshd-r1.confd to highlight core changes
Created attachment 763088 [details] sshd-r3.initd
Created attachment 763089 [details] sshd-r2.confd
Heh, I was wondering about this yesterday (didn't look into it at all) as I watched DSA keys get generated on a rather slow box :)
We started calling ssh-keygen -A to simplify things and make it consistent with systemd. See bug 457026. https://gitweb.gentoo.org/archive/repo/gentoo-2.git/commit/?id=748d355bb284f0a2d39e1b19c043f05f7bb47a96 I'm not sure it makes sense to enumerate every possible type of host key in the init script. Maybe an alternative would be to provide some way to disable host key generation and leave it up to the sysadmin.
Another alternative: Introduce a single variable containing a list of host key types. If the variable is empty, default to calling ssh-keygen -A. Otherwise loop over the list, calling ssh-keygen for each key type. This would allow the sysadmin to control the enabled key types without requiring us to update the init script whenever a new key type is introduced upstream. For systemd, I plan to move ssh-keygen to a separate service file to resolve bug 501708. The sysadmin could simply override the service file to generate specific key types if desired.
(In reply to Mike Gilbert from comment #7) > Another alternative: Introduce a single variable containing a list of host > key types. If the variable is empty, default to calling ssh-keygen -A. > Otherwise loop over the list, calling ssh-keygen for each key type. > > This would allow the sysadmin to control the enabled key types without > requiring us to update the init script whenever a new key type is introduced > upstream. > > For systemd, I plan to move ssh-keygen to a separate service file to resolve > bug 501708. The sysadmin could simply override the service file to generate > specific key types if desired. This sounds reasonable. Let me study up on parsing such a variable in a loop in classic Bourne Shell and I'll refresh the patches/files that I attached. The 'gen_hostkeys' function can pretty much stay the same; all that would be changing is the spot in checkconfig to call gen_hostkeys in a loop instead of coding the explicit keytypes.
Something like this should work: > if [ -z "${SSHD_HOSTKEY_TYPES}" ]; then > ssh-keygen -A || return 2 > else > local kt > for kt in ${SSHD_HOSTKEY_TYPES}; do > ssh-keygen -t "${kt}" -f "${SSH_CONFDIR}/ssh_host_${kd}_key" || return 2 > done > fi
(In reply to Mike Gilbert from comment #9) > Something like this should work: > > > if [ -z "${SSHD_HOSTKEY_TYPES}" ]; then > > ssh-keygen -A || return 2 > > else > > local kt > > for kt in ${SSHD_HOSTKEY_TYPES}; do > > ssh-keygen -t "${kt}" -f "${SSH_CONFDIR}/ssh_host_${kd}_key" || return 2 > > done > > fi I was thinking how much effort should go towards validation of the input in the conf.d variable, given that this variable isn't exactly a yes/no flag. To that end, I went looking and none of the ssh tools have an ability to report the available keytypes that are accepted by the '-t' flag to ssh-keygen. Closest I can get is 'ssh -Q HostKeyAlgorithms', which returns the specific list of keys versus their general key families. But that is workable, to an extent, if one applies some regex/sort/uniq: Full list of specific keys: # ssh -Q key ssh-ed25519 ssh-ed25519-cert-v01@openssh.com sk-ssh-ed25519@openssh.com sk-ssh-ed25519-cert-v01@openssh.com ssh-xmss@openssh.com ssh-xmss-cert-v01@openssh.com ssh-rsa ssh-dss ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521 sk-ecdsa-sha2-nistp256@openssh.com ssh-rsa-cert-v01@openssh.com ssh-dss-cert-v01@openssh.com ecdsa-sha2-nistp256-cert-v01@openssh.com ecdsa-sha2-nistp384-cert-v01@openssh.com ecdsa-sha2-nistp521-cert-v01@openssh.com sk-ecdsa-sha2-nistp256-cert-v01@openssh.com Key families: # ssh -Q HostKeyAlgorithms | \ sed -E -e 's/(s(ha2|k|sh)|(nistp|cert-v)[0-9]+|webauthn|@.+|-)//g' \ -e 's/rsa[0-9]+/rsa/g' \ -e 's/dss/dsa/g' | sort | uniq dsa ecdsa ed25519 rsa xmss Maybe swap the newlines for spaces and that output can be used to validate that the list of tokens put into the conf.d variable is accurate and won't lead to a system not starting up correctly. That said, this might be going into overkill territory (something I am very gifted at doing), but I figured I'd get some input. Going this route, we can catch and validate unknown/misspelled keytypes as well as when a keytype gets deprecated and removed (as DSA ones will soon be). When that happens, checkconfig can detect and warn before stopping sshd. Downside, the sed formula will need periodic maintenance to make sure it correctly scrubs the 'ssh -Q' output to get the keys filtered down to their family. There does not seem to be any defined consistency in the formatting of the full key names, so the sed approach seems to work best. Upside, addition or removal of key families are exceptionally rare. I think 'ed25519' was the last new family officially added a number of years ago before XMSS, and DSA will be one of the first removals in some time. So my hope is the sed formula would not require much maintenance at all. Thoughts?
That seems like added complexity for nearly no benefit. Just let ssh-keygen fail if the user specifies an invalid key type.
Created attachment 763442 [details, diff] Patch against sshd-r2.initd to highlight core changes v2
Created attachment 763443 [details, diff] Patch against sshd-r1.confd to highlight core changes v2
Created attachment 763444 [details] sshd-r3.initd v2
Created attachment 763445 [details] sshd-r2.confd v2
(In reply to Mike Gilbert from comment #11) > That seems like added complexity for nearly no benefit. Just let ssh-keygen > fail if the user specifies an invalid key type. Aight, give these a look. I had to make some fixes/tweaks to the loop conditional you proposed, but it all looks to work on my end now. Tested leaving SSHD_HOSTKEY_TYPES blank and got all five keys generated, then tested just two types (ed25519, xmss), and a finally just a single type.
Created attachment 763446 [details] sshd-r2.confd v3
Created attachment 763447 [details, diff] Patch against sshd-r1.confd to highlight core changes v3
This would be really awesome to have! The proposed patches work for me (tested both with SSHD_HOSTKEY_TYPES="" and SSHD_HOSTKEY_TYPES="ed25519 rsa", which is what I want to use). Is there anything I can do to help?