]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ssh-generator: create privsep dir via tmpfiles.d/ if we are told to
authorLennart Poettering <lennart@poettering.net>
Fri, 1 Mar 2024 10:25:52 +0000 (11:25 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 3 Apr 2024 16:01:10 +0000 (01:01 +0900)
To make it easy to have a workable ssh-generator on various distros,
let's optionally generate the ssh privsep dir via tmpfiles.d/ drop-in.

This enables the concept with a path of /run/sshd/ as default. This is
the path Debian/Ubuntu uses, and means that we just work on those
distros. Debian/Ubuntu is the only distro (apparently?) that puts the
privsep dir under /run/, hence always needs the dir to be created
manually. Other distros don't need it that much, because they place the
dir in /usr/ (fedora, best choice!) or /var/ (others, not ideal, because
still mutable).

Also adds a longer explanation about this in NEWS, in the hope that
distro maintaines read that and maybe start cleaning this up.

Alternative to: #31543

NEWS
meson.build
meson_options.txt
tmpfiles.d/20-systemd-ssh-generator.conf.in

diff --git a/NEWS b/NEWS
index 7014e7582af84316544143edf06381ae2ce76d4a..9b3933f32f8140b3f82d76869273a32a0f4b77cb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -474,6 +474,82 @@ CHANGES WITH 256 in spe:
           https://systemd.io.
 
 
+        * A small new unit generator "systemd-ssh-generator" has been added. It
+          checks if the sshd binary is installed. If so, it binds it via
+          per-connection socket activation to various sockets depending on the
+          execution context:
+
+            • If the system is run in a VM providing AF_VSOCK support, it
+              automatically binds sshd to AF_VSOCK port 22.
+
+            • If the system is invoked as a full-OS container and the container
+              manager pre-mounts a directory /run/host/unix-export/, it will
+              bind sshd to an AF_UNIX socket /run/host/unix-export/ssh. The
+              idea is the container manager bind mounts the directory to an
+              appropriate place on the host as well, so that the AF_UNIX socket
+              may be used to easily connect from the host to the container.
+
+            • sshd is also bound to an AF_UNIX socket
+              /run/ssh-unix-local/socket, which may be to use ssh/sftp in a
+              "sudo"-like fashion to access resources of other local users.
+
+            • Via the kernel command line option "systemd.ssh_listen=" and the
+              system credential "ssh.listen" sshd may be bound to additional,
+              explicitly configured options, including AF_INET/AF_INET6 ports.
+
+          In particular the first two mechanisms should make dealing with local
+          VMs and full OS containers a lot easier, as SSH connections will
+          *just* *work* from the host – even if no networking is available
+          whatsoever.
+
+          systemd-ssh-generator optionally generates a per-connection
+          socket activation service file wrapping sshd. This is only done if
+          the distribution does not provide one on its own under the name
+          "sshd@.service". The generated unit only works correctly if the SSH
+          privilege separation ("privsep") directory exists. Unfortunately
+          distributions vary wildly where they place this directory. An
+          incomprehensive list:
+
+            • /usr/share/empty.sshd/  (new fedora)
+            • /var/empty/
+            • /var/empty/sshd/
+            • /run/sshd/              (debian/ubuntu?)
+
+          If the SSH privsep directory is placed below /var/ or /run/ care
+          needs to be taken that the directory is created automatically at boot
+          if needed, since these directories possibly or always come up
+          empty. This can be done via a tmpfiles.d/ drop-in. You may use the
+          "sshdprivsepdir" meson option provided by systemd to configure the
+          directory, in case you want systemd to create the directory as needed
+          automatically, if your distribution does not cover this natively.
+
+          Recommendations to distributions, in order to make things just work:
+
+            • Please provide a per-connection SSH service file under the name
+              "sshd@.service".
+
+            • Please move the SSH privsep dir into /usr/ (so that it is truly
+              immutable on image-based operating systems, is strictly under
+              package manager control, and never requires recreation if the
+              system boots up with an empty /run/ or /var/).
+
+            • As an extension of this: please consider following Fedora's lead
+              here, and use /usr/share/empty.sshd/ to minimize needless
+              differences between distributions.
+
+            • If your distribution insists on placing the directory in /var/ or
+              /run/ then please at least provide a tmpfiles.d/ drop-in to
+              recreate it automatically at boot, so that the sshd binary just
+              works, regardless in which context it is called.
+
+        * A small tool "systemd-ssh-proxy" has been added, which is supposed to
+          act as counterpart to "systemd-ssh-generator". It's a small plug-in
+          for the SSH client (via ProxyCommand/ProxyUseFdpass) to allow it to
+          connect to AF_VSOCK or AF_UNIX sockets. Example: "ssh vsock/4711"
+          connects to a local VM with cid 4711, or "ssh
+          unix/run/ssh-unix-local/socket" to connect to the local host via the
+          AF_UNIX socket /run/ssh-unix-local/socket.
+
 CHANGES WITH 255:
 
         Announcements of Future Feature Removals and Incompatible Changes:
index 64dde576800f033c0fd58373510929f8378986bb..f4b382c602391bdc5e03e946f183745d77bd9327 100644 (file)
@@ -210,6 +210,10 @@ if sshdconfdir == ''
         sshdconfdir = sysconfdir / 'ssh/sshd_config.d'
 endif
 
+sshdprivsepdir = get_option('sshdprivsepdir')
+conf.set10('CREATE_SSHDPRIVSEPDIR', sshdprivsepdir != 'no' and not sshdprivsepdir.startswith('/usr/'))
+conf.set('SSHDPRIVSEPDIR', sshdprivsepdir, description : 'SSH privilege separation directory')
+
 libcryptsetup_plugins_dir = get_option('libcryptsetup-plugins-dir')
 if libcryptsetup_plugins_dir == ''
         libcryptsetup_plugins_dir = libdir / 'cryptsetup'
@@ -2723,6 +2727,7 @@ summary({
         'PAM modules directory' :           pamlibdir,
         'PAM configuration directory' :     pamconfdir,
         'ssh server configuration directory' : sshdconfdir,
+        'ssh server privilege separation directory' : sshdprivsepdir,
         'ssh client configuration directory' : sshconfdir,
         'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
         'RPM macros directory' :            rpmmacrosdir,
index 3a3ab6e7c1a3c1b6c0f7384aac08e6166efeff27..af9a0065636474c877466783d362c34247e7321a 100644 (file)
@@ -215,6 +215,8 @@ option('sshconfdir', type : 'string',
        description : 'directory for SSH client configuration ["no" disables]')
 option('sshdconfdir', type : 'string',
        description : 'directory for SSH server configuration ["no" disables]')
+option('sshdprivsepdir', type : 'string',
+       description : 'directory for SSH privilege separation ["no" disables]', value : '/run/sshd')
 option('libcryptsetup-plugins-dir', type : 'string',
        description : 'directory for libcryptsetup plugins')
 option('docdir', type : 'string',
index 033379ec7a446c10d07b64895fbcb91bdfc9fd34..6d1a6a3e3198e504d44b62d98d7ae28da8e3fed4 100644 (file)
@@ -8,3 +8,6 @@
 # See tmpfiles.d(5) for details
 
 L {{SSHCONFDIR}}/20-systemd-ssh-proxy.conf - - - - {{LIBEXECDIR}}/ssh_config.d/20-systemd-ssh-proxy.conf
+{% if CREATE_SSHDPRIVSEPDIR %}
+d {{SSHDPRIVSEPDIR}} 0755
+{% endif %}