Access D-Bus remotely using socat
Description:
I'd like to access a D-Bus system service from another machine, knowing only machine's IP address and the service to connect to.
What I have recently found is Gabriel (D-Bus over SSH). I have compiled its GIT version (hosted on Sourceforge) and this seems to work, but I keep getting a problem with the lack of "keep-alive". This means that after some period of inactivity the SSH tunnel fails to forward D-Bus requests to remote PC and I must restart Gabriel.
Since Gabriel uses socat on the PC it connects to, I've just had an idea of using socat also on local PC (replacing Gabriel with it).
Questions:
- Could anyone more familiar with setting up "socat" confirm that solution please?
- Could such solution handle many client applications connecting to the same remote D-Bus service at once?
- As it is unneccessary for me to have the connection secured - would using "socat" on both sides make the connection significantly faster (in opposite to Gabriel's SSH tunnel, if the SSH gives too much overhead)?
- Does anyone have any better solution for accessing D-Bus remotely maybe?
Any comments appreciated.
I'll post an answer to my own question, as I have worked out a working solution.
Note: I have sacrificed all security via SSH as it wasn't needed for development in my own LAN. Changing DBus to listen on TCP instead unix sockets was also not possible.
Step 1
On the remote host with an example IP address 192.168.1.100 (and to which D-Bus I'd like to have access to) I run:
socat TCP-LISTEN:7272,reuseaddr,fork UNIX-CONNECT:/var/run/dbus/system_bus_socket
Now socat listens for connections on 7272 port and creates a separate thread for each client. This allows multiple connections at the same time.
Step 2
On local machine (which I'd like to connect to remote D-Bus) I run:
socat ABSTRACT-LISTEN:/tmp/custom_dbus_name,fork TCP:192.168.1.100:7272
This connects to the port exposed remotely with socat and creates a local abstract socket to which we can connect to.
Sample usage
Python:
import dbus
sysbus = dbus.bus.BusConnection("unix:abstract=/tmp/custom_dbus_name")
proxy_obj = sysbus.get_object('com.some.service.name', '/com/some/service/name')
my_interface = dbus.Interface(proxy_obj, dbus_interface = 'com.some.interface.name')
my_interface.SomeDBusExposedMethod()
my_interface.OtherRemoteMethod()
D-Feet
One can also use D-Feet to browse remote D-Bus services and their methods. It can be done with "File / Connect to other bus" menu option and putting your custom abstract socket name defined in second step.