当我们安装/删除/更新软件包或进行任何需要管理权限的更改时,我们会被提示输入具有权限的管理员用户的密码sudo
- 这会通过 GUI 和终端进行。
但是,如果我们尝试通过终端关机并重新启动,它会抱怨我们需要root
:
$ reboot
reboot: Need to be root
$ shutdown now
shutdown: Need to be root
但是,当我们通过右上角的齿轮执行这些操作时,我们从来不会要求输入密码。
为什么会有这种差异?
答案1
齿轮上的关机检查您是否有权关闭机器。这是通过 PolicyKit 完成的。如果要关机,/usr/share/polkit-1/actions/org.freedesktop.consolekit.policy
将检查文件中的以下语句:
<action id="org.freedesktop.consolekit.system.stop">
<description>Stop the system</description>
<message>System policy prevents stopping the system</message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
PolicyKit 触发dbus-send
命令。如果关闭,则命令如下:
dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown
有一个守护进程在后台以 root 权限运行,它会为您调用关机命令。
如果您希望能够通过命令行 ( shutdown, reboot, halt, ...
)“以老方法”关闭机器,则需要在这些命令中添加 suid 位。但请注意,系统上有权访问 shell 的每个人都可以关闭您的机器。
答案2
Ubuntu 是 GNU/Linux 操作系统的一个发行版,而 GNU/Linux 操作系统又属于 Unix 系统家族——许多现代操作系统的通用架构。
传统上,Unix 通常在大型计算机上运行。中央计算设施通过远程终端为数十或数百名用户提供服务。由于所有用户都依赖于大型机的可用性,因此不允许任何单个用户发出关机命令。Unix 架构的一个基本思想是 - 系统内核永远不会初始化关机,除非超级用户进程调用相应的函数。
在当代桌面系统中,开发人员已经付出了一定的努力,使普通桌面用户可以关机。一种常见的技术是让通常在 root 用户的安全上下文中运行的登录管理器处理关机和重启。在这种情况下,图形外壳会向登录管理器发出关闭计算机的请求。这涉及使用进程间通信 (IPC),通常通过 dbus 服务。
上面提到的 policykit 通过提供一个标准化框架扩展了此过程,通过该框架登录管理器(或任何提供关机服务的程序)可以检查哪些用户被允许导致关机,并且管理员可以通过该框架分别配置这些权限。
一些桌面环境不使用基于 IPC 的服务,而是使用一组辅助程序来提供相同或类似的功能。这些辅助程序将通过允许切换到超级用户上下文的机制调用,例如 sudo、suid 或类似于 sudo 的 policykit 机制。
无论如何,shell 上愚蠢的传统关机程序不会以这种方式工作,它要求您看到它是在超级用户上下文中运行。
答案3
因为 Linux 通常用作服务器或类似设备,并且通过 SSH 进入 Linux 机器,甚至是普通的 Ubuntu 笔记本电脑,也很常见。
问题是,您可能不希望拥有 SSH 访问权限的人能够关闭它,尤其是当可能有其他远程登录用户使用它时。有权访问 GUI 的人 — 好吧,他无论如何都可以使用物理电源按钮自行关闭它。
此外,远程登录的用户将无法重新打开它。
答案4
您无需以 root 身份从 GUI 启动关机,很大程度上是为了方便典型的桌面用户。系统知道您是登录控制台的用户,因此如果您错误地关闭计算机,您可以将其重新打开。
对于 shell 中的用户,您很可能远程登录,因此系统要求您以 root 身份登录才能发出关机命令。这可以防止登录到服务器的普通用户在其他人使用服务器时将其关闭,尽管不一定有人在现场重新启动计算机。
关机不提供 GUI 提示输入超级用户密码的原因可能只是因为那里没有真正的实用性 - 如果您在控制台上,提示会出现,那么您可以使用齿轮菜单。如果您想在关机时使用命令行提示输入超级用户密码,那么“sudo shutdown”已经可以做到。