import-creds: add support for binary credentials specified on the kernel cmdline
This commit is contained in:
parent
49850c1ee3
commit
de70ecb328
7 changed files with 37 additions and 11 deletions
|
@ -322,10 +322,11 @@ services where they are ultimately consumed.
|
||||||
be sure they can be accessed securely from initrd context.
|
be sure they can be accessed securely from initrd context.
|
||||||
|
|
||||||
4. Credentials can also be passed into a system via the kernel command line,
|
4. Credentials can also be passed into a system via the kernel command line,
|
||||||
via the `systemd.set-credential=` kernel command line option. Note though
|
via the `systemd.set_credential=` and `systemd.set_credential_binary=`
|
||||||
that any data specified here is visible to all userspace applications (even
|
kernel command line options (the latter takes Base64 encoded binary
|
||||||
unprivileged ones) via `/proc/cmdline`. Typically, this is hence not useful
|
data). Note though that any data specified here is visible to all userspace
|
||||||
to pass sensitive information, and should be avoided.
|
applications (even unprivileged ones) via `/proc/cmdline`. Typically, this
|
||||||
|
is hence not useful to pass sensitive information, and should be avoided.
|
||||||
|
|
||||||
Credentials passed to the system may be enumerated/displayed via `systemd-creds
|
Credentials passed to the system may be enumerated/displayed via `systemd-creds
|
||||||
--system`. They may also be propagated down to services, via the
|
--system`. They may also be propagated down to services, via the
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
<term><varname>systemd.setenv=</varname></term>
|
<term><varname>systemd.setenv=</varname></term>
|
||||||
<term><varname>systemd.machine_id=</varname></term>
|
<term><varname>systemd.machine_id=</varname></term>
|
||||||
<term><varname>systemd.set_credential=</varname></term>
|
<term><varname>systemd.set_credential=</varname></term>
|
||||||
|
<term><varname>systemd.set_credential_binary=</varname></term>
|
||||||
<term><varname>systemd.import_credentials=</varname></term>
|
<term><varname>systemd.import_credentials=</varname></term>
|
||||||
<term><varname>systemd.reload_limit_interval_sec=</varname></term>
|
<term><varname>systemd.reload_limit_interval_sec=</varname></term>
|
||||||
<term><varname>systemd.reload_limit_burst=</varname></term>
|
<term><varname>systemd.reload_limit_burst=</varname></term>
|
||||||
|
|
|
@ -3285,7 +3285,8 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||||
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
from the initrd (see
|
from the initrd (see
|
||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>), or be
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>), or be
|
||||||
specified on the kernel command line using the <literal>systemd.set_credential=</literal> switch (see
|
specified on the kernel command line using the <literal>systemd.set_credential=</literal> and
|
||||||
|
<literal>systemd.set_credential_binary=</literal> switches (see
|
||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> – this is
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> – this is
|
||||||
not recommended since unprivileged userspace can read the kernel command line). </para>
|
not recommended since unprivileged userspace can read the kernel command line). </para>
|
||||||
|
|
||||||
|
|
|
@ -932,12 +932,15 @@
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>systemd.set_credential=</varname></term>
|
<term><varname>systemd.set_credential=</varname></term>
|
||||||
|
<term><varname>systemd.set_credential_binary=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Sets a system credential, which can then be propagated to system services using the
|
<listitem><para>Sets a system credential, which can then be propagated to system services using the
|
||||||
<varname>ImportCredential=</varname> or <varname>LoadCredential=</varname> setting, see
|
<varname>ImportCredential=</varname> or <varname>LoadCredential=</varname> setting, see
|
||||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
||||||
details. Takes a pair of credential name and value, separated by a colon. Note that the kernel
|
details. Takes a pair of credential name and value, separated by a colon. The
|
||||||
command line is typically accessible by unprivileged programs in
|
<varname>systemd.set_credential=</varname> parameter expects the credential value in literal text
|
||||||
|
form, the <varname>systemd.set_credential_binary=</varname> parameter takes binary data encoded in
|
||||||
|
Base64. Note that the kernel command line is typically accessible by unprivileged programs in
|
||||||
<filename>/proc/cmdline</filename>. Thus, this mechanism is not suitable for transferring sensitive
|
<filename>/proc/cmdline</filename>. Thus, this mechanism is not suitable for transferring sensitive
|
||||||
data. Use it only for data that is not sensitive (e.g. public keys/certificates, rather than private
|
data. Use it only for data that is not sensitive (e.g. public keys/certificates, rather than private
|
||||||
keys), or in testing/debugging environments.</para>
|
keys), or in testing/debugging environments.</para>
|
||||||
|
|
|
@ -278,15 +278,21 @@ static int import_credentials_boot(void) {
|
||||||
|
|
||||||
static int proc_cmdline_callback(const char *key, const char *value, void *data) {
|
static int proc_cmdline_callback(const char *key, const char *value, void *data) {
|
||||||
ImportCredentialContext *c = ASSERT_PTR(data);
|
ImportCredentialContext *c = ASSERT_PTR(data);
|
||||||
|
_cleanup_free_ void *binary = NULL;
|
||||||
_cleanup_free_ char *n = NULL;
|
_cleanup_free_ char *n = NULL;
|
||||||
_cleanup_close_ int nfd = -EBADF;
|
_cleanup_close_ int nfd = -EBADF;
|
||||||
const char *colon;
|
const char *colon, *d;
|
||||||
|
bool base64;
|
||||||
size_t l;
|
size_t l;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(key);
|
assert(key);
|
||||||
|
|
||||||
if (!proc_cmdline_key_streq(key, "systemd.set_credential"))
|
if (proc_cmdline_key_streq(key, "systemd.set_credential"))
|
||||||
|
base64 = false;
|
||||||
|
else if (proc_cmdline_key_streq(key, "systemd.set_credential_binary"))
|
||||||
|
base64 = true;
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
colon = value ? strchr(value, ':') : NULL;
|
colon = value ? strchr(value, ':') : NULL;
|
||||||
|
@ -305,7 +311,19 @@ static int proc_cmdline_callback(const char *key, const char *value, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
colon++;
|
colon++;
|
||||||
|
|
||||||
|
if (base64) {
|
||||||
|
r = unbase64mem(colon, SIZE_MAX, &binary, &l);
|
||||||
|
if (r < 0) {
|
||||||
|
log_warning_errno(r, "Failed to decode binary credential '%s' data, ignoring: %m", n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = binary;
|
||||||
|
} else {
|
||||||
|
d = colon;
|
||||||
l = strlen(colon);
|
l = strlen(colon);
|
||||||
|
}
|
||||||
|
|
||||||
if (!credential_size_ok(c, n, l))
|
if (!credential_size_ok(c, n, l))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -320,7 +338,7 @@ static int proc_cmdline_callback(const char *key, const char *value, void *data)
|
||||||
if (nfd < 0)
|
if (nfd < 0)
|
||||||
return nfd;
|
return nfd;
|
||||||
|
|
||||||
r = loop_write(nfd, colon, l, /* do_poll= */ false);
|
r = loop_write(nfd, d, l, /* do_poll= */ false);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
(void) unlinkat(c->target_dir_fd, n, 0);
|
(void) unlinkat(c->target_dir_fd, n, 0);
|
||||||
return log_error_errno(r, "Failed to write credential: %m");
|
return log_error_errno(r, "Failed to write credential: %m");
|
||||||
|
|
|
@ -25,6 +25,7 @@ KERNEL_CREDS=(
|
||||||
"systemd.set_credential=sysctl.extra:kernel.domainname=sysctltest"
|
"systemd.set_credential=sysctl.extra:kernel.domainname=sysctltest"
|
||||||
"systemd.set_credential=login.motd:hello"
|
"systemd.set_credential=login.motd:hello"
|
||||||
"systemd.set_credential=login.issue:welcome"
|
"systemd.set_credential=login.issue:welcome"
|
||||||
|
"systemd.set_credential_binary=waldi:d29vb29mZmZ3dWZmZnd1ZmYK"
|
||||||
"rd.systemd.import_credentials=no"
|
"rd.systemd.import_credentials=no"
|
||||||
)
|
)
|
||||||
KERNEL_APPEND="${KERNEL_APPEND:-} ${KERNEL_CREDS[*]}"
|
KERNEL_APPEND="${KERNEL_APPEND:-} ${KERNEL_CREDS[*]}"
|
||||||
|
|
|
@ -176,6 +176,7 @@ if systemd-detect-virt -q -c ; then
|
||||||
elif [ -d /sys/firmware/qemu_fw_cfg/by_name ]; then
|
elif [ -d /sys/firmware/qemu_fw_cfg/by_name ]; then
|
||||||
# Verify that passing creds through kernel cmdline works
|
# Verify that passing creds through kernel cmdline works
|
||||||
[ "$(systemd-creds --system cat kernelcmdlinecred)" = "uff" ]
|
[ "$(systemd-creds --system cat kernelcmdlinecred)" = "uff" ]
|
||||||
|
[ "$(systemd-creds --system cat waldi)" = "woooofffwufffwuff" ]
|
||||||
|
|
||||||
# And that it also works via SMBIOS
|
# And that it also works via SMBIOS
|
||||||
[ "$(systemd-creds --system cat smbioscredential)" = "magicdata" ]
|
[ "$(systemd-creds --system cat smbioscredential)" = "magicdata" ]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue