]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ssh-generator: Make sure sshd can always read the authorized keys file
authorDaan De Meyer <daan@amutable.com>
Thu, 28 May 2026 09:26:05 +0000 (09:26 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 29 May 2026 14:12:45 +0000 (16:12 +0200)
sshd reads AuthorizedKeysFile after dropping to the authenticating user's UID, so the
0400 credential file under %d/ is unreadable for non-root users. Materialize a 0444
copy in a RuntimeDirectory so the ephemeral key works for any user. */

src/ssh-generator/ssh-generator.c
src/vmspawn/vmspawn.c

index ae062fc58da476bcc7cd7401b7e0b292dcac80fc..7d67d4178ec89ed484ff6b1ca2c88ca3eefb0f3e 100644 (file)
@@ -109,15 +109,20 @@ static int make_sshd_template_unit(
                 if (r < 0)
                         return r;
 
+                /* sshd reads AuthorizedKeysFile after dropping to the authenticating user's UID, so the
+                 * 0400 credential file under $CREDENTIALS_DIRECTORY is unreadable for non-root users.
+                 * Materialize a 0444 copy in a RuntimeDirectory so the ephemeral key works for any user. */
                 fprintf(f,
                         "[Unit]\n"
                         "Description=OpenSSH Per-Connection Server Daemon\n"
                         "Documentation=man:systemd-ssh-generator(8) man:sshd(8)\n"
                         "\n"
                         "[Service]\n"
-                        "ExecStart=-%s -i -o \"AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys\"\n"
+                        "ExecStartPre=systemd-tmpfiles --create --inline 'f^ /run/sshd-generated-%%i/authorized_keys 0444 root root - ssh.ephemeral-authorized_keys-all'\n"
+                        "ExecStart=-%s -i -o \"AuthorizedKeysFile /run/sshd-generated-%%i/authorized_keys .ssh/authorized_keys\"\n"
                         "StandardInput=socket\n"
-                        "ImportCredential=ssh.ephemeral-authorized_keys-all\n",
+                        "ImportCredential=ssh.ephemeral-authorized_keys-all\n"
+                        "RuntimeDirectory=sshd-generated-%%i\n",
                         sshd_binary);
 
                 r = fflush_and_check(f);
index 0797676bf94bddb581862f7cfa2c3c4bee2134c5..015d35023f6ec542fbe91d45b6f1cc62c14d77af 100644 (file)
@@ -3506,13 +3506,18 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
 
                 /* on distros that provide their own sshd@.service file we need to provide a dropin which
                  * picks up our public key credential */
+                /* sshd reads AuthorizedKeysFile after dropping to the authenticating user's UID, so the
+                 * 0400 credential file under %d/ is unreadable for non-root users. Materialize a 0444
+                 * copy in a RuntimeDirectory so the ephemeral key works for any user. */
                 r = machine_credential_add(
                                 &arg_credentials,
                                 "systemd.unit-dropin.sshd-vsock@.service",
                                 "[Service]\n"
+                                "ExecStartPre=systemd-tmpfiles --create --inline 'f^ /run/sshd-vsock-%i/authorized_keys 0444 root root - ssh.ephemeral-authorized_keys-all'\n"
                                 "ExecStart=\n"
-                                "ExecStart=-sshd -i -o 'AuthorizedKeysFile=%d/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys'\n"
-                                "ImportCredential=ssh.ephemeral-authorized_keys-all\n",
+                                "ExecStart=-sshd -i -o 'AuthorizedKeysFile=/run/sshd-vsock-%i/authorized_keys .ssh/authorized_keys'\n"
+                                "ImportCredential=ssh.ephemeral-authorized_keys-all\n"
+                                "RuntimeDirectory=sshd-vsock-%i\n",
                                 SIZE_MAX);
                 if (r < 0)
                         return log_error_errno(r, "Failed to set credential systemd.unit-dropin.sshd-vsock@.service: %m");