web-dev-qa-db-ja.com

TCP経由でdbusに接続する

Bansheeミュージックプレーヤーを再生および一時停止する簡単なpythonプログラムを作成しました。自分のマシンで動作しているときに、同じルーター(LAN)に接続されたリモートコンピューターで実行するのに問題があります。リモートマシンのsession.confを編集して、次の行を追加しました。

<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("\nPress\n1 to play\n2 to pause\n3 to exit\n")


            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>

/etc/dbus-1/session.confに移動し、再起動します。再起動時にリッスンが開始されることを期待して、起動しません。ロード画面でスタックし、次のテキストが表示された黒い画面が点滅することがあります。

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

したがって、ctrl + alt + f1に移動し、session.confを元の状態に変更して再起動すると、正しく起動します。

どうしたの?問題が発生することなく、dbusデーモンにtcp接続をリッスンさせるにはどうすればよいですか?

21
Gautam

最近これを設定する必要があり、そのトリックは次のとおりであることがわかりました:<listen>session.conf要素の順序が重要。 TCP要素が最初に発生することを確認する必要があります。奇妙なことですが、少なくとも私の場合は真実です。(正確に順序を逆にしてUNIXソケット<listen>要素を最初に配置した場合も、同じ黒い画面の動作になります。)

また、TCP <listen>タグを付加する必要がありますが、十分ではありません。TCPを介してリモートD-Bus接続を行うには、次のことを行う必要があります。 3つのことをします:

  1. 次のように、UNIXタグの上に<listen>タグを追加します。

    <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/>

これらの3つのことを実行すると、セッションバスにリモートで接続できるようになります。 D-Feet でリモート接続を指定すると、次のようになります。

D-Feet screen capture

システムバスにも接続する場合は、/etc/dbus-1/system.confにも同様の変更を加える必要がありますが、differentTCPポート、たとえば55557。(奇妙なことに、この場合、要素の順序は重要ではないようです。)

この構成で私が気付いた唯一の奇妙な動作は、Sudo(例:Sudo gvim)でデスクトップアプリを実行すると、エラーが発生したり、「D-BUSデーモンが実行されていません」と完全に失敗したりする傾向があることです。しかし、これは私がめったに行う必要がないので、ほとんど問題になりません。

dbus-sendを使用してリモートマシンに送信する場合は、それに応じてDBUS_SESSION_BUS_ADDRESSを次のように設定する必要があります。

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

これは、送信先のバスが実際にはリモートマシンのシステムバスであっても、設定がTCP)と一致する限り、機能します。ターゲットの<listen>/etc/dbus-1/system.confタグ。(このヒントについては Martin Vidner に感謝します。 この質問 に対する彼の答えに出くわすまで、私はdbus-sendがリモート操作をサポートしているとは信じていませんでした。)

[〜#〜] update [〜#〜]:systemdを使用している(そしてシステムバスにアクセスしたい)場合は、 ListenStream=55557という行を/lib/systemd/system/dbus.socketに追加するには、次のようにします。

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

UPDATE2D-Busの最近のバージョン が有効になることを指摘してくれた@altagirに感謝します AppArmor =利用可能なシステムでのメディエーション。したがって、これらの手順を機能させるには、<apparmor mode="disabled"/>session.conf/system.confに追加する必要がある場合もあります。

33
evadeflow

dbus 1.6.12(kubuntu 13.10など)以降、dbus構成ファイル(/etc/dbus-1/mybus.confまたは)に追加しない限り、接続も拒否されますリモートアクセスを必要とするインターフェース、すなわちsystem.d /my.interface.conf

<apparmor mode="disabled"/>

UPDATE:サービスがカスタムdbus-daemonに接続できるようにするapparmorプロファイルの作成に苦労した後、バグのために接続が常に拒否されているようですDBUSで...したがって、今のところ、tcp = ...を使用するたびにapparmorを無効にする必要があります14.04を対象としたバグ修正

bugs.launchpad.net 次の議論でバグを開きました ここ タイラーヒックスと:

AppArmorメディエーションコードには、UNIXドメインソケットを介してピアラベルをチェックする機能しかありません。ラベルを取得してから接続を拒否すると、エラーが発生する可能性があります。

注:無効化フラグはdbus <1.6.12で認識されないため、systenに応じて異なるバージョンのmydaemon.confをパッケージ化する必要があります)。そうしないと、apparmorがない場合、dbus-daemonは起動時に失敗します...私のCMakeLists.txt:

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")
7
altagir

@Shorinと別のFYIに感謝します-私は私の仕事をするためにこのようなことをしなければなりませんでした:

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

bind=0.0.0.0-bind=*が機能しなかったため、family=ipv4の部分を省略したことに注意してください。私はUbuntu12.04を使用しています。リモートマシンでnetstatを使用して、dbusがポートをリッスンしていることを確認し、ローカルからtelnetを使用して、ポートが開いていることを確認しました。

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のようなものを見る必要があります。

3
kepler22b