web-dev-qa-db-ja.com

D-Busの認証と承認

D-Busへのリモートアクセスを設定しようとしていますが、認証と承認がどのように機能しているか(機能していないか)がわかりません。

抽象ソケットでリッスンするD-Busサーバーがあります。

$ echo $DBUS_SESSION_BUS_ADDRESS 
unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31

dbus-monitorを実行して、何が起こっているかを監視します。テストケースはnotify-send helloで、ローカルマシンから実行した場合に機能します。

同じマシンの別のアカウントから、そのバスに接続できません。

otheraccount$ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31 dbus-monitor
Failed to open connection to session bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
otheraccount$ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31 notify-send hello

D-Bus仕様 を参照した後、~/.dbus-keyrings/org_freedesktop_generalを他のアカウントにコピーしましたが、役に立ちません。

schedarsocatを使用してリモートでD-Busにアクセスする からヒントを得て、TCP経由でD-Busソケットを転送してみました。

socat TCP-LISTEN:8004,reuseaddr,fork,range=127.0.0.1/32 ABSTRACT-CONNECT:/tmp/dbus-g5sxxvDlmz

アカウントからTCPソケットに接続できます。

DBUS_SESSION_BUS_ADDRESS=tcp:Host=127.0.0.1,port=8004 notify-send hello

ただし、他のアカウントからではなく、dbus-monitornotify-sendもありません。抽象ソケットを使用した上記と同じdbus-monitorのエラーメッセージ。 notify-sendがトレースを発行するようになりました:

otheraccount$ DBUS_SESSION_BUS_ADDRESS=tcp:Host=127.0.0.1,port=8004 notify-send hello

** (notify-send:2952): WARNING **: The connection is closed

紐付けにより、このバージョンのnotify-sendはCookieファイルを読み取ろうとしないため、接続できない理由がわかります。

別のマシンにSSHで接続し、TCP接続を転送しました。

ssh -R 8004:localhost:8004 remotehost

驚いたことに、dbus-monitorはCookieファイルなしで機能します。リモートホストからのD-Busトラフィックを監視できます。ローカルのdbus-monitorインスタンスで盗聴に関する通知が表示されます。

remotehost$ DBUS_SESSION_BUS_ADDRESS=tcp:Host=127.0.0.1,port=8004 dbus-monitor
signal sender=org.freedesktop.DBus -> dest=:1.58 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
   string ":1.58"
method call sender=:1.58 -> dest=org.freedesktop.DBus serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "eavesdrop=true"

ローカルマシンでnotify-sendを実行すると、リモートホストのdbus-monitorに通知が表示されます。認証が必要なアクセスレベルに確実に到達しています。

notify-sendはCookieが見つからないことについて不満を述べました。 Cookieファイルをコピーした後、notify-sendはリモートマシンから機能します。

ローカルマシンはDebian wheezyを実行します。リモートマシンはFreeBSD 10.1を実行します。

D-Busの認証と承認の仕組みがわかりません。

  1. リモートマシンからの資格情報なしで、知ることができる範囲で盗聴できるのはなぜですか? D-BusをTCP接続に転送するときに何を公開していますか?dbus-monitornotify-sendの認証が異なるのはなぜですか?
  2. 抽象ソケット上でも、TCP接続上でも、同じマシン上の別のアカウントから盗聴できないのはなぜですか?
  3. Cookieファイルが数分ごとに変化することに気付きました(定期的な間隔かどうかはわかりません)。どうして?

(私はTCPをリッスンするD-Busデーモンを起動できることを知っています。それは私の質問の目的ではありません。なぜ私が何をし、何が機能しなかったのかを理解したいのです。)

D-Busは、ここではマジッククッキーファイルを使用していません。 UNIXドメインソケット(SCM_CREDENTIALS)を介して資格情報を渡しています。

Magic cookieファイルは、いくつかのD-Bus認証メカニズムの1つにすぎません。 D-Busは [〜#〜] sasl [〜#〜] 準拠のインターフェース( RFC4422 を参照)を実装して、幅広い認証メカニズムをサポートします。これらのメカニズムの1つは「外部」認証と呼ばれ、トランスポートチャネル自体を使用して認証を保証する必要があることを意味します。少なくともUNIXソケット経由のD-Busの場合、これは最初に試行される認証メカニズムのようです。

D-Bus仕様から:

特別な資格情報を渡すNULバイト

サーバーに接続した直後に、クライアントは単一のnulバイトを送信する必要があります。このバイトには、SCM_CREDSまたはSCM_CREDENTIALSでsendmsg()を使用してUNIXドメインソケットを介して資格情報を渡す一部のオペレーティングシステムの資格情報が伴う場合があります。ただし、nulバイトは、他の種類のソケットや、資格情報を送信するためにバイトを送信する必要がないオペレーティングシステムでも送信する必要があります。このドキュメントで説明するテキストプロトコルは、1つのnulバイトの後に始まります。クライアントから受信した最初のバイトがNULバイトでない場合、サーバーはそのクライアントを切断することがあります。

最初のバイト以外のコンテキストでのNULバイトはエラーです。プロトコルはASCIIのみです。

Nulバイトと共に送信される資格情報は、SASLメカニズムEXTERNALで使用できます。

dbus-daemonのインスタンスを追跡すると、それに接続すると、接続しているユーザーの資格情報がチェックされることがわかります。

$ strace dbus-daemon --session --nofork
...
accept4(4, {sa_family=AF_LOCAL, NULL}, [2], SOCK_CLOEXEC) = 8
...
recvmsg(8, {msg_name(0)=NULL, msg_iov(1)=[{"\0", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
getsockopt(8, SOL_SOCKET, SO_PEERCRED, {pid=6694, uid=1000, gid=1000}, [12]) = 0

だからあなたの質問に答えるには:

  1. D-Busデーモンは、カーネルで検証されたユーザーIDを使用してIDを検証しています。 socatをプロキシ接続に使用することで、UIDを使用して誰でもD-Busデーモンに接続できるようになります。

  2. 別のUIDからソケットに直接接続しようとすると、デーモンは、接続しているUIDが接続を許可されているはずのUIDではないことを認識します。デフォルトでは、デーモン自体のUIDのみが許可されていると思いますが、正式には確認されていません。ただし、他のユーザーを許可することもできます。/etc/dbus-1/およびman dbus-daemonの構成ファイルを参照してください。

  3. これは、古い/期限切れのCookieを新しいものに置き換えるD-Busサーバーです。 D-Bus仕様の DBUS_COOKIE_SHA1 セクションによると、Cookieはその作成時間とともに保存され、サーバーは古すぎると判断したCookieを削除することになっています。どうやら寿命は「かなり短くなる可能性がある」。

7
Jander