chown `/usr/local` 安全吗?

chown `/usr/local` 安全吗?

我知道 的用途/usr/local是 - 为本地机器安装软件。默认情况下,root拥有目录。这意味着要在那里安装,您需要使用sudo。对于单用户或开发人员机器,这似乎是不必要的额外使用命令。因此,我的问题是 - 拥有 对我来说安全吗/usr/local

例如,Homebrew for OS X“Just Works”,因为他们拥有/usr/local安全地安装他们的软件,无需使用sudo

此外,如果您在 上安装了本地编译的软件/usr/local,则该软件目前需要 root 权限才能自行修改或安装插件。这似乎不安全 - 我只想sudo在知道确切地会发生什么。

有什么看法?

答案1

我不建议成为 的所有者/usr/local;大多数情况下,它可能不如使用 安全sudo

您的问题表明了您可能想要的两个原因chown /usr/local

第一是避免必须使用sudo安装软件。这可能对某些人(例如这个答案)表示您希望高效工作,或保存键入sudo和输入密码所需的按键。但当您说“不必要”时,您指的是最小特权原则

默认情况下,root拥有该目录。这意味着要在那里安装,您需要使用sudo。对于单用户或开发人员计算机,这似乎是不必要的额外使用命令

我经常听到/读到人们发表/抱怨这样的观点:“我是唯一使用这个系统的人,所以我不应该需要使用sudo和输入密码。”对于持这种观点的读者,并且因为这与此相关,让我们提醒自己 root 拥有东西的基本安全原因。

Ubuntu 系统上安装的大多数程序文件的文件模式为 755,或者用符号表示rwxr-xr-x为 ,这意味着任何用户或程序都可以执行它们,但只有文件所有者 root 可以修改它们。(从技术上讲,这还要求除了 root 之外,没有人对w包含它们的目录拥有权限,因此其他用户无法删除或移动它们。)

这意味着您,普通用户可以执行任何程序。如果您尝试使用程序执行您无权执行的操作,例如对 root 拥有的文件执行写入操作,则程序会出错。这使得某些命令中的拼写错误、有缺陷的应用程序或恶意代码不太可能扰乱您的系统 - 除非它以 root 身份运行,否则它无权这样做。这在运行与互联网交互的程序时尤其有用。

如果你chown /usr/local任何以你的权限运行的程序可以在那里写入文件,这些文件稍后可能会因为某种原因以 root 身份执行,比如取代另一个同名的命令。/usr/local/bin在默认情况下$PATH,并且sudosecure_path,它来了在其他位置。因此,如果我有两个可执行文件

/usr/local/bin/chown
/bin/chown

当我执行时sudo chown ...chown/usr/local/bin执行

但你可能已经知道了这一切,因为你的第二个原因与安全性有关:

此外,如果您在 上安装了本地编译的软件/usr/local,则该软件目前需要 root 权限才能自行修改或安装插件。这似乎不安全 - 我只想sudo在知道确切地会发生什么。

以防万一需要在这里提一下,将本地编译的软件安装到 是绝对正确的(无论如何根据 FHS)/usr/local,但编译本身应该在您的 中的某个地方完成$HOME,无需sudo,直到您输入 或等效项的最后一步sudo make install

我认为您建议通过运行/usr/local以非特权所有者身份安装的程序,您可以使用在尝试更新自身时抛出的特定权限错误来查看它是否试图以您不想要的方式修改不属于您的其他文件系统位置,以便您可以阻止它这样做。

可能有帮助。言外之意是你信任程序在 内做任何它想做的事情/usr/local,但不能在其他地方做。如果它请求提升的权限,你可以拒绝允许它更新,或者卸载它。这对我来说很有道理。但我认为试图/usr/local以这种方式将其用作一种沙盒可能不是一个好主意,或者至少它不太可能是最安全的解决方案。它不是一个完全隔离的位置(/opt稍微隔离一点,因为它不在默认的 中$PATH)。程序可能会在其中写入或删除某些内容/usr/local以造成危害。您运行的其他(可能编写不当的)程序可能会在那里编写和执行您不知道的代码。

如果您担心允许程序安全地自我更新,那么在将系统位置(即使是相对用户化的位置)暴露给普通用户运行的程序进行写入之前,您可能应该寻找替代方案(可能针对该程序,例如使用 python,或者您可以寻找适合您需求的 snap 或类似实现,或者使用容器或 VM 来测试潜在的不安全软件)。在我看来,这可能产生不可预测的影响,就像允许程序使用 暂时提升权限一样sudo

答案2

/usr/local不属于 的情况很不寻常root。但您可以根据需要更改所有者。

但我建议确保/usr/local/sbin仍由 拥有root以避免安全问题。这里的命令通常只能由 root 调用。

答案3

仅适用于软件需要时,请使用你的主目录,而不是/usr/local

您无需更改 的所有权/usr/local或以 root 身份运行命令(如果您不想这样做),只需配置您的构建,使其安装在您的主目录中,而不是/usr/local。这解决了更改 所有权的所有潜在问题/usr/local,包括其binsbin子目录在root的路径中的位置。

