8

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.

schedar
  • 161
  • 1
  • 7

2 Answers2

8

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.

schedar
  • 161
  • 1
  • 7
  • I've tried this solution, but I'm still missing something. I'm on Fedora 30. If I start socat with ABSTRACT-LISTEN, it doesn't create any socket (I expect a file to be present in /tmp) and d-feet can't connect because it says the file is missing. If I use UNIX-RECVFROM, it creates a socket, but d-feet complains anyway (Protocol wrong type for socket). Do I have to create the socket before connecting? How? – G B Sep 16 '19 at 14:24
  • A small step forward, now it's connecting (with UNIX-LISTEN) but not authenticating. How do I pass D-BUS authentication without resorting to ANONYMOUS access? – G B Sep 16 '19 at 14:35
  • Ok, last message. It works, but only if local user is root. How do I allow another user to connect? – G B Sep 16 '19 at 14:37
0

SSH has in inbuilt keep alive mechanism. May be you use that to ensure you session is not closed?

To enable keep alive in ssh,

Either Add the following line to the /etc/ssh/ssh_config file for global configuration:

ServerAliveInterval 60

Or add the following lines to ~/.ssh/config (create if required) for user configuration

Host *
 ServerAliveInterval 60

You can also use per host configuration by appending hostname to the * , eg :

Host *hostname.com
 ServerAliveInterval 60

Where the 60, represents the interval in seconds after which the keep alive/no-op code is sent. Also, the space in the second line is important.

Akshet
  • 316
  • 1
  • 7
  • Thank you for submission. Unfortunately it didn't help. I've updated the global configuration, restarted sshd, established connection then and waited some time. SSH session has had expired and "Gabriel" had the session channel closed already. – schedar Aug 06 '12 at 07:28