您的观点都很好,而且您是正确的,但在我们对此感到愤怒之前,我们需要提醒自己 linux 安全模型是如何工作的以及它旨在保护什么。
请记住,Linux 安全模型在设计时考虑了多用户终端或 SSH 服务器。Windows 在设计时考虑了最终用户工作站(但我听说最新一代的 Windows 对终端更友好)。特别是,Linux 约定在将应用程序沙箱化给用户方面做得更好,而在 Windows 中,任何重要的东西都作为系统运行,而 Linux GUI(X 服务器)在安全性方面很糟糕,而 Windows GUI 具有内置 UAC 之类的花哨的东西。基本上,Linux 是(并且一直是)首先是服务器,其次是工作站,而 Windows 则相反。
安全模型
就“操作系统”(即内核)而言,您有 7 个 tty 控制台和任意数量的 SSH 连接(也称为“登录会话”)——恰巧 ubuntu 附带了自动启动 GUI 的脚本会话,但对tty7
内核来说,它只是另一个应用程序。
登录会话和用户帐户彼此很好地被沙盒化,但 Linux 采取了一种安全心态,即您不需要保护用户免受他们自己的伤害。在这种安全模型中,如果您的帐户受到恶意软件的入侵,那么这是一个失败的原因,但我们仍然希望将其与其他帐户隔离开来,以保护整个系统。
例如,Linux 应用程序倾向于创建一个低权限用户,apache
或者ftp
在不需要做根深蒂固的事情时运行。如果攻击者设法控制了一个正在运行的apache
进程,它可以破坏其他apache
进程,但在跳转到ftp
进程时会遇到麻烦。
请注意,Windows 在这里采用了完全不同的方法,主要是通过所有重要事物始终作为系统运行的约定。与作为系统运行的恶意进程相比,Linux 中的恶意服务做坏事的范围更小,因此 Windows需要付出额外的努力来保护具有管理员权限的人免受“他们自己”的侵害。
GUI 环境和不是为安全而设计的 X 服务器会影响这种安全模型。
Gnome gksudo 与 Windows UAC 和键盘记录器
在 Windows 中,当用户进程请求提权时,内核会抛出一个特殊的受保护提示,其内存和键盘/鼠标总线与桌面环境的其余部分隔离。它可以做到这一点,因为 GUI 是内置在操作系统中的。在 Linux 中,GUI(X 服务器)只是另一个应用程序,因此密码提示属于调用它们的进程,以您的身份运行,与所有其他以您身份运行的窗口和进程共享内存权限和输入总线。
root 提示不能做花哨的 UAC 事情,比如锁定键盘,因为那些要么已经是 root,要么需要完全重新设计 X 服务器(参见下面的 Wayland)。一个 catch-22 在这种情况下是将 GUI 与内核分离的缺点。但至少它符合 Linux 安全模型。
如果我们要修改安全模型以通过在密码提示和在同一 GUI 会话中以用户身份运行的其他进程之间添加沙盒来限制这一点,我们可能不得不重新编写很多东西。至少,内核需要具备 GUI 感知能力,以便能够创建提示(今天并非如此)。另一个首选示例是 GUI 会话中的所有进程共享一个键盘总线。
看我写一个键盘记录器,然后在另一个窗口中按一些键:
➜ ~ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Logitech K400 Plus id=9 [slave pointer (2)]
⎜ ↳ ETPS/2 Elantech Touchpad id=13 [slave pointer (2)]
➜ ~ xinput test 9
key release 36
key press 44
hkey release 44
key press 40
ekey release 40
key press 33
lkey release 33
key press 33
lkey press 39
okey release 33
key release 39
key press 66
key press 31
任何以您身份运行的进程都可以在另一个进程的提示符或终端中嗅探密码,然后对其自身调用 sudo(这直接源于“无需保护您”的心态),因此提高密码提示的安全性是无用的,除非我们从根本上改变了安全模型,并对各种事情进行了大规模重写。
(值得注意的是,Gnome 似乎至少将锁定屏幕上的键盘总线和通过“切换用户”的新会话沙箱化,因为在那里键入的内容不会显示在我会话的键盘总线中)
韦兰
Wayland 是一个旨在取代 X11 的新协议。它锁定客户端应用程序,使它们无法窃取信息或影响窗口外的任何内容。客户端可以在外部 IPC 之外相互通信的唯一方法是通过控制所有客户端的合成器。然而,这并不能解决根本问题,只是将信任需求转移给了合成器。
虚拟化和容器
如果您使用云技术,您可能会跳来跳去地说“Docker 就是答案!!”。的确,布朗尼为你加分。虽然 Docker 本身并不是真正打算增强安全性(感谢@SvenSlootweg),但它确实指出使用容器化和/或虚拟化作为与当前 Linux 架构兼容的前向。
两个著名的 Linux 发行版在构建时考虑了进程间隔离:
Qubes OS在多个虚拟机中运行用户级应用程序,这些虚拟机被划分为“安全域”,例如工作、银行、网络浏览。
Android作为单独的低权限用户安装和运行每个应用程序,从而在应用程序之间获得进程级隔离和文件系统隔离(每个应用程序都被限制在自己的主目录中)。
底线:从最终用户的角度来看,期望 Linux 以与 Windows 相同的方式运行并非不合理,但这是您需要了解底层系统如何工作以及为什么会这样的情况之一那样设计的。只要密码提示由您拥有的进程拥有,简单地更改密码提示的实现将不会完成任何事情。Linux 要在单用户 GUI 工作站的上下文中获得与 Windows 相同的安全行为,需要对操作系统进行重大的重新设计,因此不太可能发生,但像 Docker 这样的东西可能会在更多的 Linux 中提供前进的道路——原生方式。
在这种情况下,重要的区别在于 Linux 在底层设计为多用户服务器,并且他们决定不保护用户免受他们自己的伤害,而 Windows 被设计为单用户工作站,所以您确实需要在登录会话中进行进程间保护。同样重要的是,在 Windows 中,GUI 是操作系统的一部分,而在 Linux 中,GUI 只是另一个用户级应用程序。