如果你确实需要允许其他用户运行你的软件,你可以授予他们访问权限。事实上,他们可能已经可以这样做了,因为默认情况下你的主目录有允许读取和执行访问. (如果您不想要这样,您可以很容易地更改它,只需在chmod您想要设为私有的任何文件或目录上使用 ,并可能更改您的umask。)

如果软件安装在您的主目录中,则原本应该进入的二进制文件/usr/local/bin将进入。您将获得主目录中的其他子目录,这些子目录与您安装的软件所需的子目录相对应。当您从源代码安装软件时,这通常会自动发生。/home/username/bin/usr/local

配置你的构建

从源代码构建的大多数软件都有一个运行步骤:

./configure

对于大多数附带可以这样运行的脚本的软件,当您最终运行安装时configure,它默认在内部配置要安装的构建。原因是它隐式等同于运行:/usr/localsudo make install

./configure --prefix=/usr/local

要配置在主目录中安装的版本,请使用以下命令:

./configure --prefix="$HOME"

实际上,在 Ubuntu 中,主目录路径不包含空格、其他空白或其他将被 shell 特殊处理的字符*,因此,除非您设置的用户帐户非常奇怪,否则您只需输入:

./configure --prefix=$HOME

(我不建议养成这样的习惯编写脚本但是。另外,在某些其他操作系统(例如 macOS)上,用户主目录的路径包含空格的情况并不罕见。)

或者如果您愿意,您可以输入完整的主目录路径:

./configure --prefix=/home/username

(代替username当然,请使用您的实际用户名。如果出于某种原因您的主目录不在,/home那么您必须进行相应调整。)

安装你的构建

运行后make,您可能习惯于运行sudo make install,但是当您在自己的主目录中安装时,您不需要以 root 身份运行它,因此您可以 - 并且应该--omit sudo. 只需运行:

make install

同样,对于支持uninstall目标的软件:

make uninstall

这正是您所要求的……只是在您的主目录中,而不是/usr/local

运行你的程序

大概bin您的主目录的子目录可以是:

  • 已经在你$PATH或者
  • $PATH如果您注销并重新登录,就会出现在您的

原因是,.profile您的主目录中的文件(其中包含您登录时运行的命令)默认包含此文件,用于在大多数版本Ubuntu(包括安装操作系统时创建的初始管理员帐户):

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

该代码在您登录时运行(因为它在.profile),并将您的个人bin目录放在$PATH 仅当当时存在时。这就是为什么您可能需要注销并重新登录。

旧版本比如 Ubuntu 14.04,以及较新版本Ubuntu 17.10 等操作系统都带有该功能。但是,截至本文撰写之时,Ubuntu 16.04(可能是最受欢迎的版本)却带有该功能:

# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"

这只是将bin主目录的子目录以及.local/bin子目录添加到您的$PATH,而不检查这些目录是否实际存在。因此,如果您使用 16.04,或者如果您升级当您创建用户帐户时系统版本为 16.04,那么bin您的主目录的子目录很可能已经在您的$PATH.

创建用户帐户时,.profile会从目录中复制文件。如果您的用户帐户是在较旧的 Ubuntu 版本上创建的,则它已获得该版本的,并且它不会因升级到较新版本而更改(对于您的用户帐户而言)。/etc/skel.profile

一旦bin您的主目录的子目录位于您的中$PATH,您将能够通过输入其名称来运行安装在那里的可执行文件的程序,就像您对由 Ubuntu 的包管理器安装的或在 中安装的程序所做的那样/usr/local

选项.local

你可能已经注意到,在某些 Ubuntu 版本中创建的用户帐户的默认.profile文件(包括上述的 16.04 版本)不仅会添加$HOME/bin到你的路径中,还会添加到你的路径中$HOME/.local/bin。如果你.profile没有添加该文件,但你然后您就可以简单地对其进行编辑。

尽管通常用于存储设置和缓存数据,您还可以在.local主目录的子目录中安装软件。您应该会觉得这样做毫无顾忌,因为从可用性和安全性的角度来看,--prefix="$HOME/.local"这类似于--prefix="$HOME"

请记住,以 开头的文件和目录.在图形文件浏览器中默认不显示(使用Ctrl+H取消隐藏并重新隐藏它们),在命令中也不显示ls(传递-A-a标志来显示它们)。这可能不是您想要的,也可能正是您想要的。这是个人喜好的问题。

但是,我观察到一些基于源代码的自动化软件包管理器在用户主目录中构建和安装软件时使用$HOME/.local。我实际上并不知道这种情况有多普遍——我希望进一步调查并更新这个答案——但您可能更喜欢只使用$HOME来手动编译内容。这样就可以清楚地知道内容来自哪里。而且如果发生冲突,软件仍然可能以可接受的方式共存。

您也可以故意在 中安装一些软件,$HOME/.local在 中安装其他软件$HOME。这取决于您。如果两个目录中都存在同名的命令,则环境变量bin中首先出现的目录就是运行命令的目录。$PATH


功劳归于扎娜视频直播为了指出错误在一个先前版本关于哪个 Ubuntu 版本具有哪些默认代码.profile,以及帮助我纠正他们(另见这里)。

答案4

如果 sudo 很不方便,那么只需更新 /etc/sudoers,这样您在运行 sudo 时就不必输入密码。我相信这是比更改 /usr/local 所有者更好的解决方案。

相关内容