`logname` 实用程序的正确替代品?

Wan*_*rer 4 users who

logname工具变成不可用前一段时间对于许多用户,因为它依赖于一些已被打破故意出于安全考虑,为讨论在这里。在我阅读讨论时,该功能不太可能恢复。

我使用了一段时间的变通方法,但现在我觉得它们开始站不住脚,所以我正在寻找一个合适的长期解决方案,我很惊讶地看到,似乎没有太多.

最常链接到的解决方案在此处提供,但它源自此处,其中还存在一个提示,即通过环境变量提出的解决方案SUDO_USER不可移植。

另一个提议的解决方案是创建一个包含用户名的文件并编写一个 bash 别名或类似的来模拟日志名功能,但我不会称其为合适的替代品,至少因为它假设了对环境的一定程度的可控性至少在最起码的情况下,并不总是可能的,更好说。

who来自此处的解决方案很有趣,但我找不到有关是否存在相关可靠性或可移植性限制的任何信息。

除了这些方法之外,这个领域的空气越来越稀薄,所以我决定在这里提问,希望对这个话题和我的想法有一些新的投入。

Gil*_*il' 5

TL,DR:您可能想要,即使它的行为并不总是匹配。但它不适用于所有发行版。请注意,我的回答假设是 Linux,它不适用于其他 Unix 变体。/proc/PID/loginuidlogname

我不认为你会找到一个完全令人满意的答案,因为你对做什么没有明确的期望logname。一方面,您当前使用的logname是基于 utmp 记录的 utmp 记录——将用户与终端关联的记录,并且在终端模拟器的善意下更新(许多人没有)。另一方面,您希望“更改用户名的可能性应该仅限于超级用户”。utmp 记录不是这种情况!正如您引用的评论线程中所解释的那样,utmp 记录大部分时间都在工作,但它们可以被伪造。

定义“用于登录控制台的用户名”是有问题的。名义上的情况已经够清楚了,但还有很多复杂的情况。如果用户呼叫su并附加到另一个用户的屏幕会话会发生什么?如果用户附加到另一个用户的 X11 或 VNC 会话会发生什么?你如何追踪进程到终端——你如何处理没有控制终端的进程?

Linux 实际上确实有“登录 UID”的概念。它对于每个进程都是可见的。内核会跟踪此信息,但是用户层可以让内核知道何时发生登录。这通常通过pam_loginuid完成。在幕后,它是通过写入来完成的。Linux 的登录 UID 遵循进程祖先,这并不总是正确的定义,但具有简单的优点。/proc/PID/loginuid/proc/self/loginuid

请注意,如果进程的登录 UID 为 4294967295,则该进程可能会更改它。Init 以登录 UID 4294967295 开头(等于 -1 作为 32 位值);这通常表示一个不属于任何登录会话的进程。只要登录过程正确设置了登录 UID(就在它设置从 root 到登录用户的真实 UID 之前),就可以了。但是如果有一种方法可以在没有设置登录 UID 的情况下登录,那么用户可以声明他们选择的任何登录 UID。因此,只有在系统上运行进程的所有方式都经过设置登录 UID 的步骤时,此信息才是可靠的——忘记一个,信息就变得无用了。

实验上,在 Debian jessie 机器上,我所有长期运行的登录 UID 为 -1 的进程都是系统服务。但是有一些方法可以运行登录 UID 为 -1 的进程,例如通过 incron。我不知道还有多少其他方式;incron 是我尝试的第一个,并且奏效了。在 Ubuntu 16.04 机器上,pam_loginuidlightdm的条目被注释掉了,我还没有调查原因。也许 Ubuntu 的 lightdm 和 incron 应该被视为安全漏洞,但事实是,今天你不能依赖主要发行版中开箱即用的登录 UID。

另请参阅Loginuid,是否应该允许更改(是否可变)?,这是关于防止 root 更改登录 UID 的内核选项。但要注意,它只有在登录 UID 设置为正确值后才有效;如果用户在登录 UID 仍设置为 -1 的情况下运行进程,则他们可以将其设置为任何他们想要的。事实上,让 init 切换到一个不同的值,比如 -2,并pam_loginuid覆盖那个值会更安全;那么 -1 永远不会发生,-2 表示“未知”。