为什么 sudo -i 没有为目标用户设置 XDG_RUNTIME_DIR?

为什么 sudo -i 没有为目标用户设置 XDG_RUNTIME_DIR?

XDG_RUNTIME_DIRsystemctl --user工作所必需的。

我已经设置了 ubuntu 服务器 16.04 来运行 systemd 用户会话。现在,当尝试管理它们时,我发现当通过sudo -u $user -i或什至更改用户时su - $user,环境没有XDG_RUNTIME_DIR设置,导致无法systemctl --user工作。但是,当我ssh直接进入该用户时,它设置正确。

如果我正确理解文档,这应该在libpam-systemd创建用户会话时设置。用户片正确启动,因为应该XDG_RUNTIME_DIR指向的目录( /run/users/$uid)存在。我很犹豫是否将其硬编码为,例如,,.bash_profile因为这看起来很老套(尽管有效),而 pam 应该处理它。

当然,我可以添加XDG_RUNTIME_DIRenv_keepin sudoers,但这只会保留 sudoing 用户的环境,这不是我想要的。我想要目标用户的环境。

不过,我真正想知道的是,为什么使用 正确设置会话ssh,而不是使用suor正确设置会话sudo -i

答案1

我已经在我的 Fedora 25 系统上复制了这个问题。

我在源代码中发现了一个非常可疑的情况。 https://github.com/systemd/systemd/blob/f97b34a/src/login/pam_systemd.c#L439 看起来好像是按平常心写的,sudo但其实不然sudo -u non-root-user

machinectl shell --uid=non-root-user按您的要求工作。

systemd-run尽管在 machinectl 文档中引用了它,但似乎没有按预期工作。

如果您目前启用了 SELinux,某些 machinectl 命令将不起作用,并且这些特定命令在我启用之前对我不起作用setenforce 0。然而,我正在尝试解决方法,让 machinectl 正常工作,因为我希望它能与 SELinux 一起工作,所以我的摆弄可能是导致machinectl shell超时的原因。

编辑:我认为这段代码是在之后引入的这次讨论。显然su -/sudo -i可以工作,但没有人(仍然)实现它。

相关提交是https://cgit.freedesktop.org/systemd/systemd/commit/?id=baae0358f349870544884e405e82e4be7d8add9f

答案2

不过,我真正想知道的是,为什么使用 ssh 正确设置会话,而不是使用 su 或 sudo -i 正确设置会话?

https://github.com/systemd/systemd/issues/7451#issuecomment-346787237

抱歉,“su”是一个用于临时更改用户身份和极少数其他进程凭据的工具。它不是用于打开全新登录会话的工具。新的登录会话具有定义良好的原始设置,不会从任何其他会话继承任何内容,但“su”uid 更改实际上并非如此:大多数执行环境都是继承的,以大量且不明显的方式继承方式,例如 MAC 上下文、审计上下文、cgroup 上下文、命名空间上下文、调度、计时器粒度……

如果你想要一个完整的新会话,请使用“machinectl login”或“machinectl shell”之类的东西,这实际上会给你一个完全干净、独立、分离的环境,没有隐藏的进程属性从你调用它的地方泄漏。

登录会话主要与审计会话概念绑定,并且审计会话不受“su”的影响,实际上它们被定义为“密封”,即如果进程进入会话一次,它将永远停留在有了它,它的子进程也会如此,即获得新会话的唯一方法是从 PID 1(或类似的东西)中分叉出从未属于会话一部分的东西。

或者换句话说:您通过“su”调用的内容将很好地显示在“loginctl”中,但是,它仍然是您最初登录的原始会话的一部分。您可以通过在原始会话 ID 上调用“loginctl status”来验证这一点(您可以通过 echo $XDG_SESSION_ID 查看)

答案3

我发现sudo -E bash正确运行可以保存XDG_RUNTIME_DIR

答案4

对于那些仍然想要sudo -i解决方案的人,您可以安装一个 pam 模块来创建XDG_RUNTIME_DIR.一个例子是帕姆_xdg

您的发行版不太可能有该pam_xdg软件包,因此要安装此模块,您必须自己弄清楚如何安装。我使用 Gentoo 并创建了一个安装该模块的 ebuild,但我尚未发布它,因为我的覆盖层有大量需要最终确定的开发提交。上传后我会更新这个答案。

正确安装 pam 模块后,在 中添加以下行/etc/pam.d/sudo-i

session optional        pam_xdg.so

指定required而不是optional如果首选。

请注意,此模块尝试生成默认的 XDG 值,并且pam_systemd.so可能会执行不同的操作,因此与仅使用machinectl shell.

相关内容