ssh-generator: introduce ssh-access.target

This new passive target is supposed to be pulled in by SSH
implementations and should be reached when remote SSH access is
possible. The idea is that this target can be used as indicator for
other components to determine if and when SSH access is possible.

One specific usecase for this is the new sd_notify() logic in PID 1 that
sends its own supervisor notifications whenever target units are
reached. This can be used to precisely schedule SSH connections from
host to VM/container, or just to identify systems where SSH is even
available.
This commit is contained in:
Lennart Poettering 2024-03-12 18:44:33 +01:00
parent b2d6bb5b34
commit 95be59f907
4 changed files with 47 additions and 7 deletions

View file

@ -83,6 +83,7 @@
<filename>sockets.target</filename>,
<filename>soft-reboot.target</filename>,
<filename>sound.target</filename>,
<filename>ssh-access.target</filename>,
<filename>storage-target-mode.target</filename>,
<filename>suspend.target</filename>,
<filename>swap.target</filename>,
@ -1172,6 +1173,19 @@
the <literal>$portmap</literal> facility.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>ssh-access.target</filename></term>
<listitem>
<para>Service and socket units that provide remote SSH secure shell access to the local system
should pull in this unit and order themselves before this unit. It's supposed to act as a
milestone indicating if and when SSH access into the system is available. It should only become
active when an SSH port is bound for remote clients (i.e. if SSH is used as a local privilege
escalation mechanism, it should <emphasis>not</emphasis> involve this target unit), regardless of
the protocol choices, i.e. regardless if IPv4, IPv6 or <constant>AF_VSOCK</constant> is
used.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>time-set.target</filename></term>
<listitem>

View file

@ -128,7 +128,8 @@ static int write_socket_unit(
const char *dest,
const char *unit,
const char *listen_stream,
const char *comment) {
const char *comment,
bool with_ssh_access_target_dependency) {
int r;
@ -149,13 +150,21 @@ static int write_socket_unit(
fprintf(f,
"[Unit]\n"
"Description=OpenSSH Server Socket (systemd-ssh-generator, %s)\n"
"Documentation=man:systemd-ssh-generator(8)\n"
"Documentation=man:systemd-ssh-generator(8)\n",
comment);
/* When this is a remotely accessible socket let's mark this with a milestone: ssh-access.target */
if (with_ssh_access_target_dependency)
fputs("Wants=ssh-access.target\n"
"Before=ssh-access.target\n",
f);
fprintf(f,
"\n[Socket]\n"
"ListenStream=%s\n"
"Accept=yes\n"
"PollLimitIntervalSec=30s\n"
"PollLimitBurst=50\n",
comment,
listen_stream);
r = fflush_and_check(f);
@ -230,7 +239,8 @@ static int add_vsock_socket(
dest,
"sshd-vsock.socket",
"vsock::22",
"AF_VSOCK");
"AF_VSOCK",
/* with_ssh_access_target_dependency= */ true);
if (r < 0)
return r;
@ -264,7 +274,8 @@ static int add_local_unix_socket(
dest,
"sshd-unix-local.socket",
"/run/ssh-unix-local/socket",
"AF_UNIX Local");
"AF_UNIX Local",
/* with_ssh_access_target_dependency= */ false);
if (r < 0)
return r;
@ -320,7 +331,8 @@ static int add_export_unix_socket(
dest,
"sshd-unix-export.socket",
"/run/host/unix-export/ssh",
"AF_UNIX Export");
"AF_UNIX Export",
/* with_ssh_access_target_dependency= */ true);
if (r < 0)
return r;
@ -370,7 +382,8 @@ static int add_extra_sockets(
dest,
socket ?: "sshd-extra.socket",
*i,
*i);
*i,
/* with_ssh_access_target_dependency= */ true);
if (r < 0)
return r;

View file

@ -203,6 +203,7 @@ units = [
{ 'file' : 'sockets.target' },
{ 'file' : 'soft-reboot.target' },
{ 'file' : 'sound.target' },
{ 'file' : 'ssh-access.target' },
{
'file' : 'suspend-then-hibernate.target',
'conditions' : ['ENABLE_HIBERNATE'],

12
units/ssh-access.target Normal file
View file

@ -0,0 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=SSH Access Available
Documentation=man:systemd.special(7)