Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 831762

Summary: net-misc/openssh: Modify OpenRC init script to enable control of SSH HostKey algorithm generation
Product: Gentoo Linux Reporter: Joshua Kinard <kumba>
Component: Current packagesAssignee: Gentoo's Team for Core System packages <base-system>
Status: CONFIRMED ---    
Severity: enhancement CC: sam
Priority: Normal Keywords: PATCH
Version: unspecified   
Hardware: All   
OS: Linux   
See Also: https://bugs.gentoo.org/show_bug.cgi?id=457026
https://bugs.gentoo.org/show_bug.cgi?id=501708
Whiteboard:
Package list:
Runtime testing required: ---
Attachments: Patch against sshd-r2.initd to highlight core changes
Patch against sshd-r1.confd to highlight core changes
sshd-r3.initd
sshd-r2.confd
Patch against sshd-r2.initd to highlight core changes v2
Patch against sshd-r1.confd to highlight core changes v2
sshd-r3.initd v2
sshd-r2.confd v2
sshd-r2.confd v3
Patch against sshd-r1.confd to highlight core changes v3

Description Joshua Kinard gentoo-dev 2022-01-22 00:31:41 UTC
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.
Comment 1 Joshua Kinard gentoo-dev 2022-01-22 00:33:07 UTC
Created attachment 763086 [details, diff]
Patch against sshd-r2.initd to highlight core changes
Comment 2 Joshua Kinard gentoo-dev 2022-01-22 00:33:47 UTC
Created attachment 763087 [details, diff]
Patch against sshd-r1.confd to highlight core changes
Comment 3 Joshua Kinard gentoo-dev 2022-01-22 00:35:44 UTC
Created attachment 763088 [details]
sshd-r3.initd
Comment 4 Joshua Kinard gentoo-dev 2022-01-22 00:36:05 UTC
Created attachment 763089 [details]
sshd-r2.confd
Comment 5 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2022-01-22 00:46:47 UTC
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 :)
Comment 6 Mike Gilbert gentoo-dev 2022-01-22 13:57:09 UTC
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.
Comment 7 Mike Gilbert gentoo-dev 2022-01-22 14:25:21 UTC
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.
Comment 8 Joshua Kinard gentoo-dev 2022-01-22 22:32:20 UTC
(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.
Comment 9 Mike Gilbert gentoo-dev 2022-01-23 01:09:30 UTC
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
Comment 10 Joshua Kinard gentoo-dev 2022-01-23 09:30:12 UTC
(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?
Comment 11 Mike Gilbert gentoo-dev 2022-01-23 19:11:17 UTC
That seems like added complexity for nearly no benefit. Just let ssh-keygen fail if the user specifies an invalid key type.
Comment 12 Joshua Kinard gentoo-dev 2022-01-24 00:55:11 UTC
Created attachment 763442 [details, diff]
Patch against sshd-r2.initd to highlight core changes v2
Comment 13 Joshua Kinard gentoo-dev 2022-01-24 00:55:52 UTC
Created attachment 763443 [details, diff]
Patch against sshd-r1.confd to highlight core changes v2
Comment 14 Joshua Kinard gentoo-dev 2022-01-24 00:56:24 UTC
Created attachment 763444 [details]
sshd-r3.initd v2
Comment 15 Joshua Kinard gentoo-dev 2022-01-24 00:56:50 UTC
Created attachment 763445 [details]
sshd-r2.confd v2
Comment 16 Joshua Kinard gentoo-dev 2022-01-24 00:58:33 UTC
(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.
Comment 17 Joshua Kinard gentoo-dev 2022-01-24 01:13:59 UTC
Created attachment 763446 [details]
sshd-r2.confd v3
Comment 18 Joshua Kinard gentoo-dev 2022-01-24 01:15:15 UTC
Created attachment 763447 [details, diff]
Patch against sshd-r1.confd to highlight core changes v3
Comment 19 MW 2023-08-06 13:10:06 UTC
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?