chown `/usr/local` 安全吗?

PR3*_*R3x 15 permissions chown

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

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

另外,如果你有本地编译的软件安装到/usr/local. 这似乎不安全 - 我只想sudo在我确切知道会发生什么时使用。

意见?

H.-*_*itt 5

这是不同寻常的/usr/local不归root。但是您可以根据需要更改所有者。

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

  • 我之前安装了 bower,教程建议执行 chown -R $USER /usr/local 所以我现在正在运行 chown -R root /usr/local/sbin - /usr/local 中还有其他文件夹吗?拥有根所有权会更好吗?我应该在运行命令之前检查所有权限。瞬间“后悔莫及”。 (2认同)
  • 这个答案令人不满意,解释也不完全正确。如果出于安全原因,必须保持 root 依赖的命令归 root 所有,那么 root(以及其他用户)可能运行的 `/usr/local/bin` 中的命令呢?它们不需要由 root 拥有吗?此外,root 使用的命令——包括`/usr/local/sbin` 中的命令——可能依赖于`/usr/local/lib` 中的共享库。更改这些库可以对使用它们的命令的行为进行任意更改。坚持只有 `/usr/local/sbin` 仍然归 root 所有似乎完全是武断的。 (2认同)

Zan*_*nna 5

我不建议成为/usr/local; 在大多数情况下,它可能不如使用sudo.

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

首先是避免必须使用sudo安装软件。这可能会读到某些人(例如此答案的作者)说您想要高效工作,或者保存键入sudo和输入密码所需的击键。但可能当您说“不必要”时,您指的是最小特权原则

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

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

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

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

如果您chown /usr/local任何以您的权限运行的程序都可以在那里写入文件,这些文件以后可能会出于某种原因以 root 身份执行,例如通过取代另一个同名命令。/usr/local/bin在默认值中$PATH,在sudo's 中secure_path,并且它在两者中的其他位置之前。所以如果我有两个可执行文件

/usr/local/bin/chown
/bin/chown
Run Code Online (Sandbox Code Playgroud)

当我执行sudo chown ...chown/usr/local/bin将被执行

但是您可能已经知道所有这些,因为您的第二个原因是关于安全性:

另外,如果你有本地编译的软件安装到/usr/local. 这似乎不安全 - 我只想sudo在我确切知道会发生什么时使用。

万一有必要在这里提到这一点,这是绝对正确的(根据FHS反正)安装本地编译的软件/usr/local,但在编译本身应该是在你做过什么地方$HOME,没有sudo,直到当你输入的最后一个步骤sudo make install或同等学历。

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

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

如果您担心允许程序安全地更新自身,您可能应该寻找替代方案(也许特定于程序,例如使用 python,或者您可以寻找适合您需求的 snap 或类似实现,或使用容器或 VM 以测试潜在的不安全软件),然后再公开系统位置(即使是相对用户的位置)以供普通用户运行的程序写入。在我看来,这与允许程序使用sudo.


Eli*_*gan 5

对于仅您需要的软件,请使用您的主目录而不是/usr/local.

您应该只配置/usr/local您的构建,以便它们安装在您的主目录而不是/usr/local. 这解决了更改 的所有权所带来的所有潜在问题/usr/local,包括其目录binsbin子目录在root的路径中的位置。

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

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

配置您的构建

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

./configure
Run Code Online (Sandbox Code Playgroud)

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

./configure --prefix=/usr/local
Run Code Online (Sandbox Code Playgroud)

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

./configure --prefix="$HOME"
Run Code Online (Sandbox Code Playgroud)

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

./configure --prefix=$HOME
Run Code Online (Sandbox Code Playgroud)

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

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

./configure --prefix=/home/username
Run Code Online (Sandbox Code Playgroud)

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

安装你的构建

运行之后make,您可能会习惯运行sudo make install,但是当您安装在自己的主目录中时,您不需要以 root 身份运行它,因此您可以并且应该省略sudo。赶紧跑:

./configure --prefix=/home/username
Run Code Online (Sandbox Code Playgroud)

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

make install
Run Code Online (Sandbox Code Playgroud)

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

运行你的程序

您的主目录的子目录可能bin是:

  • 已经在你的$PATH或者
  • $PATH如果您只是注销并重新登录,就会在您的帐户中。

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

make uninstall
Run Code Online (Sandbox Code Playgroud)

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

Ubuntu 14.04 等旧版本以及Ubuntu 17.10 等新版本均随之而来。然而,Ubuntu 16.04(可能是撰写本文时最受欢迎的版本)却有以下内容:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
Run Code Online (Sandbox Code Playgroud)

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

您的.profile文件是/etc/skel在创建用户帐户时从目录复制的。如果您的用户帐户是在较旧的 Ubuntu 版本上创建的,它会获得该版本的.profile,并且您的用户帐户不会通过升级到更新的版本而发生更改。

一旦bin您的主目录的子目录位于您的 中$PATH,您只需输入名称即可运行其可执行文件安装在那里的程序,就像您可以对由 Ubuntu 的包管理器安装的程序或安装在 中的程序执行的操作一样/usr/local

选项.local

您可能已经注意到,.profile在某些 Ubuntu 版本(包括如上所述的 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同名命令,则环境变量中第一个出现的目录就是命令将从中运行的目录。


感谢ZannaVideonauth指出了这个答案的先前版本中的错误,关于哪些 Ubuntu 版本在 中具有哪些默认代码.profile,并帮助我纠正它们(另请参阅此处)。