所以我有一个守护进程,用于通过 Azure Entra Id 对用户进行身份验证(守护进程是 Himmelblaud)。我正在编写一个会话 D-Bus 服务(这里的基本框架),为正在运行的各种应用程序(例如 MS 应用程序、浏览器插件、gnome-online-accounts 等)提供 SSO 凭据。此 D-Bus 服务将模仿 MS Intune D-Bus 服务。本质上,我是为 MS 的专有二进制文件提供开源的直接替代品。
所以问题是,如何在守护进程(在 systemd 动态用户下运行)和会话 D-Bus 服务(作为需要凭据的经过身份验证的用户运行)之间安全地传输适当的凭据?除了从该守护进程以某种方式获取这些信用之外,没有其他方法可以访问它们。
我正在沿着 unix 套接字的思路思考,但要验证连接的 D-Bus 会话是否来自有权请求这些凭据的用户。但这安全吗?
我想要避免的情况是一个具有多个经过身份验证的用户的系统,并且让某些用户与守护进程通信并请求其他人的 Entra Id 访问令牌等。
您可以在会话服务和系统服务之间设计一个自定义的 Unix 套接字协议,该协议使用
SO_PEERCRED
或 SCM_CREDENTIALS
功能 – 如果 Samba 和 Winbindd 已经有很多示例,我不会感到惊讶 – 但这似乎是一种浪费由于您的项目已经涉及 D-Bus(通常在相同的 Unix 套接字上工作),因此最简单的方法是使系统守护进程也成为 D-Bus 服务并利用现有代码。
对 dbus-daemon 本身有一个特殊的 D-Bus 调用,您的系统守护进程可以使用它来获取总线上任何实体的连接凭据 - 许多 D-Bus 库为这些调用提供特定的绑定,例如zbus 中的 get_connection_credentials() 和 get_connection_unix_user(),但也可以在“总线对象”上手动调用:
org.freedesktop.DBus
/org/freedesktop/DBus
org.freedesktop.DBus.GetConnectionCredentials(s bus_name)
org.freedesktop.DBus.GetConnectionUnixUser(s bus_name)
...其中参数是 D-Bus 库为服务的方法调用实现提供的原始调用者的唯一总线名称(
:1.xyz
字符串)。
系统总线上的大多数(如果不是全部)服务都依赖于这种机制 - 其中一些使用总线策略(其中 dbus-daemon 直接应用基于 Unix 客户端 UID/GID 的限制),而大多数其他服务直接获取调用者凭据并制定自己的决定。