Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2c2347f
firstboot: harden credential handling a bit
poettering Mar 11, 2026
47b4545
firstboot: permit setting the static hostname via a system credential
poettering Mar 5, 2026
e26654b
macro: split out DEFER_VOID_CALL() into its own header
poettering Mar 5, 2026
a42958e
fileio: introduce write_data_file_atomic_at() helper
poettering Feb 27, 2026
be34e98
udev: tag DMI id device with "systemd", so that we can order units af…
poettering Feb 26, 2026
c749f86
iovec-util: introduce IOVEC_MAKE_BYTE() helper
poettering Feb 26, 2026
93485fd
json-util: add json_dispatch_in6_addr() helper
poettering Feb 26, 2026
0cd86c1
dns-rr: add dns_resource_record_from_json()
poettering Feb 26, 2026
6920752
dns-rr: tighten rules on parsing RR keys from JSON
poettering Feb 26, 2026
24f457d
resolved: also flush /etc/hosts on reload
poettering Mar 4, 2026
5e8275b
resolved: add ability to define additional local RRs via drop-ins
poettering Feb 26, 2026
7df794e
hwdb: add database for basic IMDS properties
poettering Mar 4, 2026
7668b2e
imds: add new systemd-imdsd.service that makes IMDS data accessible l…
poettering Mar 4, 2026
edcb9fd
imds: add "systemd-imds" tool that is a simple client to "systemd-imdsd"
poettering Mar 4, 2026
a2fab8a
imds: add generator that hooks in IMDS logic on cloud guests
poettering Mar 4, 2026
bcee65e
test: add simple integration test for systemd-imdsd
poettering Mar 6, 2026
bcbc906
update TODO
poettering Mar 5, 2026
03b83c6
hwdb: add Oracle Cloud OCI IMDS data
rpigott Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ Features:

* start making use of the new --graceful switch to util-linux' umount command

* sysusers: allow specifying a path to an inode *and* a literal UID in the UID
column, so that if the inode exists it is used, and if not the literal UID is
used. Use this for services such as the imds one, which run under their own
UID in the initrd, and whose data should survive to the host, properly owned.

* add service file setting to force the fwmark (a la SO_MARK) to some value, so
that we can allowlist certain services for imds this way.

* make systemd work nicely without /bin/sh, logins and associated shell tools around
- add a small unit that just prints "boot complete" which we can pull in
wherever we pull in getty@1.service, but is conditioned on /bin/sh being
Expand All @@ -131,6 +139,8 @@ Features:
- make sure debug shell service (sushell) has a nice failure mode, prints a message and reboots
- varlink interface for "systemctl start" and friends

* imds: maybe do smarter api version handling

* drop NV_ORDERLY flag from the product uuid nvpcr. Effect of the flag is that
it pushes the thing into TPM RAM, but a TPM usually has very little of that,
less than NVRAM. hence setting the flag amplifies space issues. Unsetting the
Expand Down
106 changes: 106 additions & 0 deletions hwdb.d/40-imds.hwdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# This file is part of systemd

# This provides various properties that declare if and
# how IMDS is available on the local system, i.e. we are running in a major
# cloud service that provides something resembling AWS' or Azure's Instance
# Metadata Service.
#
# General IMDS endpoint data:
# IMDS_VENDOR= → Indicates IMDS is available, and which vendor it is
# IMDS_TOKEN_URL= → The URL to request an API token from. If not set, no API token is requested.
# IMDS_REFRESH_HEADER_NAME= → The HTTP request header field (everything before the ":") that contains the refresh TTL when requesting a token.
# IMDS_DATA_URL= → The base URL to request actual IMDS data fields from
# IMDS_DATA_URL_SUFFIX= → Parameters to suffix the URLs with
# IMDS_TOKEN_HEADER_NAME= → The HTTP request header field (everything before the ":") used to pass the token
# IMDS_EXTRA_HEADER=, IMDS_EXTRA_HEADER2=, IMDS_EXTRA_HEADER3, …
# → Additional HTTP headers to pass when requesting a data field (full header, including ":")
# IMDS_ADDRESS_IPV4= → IPv4 address of the IMDS server
# IMDS_ADDRESS_IPV6= → IPv6 address of the IMDS server
#
# Well-known IMDS keys:
# IMDS_KEY_HOSTNAME= → IMDS key for the hostname
# IMDS_KEY_REGION= → IMDS key for the region, if that concept applies
# IMDS_KEY_ZONE= → IMDS key for the zone{, if that concept applies
# IMDS_KEY_IPV4_PUBLIC= → IMDS key for the primary public IPv4 address if there is any
# IMDS_KEY_IPV6_PUBLIC= → IMDS key for the primary public IPv6 address if there is any
# IMDS_KEY_SSH_KEY= → IMDS key for an SSH public key to install in the root account
# IMDS_KEY_USERDATA= → IMDS key for arbitrary userdata (if there's only one)
# IMDS_KEY_USERDATA_BASE= → IMDS key for arbitrary userdata (if there are multiple, this is the common prefix)
# IMDS_KEY_USERDATA_BASE64= → IMDS key for arbitrary userdata (if there's only one, but it is base64 encoded)

# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
dmi:bvnAmazonEC2:*
IMDS_VENDOR=amazon-ec2
IMDS_TOKEN_URL=http://169.254.169.254/latest/api/token
IMDS_REFRESH_HEADER_NAME=X-aws-ec2-metadata-token-ttl-seconds
IMDS_DATA_URL=http://169.254.169.254/latest
IMDS_TOKEN_HEADER_NAME=X-aws-ec2-metadata-token
IMDS_ADDRESS_IPV4=169.254.169.254
IMDS_ADDRESS_IPV6=fd00:ec2::254
IMDS_KEY_HOSTNAME=/meta-data/hostname
IMDS_KEY_REGION=/meta-data/placement/region
IMDS_KEY_ZONE=/meta-data/placement/availability-zone
IMDS_KEY_IPV4_PUBLIC=/meta-data/public-ipv4
IMDS_KEY_IPV6_PUBLIC=/meta-data/ipv6
IMDS_KEY_SSH_KEY=/meta-data/public-keys/0/openssh-key
IMDS_KEY_USERDATA=/user-data

# https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service#instance-metadata
dmi:*:cat7783-7084-3265-9085-8269-3286-77:*
IMDS_VENDOR=microsoft-azure
IMDS_DATA_URL=http://169.254.169.254/metadata
IMDS_DATA_URL_SUFFIX=?api-version=2025-04-07&format=text
IMDS_EXTRA_HEADER=Metadata: true
IMDS_ADDRESS_IPV4=169.254.169.254
IMDS_KEY_HOSTNAME=/instance/compute/osProfile/computerName
IMDS_KEY_REGION=/instance/compute/location
IMDS_KEY_ZONE=/instance/compute/physicalZone
IMDS_KEY_IPV4_PUBLIC=/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress
IMDS_KEY_IPV6_PUBLIC=/instance/network/interface/0/ipv6/ipAddress/0/publicIpAddress
IMDS_KEY_SSH_KEY=/instance/compute/publicKeys/0/keyData
IMDS_KEY_USERDATA_BASE64=/instance/compute/userData

# https://docs.cloud.google.com/compute/docs/metadata/predefined-metadata-keys
dmi:*:pnGoogleComputeEngine:*
IMDS_VENDOR=google-gcp
IMDS_DATA_URL=http://169.254.169.254/computeMetadata/v1
IMDS_EXTRA_HEADER=Metadata-Flavor: Google
IMDS_ADDRESS_IPV4=169.254.169.254
IMDS_KEY_HOSTNAME=/instance/hostname
IMDS_KEY_REGION=/instance/region
IMDS_KEY_ZONE=/instance/zone
IMDS_KEY_IPV4_PUBLIC=/instance/network-interfaces/0/access-configs/0/external-ip
IMDS_KEY_USERDATA_BASE=/instance/attributes

# https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm#metadata-keys
dmi:*:catOracleCloud.com:*
IMDS_VENDOR=oracle-cloud-oci
IMDS_DATA_URL=http://169.254.169.254/opc/v2
IMDS_ADDRESS_IPV4=169.254.169.254
IMDS_ADDRESS_IPV6=fd00:c1::a9fe:a9fe
IMDS_EXTRA_HEADER=Authorization: Bearer Oracle
IMDS_KEY_HOSTNAME=/instance/hostname
IMDS_KEY_REGION=/instance/region
IMDS_KEY_ZONE=/instance/availabilityDomain
IMDS_KEY_SSH_KEY=/instance/metadata/ssh_authorized_keys
IMDS_KEY_USERDATA_BASE64=/metadata/user_data

# https://docs.hetzner.cloud/reference/cloud#description/server-metadata
dmi:bvnHetzner:*
IMDS_VENDOR=hetzner
IMDS_DATA_URL=http://169.254.169.254/hetzner/v1/metadata
IMDS_ADDRESS_IPV4=169.254.169.254
IMDS_KEY_HOSTNAME=/hostname
IMDS_KEY_REGION=/region
IMDS_KEY_ZONE=/availability-zone
IMDS_KEY_IPV4_PUBLIC=/public-ipv4
IMDS_KEY_SSH_KEY=/public-keys/0
IMDS_KEY_USERDATA=/userdata

# https://www.scaleway.com/en/docs/instances/how-to/use-cloud-init/
dmi:*:svnScaleway:*
IMDS_VENDOR=scaleway
IMDS_DATA_URL=http://169.254.42.42
IMDS_ADDRESS_IPV4=169.254.42.42
IMDS_ADDRESS_IPV6=fd00:42::42
IMDS_KEY_USERDATA=/user_data
1 change: 1 addition & 0 deletions hwdb.d/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ hwdb_files_notest = files(
hwdb_files_test = files(
'20-dmi-id.hwdb',
'20-net-ifname.hwdb',
'40-imds.hwdb',
'60-autosuspend.hwdb',
'60-autosuspend-fingerprint-reader.hwdb',
'60-evdev.hwdb',
Expand Down
20 changes: 19 additions & 1 deletion hwdb.d/parse_hwdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def hwdb_grammar():
matchline = (matchline_typed | matchline_general) + EOL

propertyline = (White(' ', exact=1).suppress() +
Combine(UDEV_TAG - '=' - Optional(Word(alphanums + '_=:@*.!-;, "/'))
Combine(UDEV_TAG - '=' - Optional(Word(alphanums + '_=:@*.!-;, "/?&'))
- Optional(pythonStyleComment)) +
EOL)
propertycomment = White(' ', exact=1) + pythonStyleComment + EOL
Expand Down Expand Up @@ -215,6 +215,24 @@ def property_grammar():
('ID_NET_NAME_FROM_DATABASE', name_literal),
('ID_NET_NAME_INCLUDE_DOMAIN', zero_one),
('TPM2_BROKEN_NVPCR', zero_one),
('IMDS_VENDOR', name_literal),
('IMDS_TOKEN_URL', name_literal),
('IMDS_REFRESH_HEADER_NAME', name_literal),
('IMDS_DATA_URL', name_literal),
('IMDS_DATA_URL_SUFFIX', name_literal),
('IMDS_TOKEN_HEADER_NAME', name_literal),
('IMDS_EXTRA_HEADER', name_literal),
('IMDS_ADDRESS_IPV4', name_literal),
('IMDS_ADDRESS_IPV6', name_literal),
('IMDS_KEY_HOSTNAME', name_literal),
('IMDS_KEY_REGION', name_literal),
('IMDS_KEY_ZONE', name_literal),
('IMDS_KEY_IPV4_PUBLIC', name_literal),
('IMDS_KEY_IPV6_PUBLIC', name_literal),
('IMDS_KEY_SSH_KEY', name_literal),
('IMDS_KEY_USERDATA', name_literal),
('IMDS_KEY_USERDATA_BASE', name_literal),
('IMDS_KEY_USERDATA_BASE64', name_literal),
)
fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE')
for name, val in props]
Expand Down
13 changes: 13 additions & 0 deletions man/kernel-command-line.xml
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,19 @@
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>

<varlistentry>
<term><varname>systemd.imds=</varname></term>
<term><varname>systemd.imds.*=</varname></term>

<listitem><para>Controls various Instance Metadata Service (IMDS) cloud aspects, see
<citerefentry><refentrytitle>systemd-imdsd@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd-imds-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for details.</para>

<xi:include href="version-info.xml" xpointer="v261"/></listitem>
</varlistentry>

</variablelist>
</refsect1>

Expand Down
9 changes: 9 additions & 0 deletions man/rules/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,14 @@ manpages = [
['systemd-hostnamed.service', '8', ['systemd-hostnamed'], 'ENABLE_HOSTNAMED'],
['systemd-hwdb', '8', [], 'ENABLE_HWDB'],
['systemd-id128', '1', [], ''],
['systemd-imds-generator', '8', [], 'ENABLE_IMDS'],
['systemd-imds', '1', ['systemd-imds-import.service'], 'ENABLE_IMDS'],
['systemd-imdsd@.service',
'8',
['systemd-imdsd',
'systemd-imdsd-early-network.service',
'systemd-imdsd.socket'],
'ENABLE_IMDS'],
['systemd-import-generator', '8', [], ''],
['systemd-importd.service', '8', ['systemd-importd'], 'ENABLE_IMPORTD'],
['systemd-inhibit', '1', [], ''],
Expand Down Expand Up @@ -1260,6 +1268,7 @@ manpages = [
['systemd.pcrlock', '5', ['systemd.pcrlock.d'], ''],
['systemd.preset', '5', [], ''],
['systemd.resource-control', '5', [], ''],
['systemd.rr', '5', [], 'ENABLE_RESOLVE'],
['systemd.scope', '5', [], ''],
['systemd.service', '5', [], ''],
['systemd.slice', '5', [], ''],
Expand Down
10 changes: 10 additions & 0 deletions man/systemd-firstboot.xml
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,16 @@

<xi:include href="version-info.xml" xpointer="v249"/></listitem>
</varlistentry>

<varlistentry>
<term><varname>firstboot.hostname</varname></term>

<listitem><para>This credential specifies the static system hostname setting to set during first
boot, in place of prompting the user. Note that this controls the static hostname, not the transient
hostname, and only has an effect on first boot, unlike <varname>system.hostname</varname>.</para>

<xi:include href="version-info.xml" xpointer="v261"/></listitem>
</varlistentry>
</variablelist>

<para>Note that by default the <filename>systemd-firstboot.service</filename> unit file is set up to
Expand Down
104 changes: 104 additions & 0 deletions man/systemd-imds-generator.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->

<refentry id="systemd-imds-generator" conditional='ENABLE_IMDS'
xmlns:xi="http://www.w3.org/2001/XInclude">

<refentryinfo>
<title>systemd-imds-generator</title>
<productname>systemd</productname>
</refentryinfo>

<refmeta>
<refentrytitle>systemd-imds-generator</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>

<refnamediv>
<refname>systemd-imds-generator</refname>
<refpurpose>Generator to automatically enable IMDS on supporting environments</refpurpose>
</refnamediv>

<refsynopsisdiv>
<para><filename>/usr/lib/systemd/system-generators/systemd-imds-generator</filename></para>
</refsynopsisdiv>

<refsect1>
<title>Description</title>

<para><command>systemd-imds-generator</command> is a generator that enables IMDS (Instance Metadata
Service) functionality at boot on systems that support it. Specifically it does three things:</para>

<itemizedlist>
<listitem><para>It pulls the <filename>systemd-imdsd@.service</filename> unit into the initial
transaction, which provides IMDS access to local applications via Varlink IPC.</para></listitem>

<listitem><para>It pulls the <filename>systemd-imds-early-network.service</filename> unit into the
initial transaction, which generates a suitable
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
network configuration file that allows early-boot network access to the IMDS
functionality.</para></listitem>

<listitem><para>It pulls the <filename>systemd-imds-import.service</filename> unit into the initial
transaction, which automatically imports various credentials from IMDS into the local system, storing
them in <filename>/run/credstore/</filename>.</para></listitem>
</itemizedlist>

<para>By default, whether to pull in these services or not is decided based on
<citerefentry><refentrytitle>hwdb</refentrytitle><manvolnum>7</manvolnum></citerefentry> information,
that detects various IMDS environments automatically. However, this logic may be overridden via
<varname>systemd.imds=</varname>, see below.</para>

<para><command>systemd-imds-generator</command> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect1>

<refsect1>
<title>Kernel Command Line</title>

<para><command>systemd-imds-generator</command> understands the following kernel command line
parameters:</para>

<variablelist class='kernel-commandline-options'>

<varlistentry>
<term><varname>systemd.imds=</varname></term>
<listitem>
<para>Takes a boolean argument, and may be used to enable or disable the IMDS logic. Note that this
controls only whether the relevant services (as listed above) are automatically pulled into the
initial transaction, it has no effect if some other unit or the user explicitly activate the
relevant units. If this option is not used automatic detection of IMDS is used, see above.</para>

<xi:include href="version-info.xml" xpointer="v261"/>
</listitem>
</varlistentry>

<xi:include href="systemd-imdsd@.service.xml" xpointer="kernel-cmdline-imds-network"/>

<varlistentry>
<term><varname>systemd.imds.import=</varname></term>
<listitem>
<para>Takes a boolean argument. If false the <filename>systemd-imds-import.service</filename> (see
above) is not pulled into the initial transaction, i.e. no credentials are imported from
IMDS. Defaults to true.</para>

<xi:include href="version-info.xml" xpointer="v261"/>
</listitem>
</varlistentry>

</variablelist>
</refsect1>

<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-imds</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-imdsd@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.system-credentials</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>

</refentry>
Loading