Подключение к dbus по tcp

я написал простую программу python для воспроизведения и приостановки музыкального проигрывателя banshee. Пока он работает на моей собственной машине, у меня проблемы с удаленным компьютером, подключенным к тому же маршрутизатору (LAN). Я редактировал сеанс.конф удаленной машины, чтобы добавить эту строку:

<listen>tcp:host=localhost,port=12434</listen>

и вот моя программа:

    import dbus


    bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434")
    proxy_object=bus_obj.get_object('org.bansheeproject.Banshee',                              
    '/org/bansheeproject/Banshee/PlayerEngine')

    playerengine_iface=dbus.Interface(proxy_object,
    dbus_interface='org.bansheeproject.Banshee.PlayerEngine')

    var=0

    while (var!="3"):
        var=raw_input("nPressn1 to playn2 to pausen3 to exitn")


            if var=="1":
                print "playing..."
                playerengine_iface.Play()

            elif var=="2":
                print "pausing"
                playerengine_iface.Pause()

это то, что я получаю, когда пытаюсь выполнить его

Traceback (most recent call last):
  File "dbus3.py", line 4, in <module>
    bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434")
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 125, in __new__
    bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoServer: Failed to connect to socket "localhost:12434" Connection refused

что я здесь делаю не так? я должен изменить /usr/lib/python2.7/dist-packages/dbus/bus.py

обновление:

хорошо, вот сделка когда я добавить

<listen>tcp:host=192.168.1.7,port=12434</listen>

to to / etc/dbus-1 / session.conf, затем перезагрузитесь, надеясь, что он начнет слушать при перезагрузке, Он никогда не загружается. Она застревает на экране загрузки и иногда черный экран со следующим текстом вспышки:

Pulseaudio Configured For Per-user Sessions Saned Disabled;edit/etc/default/saned

Итак, когда я иду ctrl + alt+f1, измените сеанс.conf в исходное состояние и перезагрузка, он загружается правильно.

что и все из-за этого? Как я могу заставить dbus daemon прослушивать tcp-соединения без проблем?

3 ответов


недавно мне нужно было настроить это и обнаружил, что трюк:порядок имеет значение на <listen> элементов session.conf. Вы должны убедиться, что элемент TCP происходит первым. Странно, я знаю, но это правда, по крайней мере в моем случае. (Я вижу ровно такое же поведение черного экрана, если я изменю порядок и поставлю сокет UNIX <listen> элемент первого.)

кроме того, добавление TCP <listen> тег необходим, но недостаточно. Сделать удаленный D-Bus соединения через TCP работают, вам нужно сделать три вещи:

  1. добавить <listen> тег над UNIX, похожий на этот:

    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    
  2. добавить строку (прямо под <listen> теги в порядке), что говорит:

    <auth>ANONYMOUS</auth>
    
  3. добавить еще одну строку под ними, которая говорит:

    <allow_anonymous/>
    

на <auth> тег должен быть добавлен в дополнение к любым другим <auth> теги, которые могут содержаться в ваш session.conf. В общем, ваш session.conf должен содержать фрагмент, который выглядит так:

<listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
<listen>unix:tmpdir=/tmp</listen>

<auth>ANONYMOUS</auth>
<allow_anonymous/>

после выполнения этих трех действий вы сможете удаленно подключиться к шине сеанса. Вот как это выглядит при указании удаленного подключения в D-Ноги:

D-Feet screen capture

обратите внимание, что если вы хотите подключиться к системной шине, вам нужно внести аналогичные изменения в /etc/dbus-1/system.conf, но указать разные TCP-порт, например 55557. (Как ни странно, в этом случае порядок элементов не имеет значения.)

единственное странное поведение, которое я заметил в этой конфигурации, - это запуск настольных приложений с sudo (например, sudo gvim) имеет тенденцию генерировать ошибки или терпеть неудачу, говоря "нет D-BUS daemon running". Но это то, что мне нужно делать так редко, что это вряд ли имеет значение.

если вы хотите отправить на удаленную машину с помощью dbus-send, вам необходимо установить DBUS_SESSION_BUS_ADDRESS соответственно, например, для что-то вроде:

export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=*,port=55556,family=ipv4

это работает, даже если автобус, который вы хотите отправить, на самом деле система шина удаленного компьютера, если параметр соответствует TCP <listen> tag in /etc/dbus-1/system.conf на цели. (Спасибо Мартин Vidner за этот совет. Пока я не наткнулся на его ответ этот вопрос, я не верю dbus-send поддерживается дистанционное управление.)

обновление: если вы используете systemd (и хотите получить доступ к системной шине), вам также может потребоваться добавить строку ListenStream=55557 to /lib/systemd/system/dbus.socket, например:

[Socket]
ListenStream=/var/run/dbus/system_bus_socket
ListenStream=55557  # <-- Add this line

обновление 2: спасибо @алтагир для указывая, что последние версии D-Bus позволит AppArmor посредничество в системах, где оно доступно, поэтому вам также может потребоваться добавить <apparmor mode="disabled"/> to session.conf/system.conf для этих инструкций для работы.


начиная с dbus 1.6.12 (например, kubuntu 13.10), ваше соединение также будет отклонено, если вы не добавите в файл конфигурации dbus (либо /etc/dbus-1/mybus.conf или интерфейс, требующий удаленного доступа, т. е. система.d/мой.взаимодействие.conf)

<apparmor mode="disabled"/>

обновление: после попытки создать профиль apparmor, позволяющий службе подключаться к пользовательскому dbus-демону, кажется, что соединение всегда отклоняется из-за ошибки в DBUS... так что сейчас мы должны отключить apparmor всякий раз, когда вы используете tcp=... Исправить ошибку нацеливали на 14.04

Я открыл ошибку в bugs.launchpad.net после обсуждения здесь с Тайлером Хиксом:

код посредничества AppArmor только имеет возможность проверять метки одноранговых узлов через доменные сокеты UNIX. Скорее всего, он видит ошибку, когда получение ярлыка, а затем отказ от соединения.

Примечание.: этот флаг disable не распознается dbus

IF(EXISTS "/usr/sbin/apparmor_status")
  install(FILES dbus_daemon-apparmordisabled.conf RENAME dbus_daemon.conf DESTINATION /etc/dbus-1/ )
ELSE (EXISTS "/usr/sbin/apparmor_status")
   install(FILES dbus_daemon.conf DESTINATION /etc/dbus-1/ )
ENDIF(EXISTS "/usr/sbin/apparmor_status")

еще одно спасибо @Shorin, и еще один FYI-я должен был сделать что-то вроде этого, чтобы заставить мою работу:

<listen>tcp:host=localhost,bind=0.0.0.0,port=55884</listen>

Примечание bind=0.0.0.0 - the bind=* не сработало для меня, и я опустил family=ipv4 часть. Я на Ubuntu 12.04. Я использовал netstat на удаленной машине, чтобы подтвердить, что dbus прослушивает порт, и telnet от local, чтобы подтвердить, что порт открыт.

netstat -plntu | grep 55884

tcp   0     0 0.0.0.0:55884    0.0.0.0:*     LISTEN    707/dbus-daemon

вы должны увидеть что-то вроде 0 0.0.0.0:55884, а не что-то вроде 0 127.0.0.1:55884.