From 382f141fead03714820f274319bc606883a61c48 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 6 Feb 2026 15:04:11 +0100 Subject: [PATCH] units: symlink well-known Varlink services into /run/varlink/registry/ So far we didn't provide any concept to enumerate local Varlink services. Let's change that. Let's define very light-weight scheme for this: provide a well-known dir /run/varlink/registry/ where services that implement public interfaces can link their sockets into. When enumerating services it's thus sufficient to enumerate inodes in that directory. The usecase for this is twofold: 1. It's simply very useful to be able to see which public services are bound on the local system, for debugging/admin/development purposes. 2. At Amutable we'd like to optionally provide a HTTP-to-Varlink bridge on individual nodes, that allows remote peers (after authentication) to access local Varlink services. For that it's essential we know the list of services and their entrypoints to expose, it would be security-wise highly problematic for clients to provide AF_UNIX entrypoint paths when connecting. hence: let's instead just have a dir with the public stuff, and let's ensure the HTTP-to-Varlink bridge simply exposes that stuff, and nothing else. Non-public interfaces (such as the oomd interfaces between PID 1 and oomd), and interfaces with multiple implementors (such as the resolved hook interface, or the metrics collection stuff) should not be linked in. This is inspired by the Varlink.org "registry" concept, briefly explained here: https://varlink.org/FAQ#how-do-i-find-the-service-which-implements-a-local-interface Note however that the described Varlink interface is not actually implemented here, the directory is introduced however in a fashion that conceptually matches the registry defined there, and would allow us to implement the registry interface on top of it. (One of the reason the registry Varlink API is not implemented right now is that the URI format it relies on is entirely unspecified in the Varlink docs right now. Some research needs to be done to extract what's implemented in the reference implementation and to determine how it maps to the Varlink entrypoint address format systemd's own tooling currently uses) This primarily installs the symlinks via Symlinks= in unit files and via a new tmpfiles.d/ drop-in. But since we touch all .socket units relating to Varlink this also sets the FileDescriptorName= to varlink for each, just to minimize diffrences and make things work more alike (the services in questin don't care about the name, so this doesn't change). In one case we replace a pair of separate sockets for two closely related varlink services by a socket and a symlink, so that we can safely use Symlinks= to also install the registry symlinks. --- tmpfiles.d/20-systemd-varlink.conf | 18 ++++++++++++++++++ tmpfiles.d/meson.build | 3 +++ tmpfiles.d/user/20-systemd-varlink.conf | 7 +++++++ tmpfiles.d/user/meson.build | 11 +++++++++++ units/systemd-ask-password.socket | 1 + units/systemd-bootctl.socket | 1 + units/systemd-creds.socket | 1 + units/systemd-factory-reset.socket | 1 + units/systemd-hostnamed.socket | 1 + units/systemd-importd.socket | 1 + units/systemd-logind-varlink.socket | 1 + units/systemd-machined.socket | 2 +- units/systemd-mountfsd.socket | 2 ++ units/systemd-mute-console.socket | 1 + units/systemd-networkd-varlink.socket | 1 + units/systemd-nsresourced.socket | 3 ++- units/systemd-pcrextend.socket | 1 + units/systemd-pcrlock.socket | 1 + units/systemd-repart.socket | 1 + units/systemd-resolved-monitor.socket | 1 + units/systemd-resolved-varlink.socket | 1 + units/systemd-sysext.socket | 1 + units/systemd-udevd-varlink.socket | 1 + units/systemd-userdbd.socket | 3 ++- units/user/systemd-ask-password.socket | 1 + units/user/systemd-importd.socket | 1 + units/user/systemd-machined.socket | 2 +- 27 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 tmpfiles.d/20-systemd-varlink.conf create mode 100644 tmpfiles.d/user/20-systemd-varlink.conf create mode 100644 tmpfiles.d/user/meson.build diff --git a/tmpfiles.d/20-systemd-varlink.conf b/tmpfiles.d/20-systemd-varlink.conf new file mode 100644 index 0000000000..96905ff4f1 --- /dev/null +++ b/tmpfiles.d/20-systemd-varlink.conf @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# See tmpfiles.d(5) for details. + +# Varlink AF_UNIX entrypoint socket inodes of relevant system services may be +# linked into this directory, to make them "well-known". Typically, tools such +# as the Varlink HTTP bridge expose services linked in here as public +# interfaces. The symlink should be named after the Varlink interface to +# expose. Interfaces that may be implemented by multiple services (such as +# the generic "io.systemd.service") should not be symlinked here. +d /run/varlink/registry/ 0755 root root + +# Socket activated services should use Symlinks= in the .socket unit file to +# create these symlinks. If that's not applicable, consider creating the +# symlinks via a tmpfiles.d/ snippet, like we do here, so that registration can +# be influenced by the administrator. +L /run/varlink/registry/io.systemd.Unit - - - - ../../systemd/io.systemd.Manager +L /run/varlink/registry/io.systemd.Manager - - - - ../../systemd/io.systemd.Manager +L /run/varlink/registry/io.systemd.Journal - - - - ../../systemd/journal/io.systemd.journal diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build index 7f3fce48c9..c8f9015b2e 100644 --- a/tmpfiles.d/meson.build +++ b/tmpfiles.d/meson.build @@ -13,6 +13,7 @@ files = [['README' ], ['systemd-nspawn.conf', 'ENABLE_MACHINED' ], ['systemd-pstore.conf', 'ENABLE_PSTORE' ], ['systemd-resolve.conf', 'ENABLE_RESOLVE' ], + ['20-systemd-varlink.conf' ], ['systemd-tmp.conf' ], ['tmp.conf' ], ['x11.conf' ], @@ -59,3 +60,5 @@ endforeach if install_sysconfdir install_emptydir(sysconfdir / 'tmpfiles.d') endif + +subdir('user') diff --git a/tmpfiles.d/user/20-systemd-varlink.conf b/tmpfiles.d/user/20-systemd-varlink.conf new file mode 100644 index 0000000000..6df6408f18 --- /dev/null +++ b/tmpfiles.d/user/20-systemd-varlink.conf @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# See tmpfiles.d(5) for details. + +d %t/varlink/registry/ 0755 + +L %t/varlink/registry/io.systemd.Unit - - - - ../../systemd/io.systemd.Manager +L %t/varlink/registry/io.systemd.Manager - - - - ../../systemd/io.systemd.Manager diff --git a/tmpfiles.d/user/meson.build b/tmpfiles.d/user/meson.build new file mode 100644 index 0000000000..551e4fe56b --- /dev/null +++ b/tmpfiles.d/user/meson.build @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +files = [ '20-systemd-varlink.conf' ] + +foreach f : files + install_data(f, install_dir : usertmpfilesdir) +endforeach + +if install_sysconfdir + install_emptydir(sysconfdir / 'user-tmpfiles.d') +endif diff --git a/units/systemd-ask-password.socket b/units/systemd-ask-password.socket index c8d203b077..df5eaffc22 100644 --- a/units/systemd-ask-password.socket +++ b/units/systemd-ask-password.socket @@ -15,6 +15,7 @@ Before=sockets.target [Socket] ListenStream=/run/systemd/io.systemd.AskPassword +Symlinks=/run/varlink/registry/io.systemd.AskPassword FileDescriptorName=varlink SocketMode=0666 Accept=yes diff --git a/units/systemd-bootctl.socket b/units/systemd-bootctl.socket index f9553b840b..e720f24f54 100644 --- a/units/systemd-bootctl.socket +++ b/units/systemd-bootctl.socket @@ -16,6 +16,7 @@ Before=sockets.target [Socket] ListenStream=/run/systemd/io.systemd.BootControl +Symlinks=/run/varlink/registry/io.systemd.BootControl FileDescriptorName=varlink SocketMode=0600 Accept=yes diff --git a/units/systemd-creds.socket b/units/systemd-creds.socket index bf13c11e0f..3ea3ca5b05 100644 --- a/units/systemd-creds.socket +++ b/units/systemd-creds.socket @@ -15,6 +15,7 @@ Before=sockets.target [Socket] ListenStream=/run/systemd/io.systemd.Credentials +Symlinks=/run/varlink/registry/io.systemd.Credentials FileDescriptorName=varlink SocketMode=0666 Accept=yes diff --git a/units/systemd-factory-reset.socket b/units/systemd-factory-reset.socket index d833ffdb99..467517ec24 100644 --- a/units/systemd-factory-reset.socket +++ b/units/systemd-factory-reset.socket @@ -15,6 +15,7 @@ Before=sockets.target [Socket] ListenStream=/run/systemd/io.systemd.FactoryReset +Symlinks=/run/varlink/registry/io.systemd.FactoryReset FileDescriptorName=varlink SocketMode=0666 Accept=yes diff --git a/units/systemd-hostnamed.socket b/units/systemd-hostnamed.socket index 2a2cfce653..288e736b47 100644 --- a/units/systemd-hostnamed.socket +++ b/units/systemd-hostnamed.socket @@ -15,5 +15,6 @@ Documentation=man:machine-info(5) [Socket] ListenStream=/run/systemd/io.systemd.Hostname +Symlinks=/run/varlink/registry/io.systemd.Hostname FileDescriptorName=varlink SocketMode=0666 diff --git a/units/systemd-importd.socket b/units/systemd-importd.socket index d1c9c22a4c..a538ef0d0e 100644 --- a/units/systemd-importd.socket +++ b/units/systemd-importd.socket @@ -20,5 +20,6 @@ Before=shutdown.target [Socket] ListenStream=/run/systemd/io.systemd.Import +Symlinks=/run/varlink/registry/io.systemd.Import FileDescriptorName=varlink SocketMode=0666 diff --git a/units/systemd-logind-varlink.socket b/units/systemd-logind-varlink.socket index 3978e8ab90..1d3652e049 100644 --- a/units/systemd-logind-varlink.socket +++ b/units/systemd-logind-varlink.socket @@ -13,6 +13,7 @@ Documentation=man:systemd-logind.service(8) [Socket] ListenStream=/run/systemd/io.systemd.Login +Symlinks=/run/varlink/registry/io.systemd.Login FileDescriptorName=varlink SocketMode=0666 Service=systemd-logind.service diff --git a/units/systemd-machined.socket b/units/systemd-machined.socket index 3df5c7d8c3..75a91bb0cc 100644 --- a/units/systemd-machined.socket +++ b/units/systemd-machined.socket @@ -13,6 +13,6 @@ Documentation=man:systemd-machined.service(8) [Socket] ListenStream=/run/systemd/machine/io.systemd.Machine -ListenStream=/run/systemd/machine/io.systemd.MachineImage +Symlinks=/run/systemd/machine/io.systemd.MachineImage /run/varlink/registry/io.systemd.Machine /run/varlink/registry/io.systemd.MachineImage FileDescriptorName=varlink SocketMode=0666 diff --git a/units/systemd-mountfsd.socket b/units/systemd-mountfsd.socket index cd88003af9..431369a1a1 100644 --- a/units/systemd-mountfsd.socket +++ b/units/systemd-mountfsd.socket @@ -16,6 +16,8 @@ Before=sockets.target shutdown.target [Socket] ListenStream=/run/systemd/io.systemd.MountFileSystem +Symlinks=/run/varlink/registry/io.systemd.MountFileSystem +FileDescriptorName=varlink SocketMode=0666 [Install] diff --git a/units/systemd-mute-console.socket b/units/systemd-mute-console.socket index 16032e94b4..5eae6d5acd 100644 --- a/units/systemd-mute-console.socket +++ b/units/systemd-mute-console.socket @@ -17,6 +17,7 @@ Before=shutdown.target [Socket] ListenStream=/run/systemd/io.systemd.MuteConsole +Symlinks=/run/varlink/registry/io.systemd.MuteConsole FileDescriptorName=varlink SocketMode=0600 Accept=yes diff --git a/units/systemd-networkd-varlink.socket b/units/systemd-networkd-varlink.socket index 7d194fff34..1f4db858bc 100644 --- a/units/systemd-networkd-varlink.socket +++ b/units/systemd-networkd-varlink.socket @@ -17,6 +17,7 @@ Conflicts=shutdown.target [Socket] ListenStream=/run/systemd/netif/io.systemd.Network +Symlinks=/run/varlink/registry/io.systemd.Network FileDescriptorName=varlink SocketMode=0666 Service=systemd-networkd.service diff --git a/units/systemd-nsresourced.socket b/units/systemd-nsresourced.socket index 2e3c8e9baa..c159a5676a 100644 --- a/units/systemd-nsresourced.socket +++ b/units/systemd-nsresourced.socket @@ -16,7 +16,8 @@ Before=sockets.target shutdown.target [Socket] ListenStream=/run/systemd/io.systemd.NamespaceResource -Symlinks=/run/systemd/userdb/io.systemd.NamespaceResource +Symlinks=/run/systemd/userdb/io.systemd.NamespaceResource /run/varlink/registry/io.systemd.NamespaceResource +FileDescriptorName=varlink SocketMode=0666 [Install] diff --git a/units/systemd-pcrextend.socket b/units/systemd-pcrextend.socket index 4f74748125..d429150eda 100644 --- a/units/systemd-pcrextend.socket +++ b/units/systemd-pcrextend.socket @@ -17,6 +17,7 @@ ConditionSecurity=measured-uki [Socket] ListenStream=/run/systemd/io.systemd.PCRExtend +Symlinks=/run/varlink/registry/io.systemd.PCRExtend FileDescriptorName=varlink SocketMode=0600 Accept=yes diff --git a/units/systemd-pcrlock.socket b/units/systemd-pcrlock.socket index ca1cd53aea..e166caf3d8 100644 --- a/units/systemd-pcrlock.socket +++ b/units/systemd-pcrlock.socket @@ -17,6 +17,7 @@ ConditionSecurity=measured-uki [Socket] ListenStream=/run/systemd/io.systemd.PCRLock +Symlinks=/run/varlink/registry/io.systemd.PCRLock FileDescriptorName=varlink SocketMode=0600 Accept=yes diff --git a/units/systemd-repart.socket b/units/systemd-repart.socket index c9fc308b1b..ecd275414d 100644 --- a/units/systemd-repart.socket +++ b/units/systemd-repart.socket @@ -17,6 +17,7 @@ Before=shutdown.target [Socket] ListenStream=/run/systemd/io.systemd.Repart +Symlinks=/run/varlink/registry/io.systemd.Repart FileDescriptorName=varlink SocketMode=0600 Accept=yes diff --git a/units/systemd-resolved-monitor.socket b/units/systemd-resolved-monitor.socket index a778e60dd2..3674a1f876 100644 --- a/units/systemd-resolved-monitor.socket +++ b/units/systemd-resolved-monitor.socket @@ -17,6 +17,7 @@ Conflicts=shutdown.target [Socket] Service=systemd-resolved.service ListenStream=/run/systemd/resolve/io.systemd.Resolve.Monitor +Symlinks=/run/varlink/registry/io.systemd.Resolve.Monitor FileDescriptorName=varlink-monitor SocketMode=0666 diff --git a/units/systemd-resolved-varlink.socket b/units/systemd-resolved-varlink.socket index 7ac83e5ec9..a570168373 100644 --- a/units/systemd-resolved-varlink.socket +++ b/units/systemd-resolved-varlink.socket @@ -17,6 +17,7 @@ Conflicts=shutdown.target [Socket] Service=systemd-resolved.service ListenStream=/run/systemd/resolve/io.systemd.Resolve +Symlinks=/run/varlink/registry/io.systemd.Resolve FileDescriptorName=varlink SocketMode=0666 diff --git a/units/systemd-sysext.socket b/units/systemd-sysext.socket index 97d1695780..61d7268f37 100644 --- a/units/systemd-sysext.socket +++ b/units/systemd-sysext.socket @@ -17,6 +17,7 @@ ConditionCapability=CAP_SYS_ADMIN [Socket] ListenStream=/run/systemd/io.systemd.sysext +Symlinks=/run/varlink/registry/io.systemd.sysext FileDescriptorName=varlink SocketMode=0666 Accept=yes diff --git a/units/systemd-udevd-varlink.socket b/units/systemd-udevd-varlink.socket index 74353e7f1a..c2b7652e5e 100644 --- a/units/systemd-udevd-varlink.socket +++ b/units/systemd-udevd-varlink.socket @@ -17,6 +17,7 @@ ConditionPathIsReadWrite=/sys [Socket] Service=systemd-udevd.service ListenStream=/run/udev/io.systemd.Udev +Symlinks=/run/varlink/registry/io.systemd.Udev FileDescriptorName=varlink SocketMode=0600 RemoveOnStop=yes diff --git a/units/systemd-userdbd.socket b/units/systemd-userdbd.socket index 6ef1adeca7..6793d1b41d 100644 --- a/units/systemd-userdbd.socket +++ b/units/systemd-userdbd.socket @@ -15,7 +15,8 @@ Before=sockets.target [Socket] ListenStream=/run/systemd/userdb/io.systemd.Multiplexer -Symlinks=/run/systemd/userdb/io.systemd.NameServiceSwitch /run/systemd/userdb/io.systemd.DropIn +Symlinks=/run/systemd/userdb/io.systemd.NameServiceSwitch /run/systemd/userdb/io.systemd.DropIn /run/varlink/registry/io.systemd.UserDatabase +FileDescriptorName=varlink SocketMode=0666 RemoveOnStop=yes diff --git a/units/user/systemd-ask-password.socket b/units/user/systemd-ask-password.socket index ce9ccd9e55..56492fae54 100644 --- a/units/user/systemd-ask-password.socket +++ b/units/user/systemd-ask-password.socket @@ -15,6 +15,7 @@ Before=sockets.target [Socket] ListenStream=%t/systemd/io.systemd.AskPassword +Symlinks=%t/varlink/registry/io.systemd.AskPassword FileDescriptorName=varlink SocketMode=0600 Accept=yes diff --git a/units/user/systemd-importd.socket b/units/user/systemd-importd.socket index d266d927f8..67ea62bdb0 100644 --- a/units/user/systemd-importd.socket +++ b/units/user/systemd-importd.socket @@ -14,5 +14,6 @@ Documentation=man:org.freedesktop.import1(5) [Socket] ListenStream=%t/systemd/io.systemd.Import +Symlinks=%t/varlink/registry/io.systemd.Import FileDescriptorName=varlink SocketMode=0600 diff --git a/units/user/systemd-machined.socket b/units/user/systemd-machined.socket index d368215e98..17e552a7dc 100644 --- a/units/user/systemd-machined.socket +++ b/units/user/systemd-machined.socket @@ -13,6 +13,6 @@ Documentation=man:systemd-machined.service(8) [Socket] ListenStream=%t/systemd/machine/io.systemd.Machine -ListenStream=%t/systemd/machine/io.systemd.MachineImage +Symlinks=%t/systemd/machine/io.systemd.MachineImage %t/varlink/registry/io.systemd.Machine %t/varlink/registry/io.systemd.MachineImage FileDescriptorName=varlink SocketMode=0600