Bridge a D-Bus Connection with systemd-stdio-bridge
systemd-stdio-bridge is the remote end of a D-Bus connection carried over standard input and output, exactly what an SSH hop or a container needs. This guide covers the system bus, a user bus, containers and an explicit bus address, while keeping the bridge's binary traffic away from your terminal. Allow about fifteen minutes.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need: a Linux host with the
systemdpackage installed and a D-Bus client that knows how to use a standard-input/output transport. - Versions: the examples match systemd 255.4-1ubuntu8.17, installed here as Ubuntu package
systemd.
The bridge is not a general-purpose text command: when it is running normally, its standard streams carry D-Bus messages, not anything readable.
1. Check the installed bridge
Confirm which executable will run. This is an ordinary, read-only check that needs no elevated privileges.
$ command -v systemd-stdio-bridge
/usr/bin/systemd-stdio-bridge
$ dpkg-query -W -f='${Package} ${Version}\n' systemd
systemd 255.4-1ubuntu8.17
$ systemd-stdio-bridge --version
systemd 255 (255.4-1ubuntu8.17)
The installed manual describes the program as a proxy between standard input/output and a D-Bus bus. It expects the first connection on those streams and opens a second connection to the selected bus, returning zero on success and a non-zero status on failure.
Checkpoint
The path is the systemd executable you intended to use, and its package version is recorded. If command -v finds nothing, stop and install or repair the normal systemd package through your distribution's package manager.
2. Keep the bridge inside a transport
Warning
Do not start the bridge by itself in an interactive terminal and then type into it. Its streams are a protocol endpoint, not a command prompt: a text terminal cannot provide a useful D-Bus client connection, and binary output may make the terminal display confusing characters.
The normal shape is a client on one side and systemd-stdio-bridge on the other. For an SSH hop, a D-Bus-aware client starts the remote command over SSH, leaving SSH to carry the remote process's standard streams.
$ ssh USER@HOST systemd-stdio-bridge --system
This line is a transport building block, not a complete D-Bus query by itself. Replace USER@HOST with a real SSH target and invoke it through the client that requested the remote D-Bus connection; the bridge reads and writes the connection, it does not print a human-readable session transcript.
There is no persistent configuration to undo here. When the client closes the connection, SSH and the bridge exit. If you have accidentally started a foreground bridge, use Ctrl-C in that terminal: this stops that process but does not change the bus or its services.
3. Select the system or user bus
The default is the local system bus, equivalent to --system. Make that choice explicit in scripts and remote commands so a later reader does not have to remember the default.
$ ssh USER@HOST systemd-stdio-bridge --system
Use --user instead when the bridge should connect to the calling user's service manager and user bus.
$ ssh USER@HOST systemd-stdio-bridge --user
These options select the bus the bridge opens on its local side. They do not change the identity of the SSH connection, grant access to another account, or turn a system service into a user service. The remote account still needs permission to connect to the selected bus.
Checkpoint
Choose exactly one of --system and --user. Omit both and the installed command falls back to the system bus. A failed connection is usually a bus availability, session environment or authorisation problem, not a reason to add sudo blindly.
4. Target a local container
Use --machine=CONTAINER, or its short form -M CONTAINER, to connect to a local container. With no user prefix, the manual says the connection is made as root in the named container.
$ systemd-stdio-bridge --machine=CONTAINER_NAME
Put a user name before @ to select the account instead, for example --machine=alice@CONTAINER_NAME. The special name .host means the local host, which is useful when selecting a particular user's user bus.
$ systemd-stdio-bridge --user [email protected]
Do not confuse --machine with an SSH destination: it addresses a local container through systemd's machine interface. The container or host must exist and be reachable by the local systemd environment before a D-Bus client can use the bridge.
Because these commands only open a bus connection, they do not create or remove a container. A failed attempt has no service-management rollback to perform. If the target is missing, check the machine name with your normal systemd machine-management tools before retrying.
5. Supply an explicit bus address
--bus-path=PATH, also written -p PATH, overrides the default bus address unix:path=/run/dbus/system_bus_socket. Use it when the service is deliberately exposed at a different D-Bus address.
$ systemd-stdio-bridge --bus-path='unix:path=/run/dbus/system_bus_socket'
That command just spells out the installed default; it does not make the bridge useful as a standalone terminal process. In a real transport command, keep the address as one shell argument.
$ ssh USER@HOST systemd-stdio-bridge --bus-path='unix:path=/run/dbus/system_bus_socket'
Warning
Only use an address from a trusted configuration source. A bus address can select a different socket or transport, and connecting to the wrong bus can expose the client to an unexpected service namespace. Do not paste an untrusted address into a privileged service or automation job.
6. Verify option parsing without opening a bus
The help path is the safest local smoke test, since it exits before trying to proxy a connection.
$ systemd-stdio-bridge --help
systemd-stdio-bridge [OPTIONS...]
Forward messages between a pipe or socket and a D-Bus bus.
-h --help Show this help
--version Show package version
-p --bus-path=PATH Path to the bus address (default: unix:path=/run/dbus/system_bus_socket)
--system Connect to system bus
--user Connect to user bus
-M --machine=CONTAINER Name of local container to connect to
If an automated check needs to test failure handling, use a temporary, deliberately invalid bus path through a D-Bus client that supplies the bridge's standard streams. Do not redirect a normal terminal into the bridge and read the result as a D-Bus test. Record the client's exit status and its diagnostic; the bridge's own contract only promises zero for success and non-zero for failure, not one fixed error number or wording.
Done means
- Binary checked: the installed executable and systemd version have been confirmed.
- Client owns the streams: a D-Bus-aware client, not an interactive terminal, owns the bridge's standard streams.
- Bus made explicit: the selected bus is explicit: system, user, local container or a verified bus address.
- Access checked: remote access uses the required SSH account and bus authorisation, with
sudonever added as a guess. - Nothing left changed: the help and version checks pass, and no persistent service or container configuration was touched.