From f1f7d9c3d357d9715ae78e2445321bc1d0081ad1 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 6 Aug 2025 01:54:52 +0200 Subject: [PATCH] cmd/initContainer: Unbreak access to CA certificates in sshd(8) sessions When a Toolbx container is set up to use the p11-kit-client.so PKCS #11 module instead of the usual p11-kit-trust.so module, the P11_KIT_SERVER_ADDRESS environment variable must be set inside the container, so that it can communicate with the host operating system. Currently, this works as described above with the 'enter' and 'run' commands, but not within child sessions started by an sshd(8) [1] instance running inside a container, because P11_KIT_SERVER_ADDRESS is absent. To make this work, sshd(8) [1] must be configured [2] to set P11_KIT_SERVER_ADDRESS in its child sessions. If sshd(8) uses the /etc/ssh/sshd_config.d directory for configuration, then the entry point will automatically do this from now on. This requires at least OpenSSH 8.2, which added support for the 'Include' directive in sshd_config(5) [2,3], and the directive must be used to include the configuration from /etc/ssh/sshd_config.d. Otherwise, the user will have to do it themself. eg., Ubuntu 16.04 Xenial Xerus and 18.04 Bionic Beaver don't use /etc/ssh/sshd_config.d because their OpenSSH is too old [4,5]. Note that the permissions of the /etc/ssh/sshd_config.d directory and its contents differ across operating system distributions. OSes within the Fedora family use 0700 for the directory and 0600 for its contents. Arch Linux and Ubuntu use 0755 and 0644. The entry point tries to follow the permissions used by the distribution. Fallout from 5ed2442214f0eb8d58d1bfc7df50f62328815cb2 [1] https://man7.org/linux/man-pages/man8/sshd.8.html [2] https://man7.org/linux/man-pages/man5/sshd_config.5.html [3] OpenSSH commit c2bd7f74b0e0f3a3 https://github.com/openssh/openssh-portable/commit/c2bd7f74b0e0f3a3 https://bugzilla.mindrot.org/show_bug.cgi?id=2468 [4] https://code.launchpad.net/~git-ubuntu-import/ubuntu/+source/openssh/+git/openssh/+ref/ubuntu/xenial-updates [5] https://code.launchpad.net/~git-ubuntu-import/ubuntu/+source/openssh/+git/openssh/+ref/ubuntu/bionic-updates https://github.com/containers/toolbox/issues/626 https://github.com/containers/toolbox/issues/1674 --- src/cmd/initContainer.go | 56 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go index b617f9d..cac4ddf 100644 --- a/src/cmd/initContainer.go +++ b/src/cmd/initContainer.go @@ -600,10 +600,11 @@ func configurePKCS11(targetUser *user.User) error { } } - if path, err := utils.GetP11KitServerSocket(targetUser); err != nil { + serverSocket, err := utils.GetP11KitServerSocket(targetUser) + if err != nil { return err - } else if !utils.PathExists(path) { - logrus.Debugf("%s: socket %s not found", logPrefix, path) + } else if !utils.PathExists(serverSocket) { + logrus.Debugf("%s: socket %s not found", logPrefix, serverSocket) logrus.Debugf("%s: skipping", logPrefix) return nil } @@ -622,6 +623,10 @@ func configurePKCS11(targetUser *user.User) error { return fmt.Errorf("failed to configure PKCS #11 to read from the host: %w", err) } + if err := configureSSHD(serverSocket); err != nil { + return err + } + return nil } @@ -647,6 +652,51 @@ func configureRPM() error { return nil } +func configureSSHD(p11KitServerSocket string) error { + const logPrefix = "Configuring sshd(8) to set P11_KIT_SERVER_ADDRESS" + logrus.Debugf("%s", logPrefix) + + sshdConfigD := "/etc/ssh/sshd_config.d" + fileInfo, err := os.Stat(sshdConfigD) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + logrus.Debugf("%s: directory %s not found", logPrefix, sshdConfigD) + logrus.Debugf("%s: skipping", logPrefix) + return nil + } else { + logrus.Debugf("%s: failed to stat %s: %s", logPrefix, sshdConfigD, err) + return fmt.Errorf("failed to stat %s", sshdConfigD) + } + } + + fileMode := fileInfo.Mode() + if !fileMode.IsDir() { + logrus.Debugf("%s: directory %s not found", logPrefix, sshdConfigD) + logrus.Debugf("%s: skipping", logPrefix) + return nil + } + + sshdConfig := filepath.Join(sshdConfigD, "90-toolbx.conf") + + var builder strings.Builder + fmt.Fprintf(&builder, "# Written by Toolbx\n") + fmt.Fprintf(&builder, "# https://containertoolbx.org/\n") + fmt.Fprintf(&builder, "\n") + fmt.Fprintf(&builder, "SetEnv P11_KIT_SERVER_ADDRESS=unix:path=%s\n", p11KitServerSocket) + + sshdConfigString := builder.String() + sshdConfigBytes := []byte(sshdConfigString) + + filePerm := fileMode.Perm() + filePerm = filePerm & 0666 + + if err := renameio.WriteFile(sshdConfig, sshdConfigBytes, filePerm); err != nil { + return fmt.Errorf("failed to configure sshd(8) to set P11_KIT_SERVER_ADDRESS: %w", err) + } + + return nil +} + func configureUsers(targetUserUid int, targetUser, targetUserHome, targetUserShell string, homeLink bool) error { if homeLink { if err := redirectPath("/home", "/var/home", true); err != nil {