AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 447305
Accepted
mur
mur
Asked: 2018-06-02 04:29:02 +0800 CST2018-06-02 04:29:02 +0800 CST 2018-06-02 04:29:02 +0800 CST

如果我的应用程序从一开始就可以在较低级别运行,我为什么要 chroot 进行沙盒以确保安全?

  • 772

我正在用 C 语言编写一个 HTTP 服务器守护程序(这是有原因的),并使用 systemd 单元文件对其进行管理。

我正在重写一个 20 年前设计的应用程序,大约在 1995 年。他们使用的系统是 chroot,然后是 setuid,以及标准程序。

现在,在我之前的工作中,通常的政策是您永远不会以 root 身份运行任何进程。您为它创建一个用户/组并从那里运行。当然,系统确实以root身份运行了一些东西,但我们可以不以root身份完成所有业务逻辑处理。

现在对于 HTTP 守护进程,如果我不在应用程序中 chroot,我可以在没有 root 的情况下运行它。那么,应用程序永远不会以 root 身份运行不是更安全吗?

从一开始就以 mydaemon-user 身份运行它不是更安全吗?而不是从 root 启动它,chrooting,然后 setuid 到 mydaemon-user?

chroot daemon
  • 3 3 个回答
  • 2076 Views

3 个回答

  • Voted
  1. Best Answer
    JdeBP
    2018-06-02T06:14:54+08:002018-06-02T06:14:54+08:00

    似乎其他人错过了你的观点,这不是为什么要使用变根的原因,当然你已经清楚地知道了,也不是你可以做些什么来限制守护进程,当你也清楚地知道在非特权用户帐户;但是为什么要在应用程序内部做这些事情。实际上有一个相当恰当的例子来说明原因。

    考虑httpdDaniel J. Bernstein 的 publicfile 包中守护程序的设计。它所做的第一件事是将 root 更改为它被告知要与命令参数一起使用的根目录,然后将权限删除到在两个环境变量中传递的非特权用户 ID 和组 ID。

    Dæmon 管理工具集具有专用工具,用于更改根目录和删除非特权用户和组 ID。Gerrit Pape 的 runit 有chpst. 我的 nosh 工具集有chroot和setuidgid-fromenv. Laurent Bercot 的 s6 有s6-chroot和s6-setuidgid. 韦恩·马歇尔 (Wayne Marshall) 的 Perp 有runtool和runuid. 等等。事实上,他们都有 M. Bernstein 自己的 daemontools 工具集setuidgid作为先行词。

    人们会认为可以从httpd这些专用工具中提取功能并使用它们。然后,正如您所设想的,服务器程序的任何部分都不会以超级用户权限运行。

    问题是,一个直接后果是必须做更多的工作来设置更改的根,这会暴露出新的问题。

    就Bernstein而言httpd,根目录树中唯一的文件和目录是要发布到世界各地的文件和目录。树上什么都没有。此外,任何可执行程序映像文件都没有理由存在于该树中。

    但是将根目录更改为链式加载程序(或 systemd),然后突然将程序映像文件httpd,它加载的任何共享库,以及程序加载器或 C 运行时库访问的任何特殊文件/etc,/run以及/dev在程序初始化期间(如果您truss/strace是 C 或 C++ 程序,您可能会发现这非常令人惊讶),也必须存在于更改的根目录中。否则httpd无法链接到并且不会加载/运行。

    请记住,这是一个 HTTP(S) 内容服务器。它可能会在更改的根目录中提供任何(世界可读的)文件。这现在包括您的共享库、程序加载器以及操作系统的各种加载器/CRTL 配置文件的副本。如果某些(意外)意味着内容服务器有权写入内容,则受感染的服务器可能会获得对httpd自身程序映像的写入权限,甚至是您系统的程序加载器。(请记住,您现在有两组平行的/usr、/lib、/etc、/run和/dev目录来保证安全。)

    这些都不是httpd更改 root 并自行删除特权的情况。

    因此,您已经换取了少量特权代码,这些代码相当容易审计,并且在httpd程序开始时运行,以超级用户权限运行;因为在更改的根目录中具有极大扩展的文件和目录的攻击面。

    这就是为什么它不像在服务程序外部做所有事情那么简单。

    请注意,这仍然是其自身的最低限度的功能httpd。所有执行操作的代码,例如在操作系统的帐户数据库中查找用户 ID 和组 ID 以首先放入这些环境变量中,都是程序外部的httpd,在简单的独立可审计命令中,例如envuidgid. (当然,它是一个 UCSPI 工具,因此它不包含任何用于侦听相关 TCP 端口或接受连接的代码,这些代码是诸如tcpserver、tcp-socket-listen、tcp-socket-accept、s6-tcpserver4-socketbinder、等命令的域s6-tcpserver4d。)

    进一步阅读

    • 丹尼尔 J. 伯恩斯坦 (1996)。 httpd. 公共文件. cr.yp.to.
    • httpd. Daniel J. Bernstein 的软件合二为一。软件。乔纳森·德博因·波拉德。2016 年。
    • gopherd. Daniel J. Bernstein 的软件合二为一。软件。乔纳森·德博因·波拉德。2017 年。
    • https://unix.stackexchange.com/a/353698/5132
    • https://github.com/janmojzis/httpfile/blob/master/droproot.c
    • 29
  2. sourcejedi
    2018-06-02T04:56:48+08:002018-06-02T04:56:48+08:00

    我认为您问题的许多细节同样适用于avahi-daemon我最近看过的 。(我可能错过了另一个不同的细节)。在 chroot 中运行 avahi-daemon 有很多优点,以防 avahi-daemon 受到威胁。这些包括:

    1. 它无法读取任何用户的主目录并泄露私人信息。
    2. 它不能通过写入 /tmp 来利用其他程序中的错误。至少有一整类这样的错误。例如https://www.google.co.uk/search?q=tmp+race+security+bug
    3. 它无法打开 chroot 之外的任何 unix 套接字文件,其他守护进程可能正在侦听和读取消息。

    当您不使用 dbus 或类似设备时,第 3 点可能特别好……我认为 avahi-daemon 使用 dbus,因此即使从 chroot 内部也可以确保保持对系统 dbus 的访问。如果您不需要在系统 dbus 上发送消息的能力,那么拒绝该能力可能是一个很好的安全功能。

    使用 systemd 单元文件管理它

    请注意,如果 avahi-daemon 被重写,它可能会选择依赖 systemd 来保证安全性,并使用例如ProtectHome. 我建议对 avahi-daemon 进行更改,以将这些保护添加为额外的层,以及 chroot 无法保证的一些额外保护。您可以在此处查看我提出的完整选项列表:

    https://github.com/lathiat/avahi/pull/181/commits/67a7b10049c58d6afeebdc64ffd2023c5a93d49a

    如果 avahi-daemon不使用 chroot 本身,我可以使用更多限制,其中一些在提交消息中提到。我不确定这适用多少。

    请注意,我使用的保护措施不会限制守护进程打开 unix 套接字文件(上面的第 3 点)。

    另一种方法是使用 SELinux。但是,您可能会将您的应用程序绑定到该 Linux 发行版的子集。我在这里积极考虑 SELinux 的原因是 SELinux 以细粒度的方式限制了进程对 dbus 的访问。例如,我认为您可能经常期望它systemd不会出现在您需要能够向其发送消息的总线名称列表中:-)。

    “我想知道,如果使用 systemd 沙盒比 chroot/setuid/umask/ 更安全...”

    摘要:为什么不两者兼而有之?让我们对上面的内容进行一点解码:-)。

    如果您考虑第 3 点,使用 chroot 会提供更多限制。ProtectHome= 及其朋友甚至不尝试像 chroot 那样限制。(例如,没有一个命名的 systemd 选项黑名单/run,我们倾向于放置 unix 套接字文件)。

    chroot 表明限制文件系统访问可能非常强大,但并非Linux 上的所有内容都是文件 :-)。有一些 systemd 选项可以限制其他东西,而不是文件。如果程序受到攻击,这很有用,您可以减少它可用的内核功能,它可能会尝试利用其中的漏洞。例如 avahi-daemon 不需要蓝牙套接字,我猜您的 Web 服务器也不需要:-)。所以不要让它访问 AF_BLUETOOTH 地址系列。RestrictAddressFamilies=只需使用该选项将 AF_INET、AF_INET6 和 AF_UNIX 列入白名单。

    请阅读您使用的每个选项的文档。有些选项与其他选项结合使用会更有效,有些选项并非在所有 CPU 架构上都可用。(不是因为 CPU 不好,而是因为那个 CPU 的 Linux 端口设计得不太好。我认为)。

    (这里有一个一般原则。如果您可以编写您想要允许的列表,而不是您想要拒绝的列表,那么它会更安全。就像定义一个 chroot 为您提供了一个您可以访问的文件列表,这更健壮而不是说你想阻止/home)。

    原则上,您可以在 setuid() 之前自己应用所有相同的限制。这只是您可以从 systemd 复制的代码。但是,systemd 单元选项应该更容易编写,并且由于它们是标准格式,因此应该更易于阅读和查看。

    因此,我强烈建议您通读man systemd.exec目标平台上的沙盒部分。但是,如果您想要尽可能安全的设计,我也不会害怕在您的程序中chroot尝试(然后放弃root特权)。这里有一个权衡。使用对您的整体设计施加了一些限制。如果您已经有一个使用 chroot 的设计,并且它似乎可以满足您的需求,那听起来非常棒。chroot

    • 7
  3. Lucas Werkmeister
    2018-06-02T05:33:43+08:002018-06-02T05:33:43+08:00

    如果您可以依赖 systemd,那么将沙盒留给 systemd 确实更安全(也更简单!)。(当然,该应用程序还可以检测它是否已被 systemd 沙箱启动,如果它仍然是 root,则可以检测沙箱本身。)您描述的服务的等价物是:

    [Service]
    ExecStart=/usr/local/bin/mydaemon
    User=mydaemon-user
    RootDirectory=...
    

    但我们不必止步于此。systemd 还可以为你做很多其他的沙盒——这里有一些例子:

    [Service]
    # allocate separate /tmp and /var/tmp for the service
    PrivateTmp=yes
    # mount / (except for some subdirectories) read-only
    ProtectSystem=strict
    # empty /home, /root
    ProtectHome=yes
    # disable setuid and other privilege escalation mechanisms
    NoNewPrivileges=yes
    # separate network namespace with only loopback device
    PrivateNetwork=yes
    # only unix domain sockets (no inet, inet6, netlink, …)
    RestrictAddressFamilies=AF_UNIX
    

    有关man 5 systemd.exec更多指令和更详细的描述,请参阅。如果你让你的守护进程man 5 systemd.socket可以激活套接字(如果它是一个简单的服务器,只监听一些端口,不需要连接到其他服务器,这可能很有用。(在我看来,与文件系统相关的选项也可以使这些选项RootDirectory过时,所以也许您不需要再费心为所有必需的二进制文件和库设置一个新的根目录了。)

    较新的 systemd 版本(自 v232 起)也支持DynamicUser=yes,其中 systemd 将自动为您分配服务用户,仅用于服务运行时。这意味着您不必为该服务注册永久用户,并且只要该服务不写入除其StateDirectory、LogsDirectory和之外的任何文件系统位置CacheDirectory(您也可以在单元文件中声明),它就可以正常工作 -再看man 5 systemd.exec一次——然后由哪个 systemd 管理,注意正确地将它们分配给动态用户)。

    • 1

相关问题

  • 可以 ping 8.8.8.8 但无法访问互联网 - Manjaro linux

  • chroot 一个用户到不同位置的多个目录

  • Systemctl 从失败列表中删除单元

  • 如何以编程方式将语言环境添加到 chrooted 系统?

  • Steam 库文件夹必须位于可执行文件系统上

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve