【问题标题】:Become root after app starts应用启动后成为root
【发布时间】:2017-07-13 22:25:41
【问题描述】:

有时,用户会在我的 Node 应用程序中启动需要升级管理员或 root 权限的操作。我不想让用户使用sudo 运行应用程序,而是提示用户输入密码并升级已经运行的 Node 进程的权限。

我对我的应用程序使用sudo 执行子进程不感兴趣(sudo-prompt 已经可以)。我希望节点进程本身在没有sudo 的非root 用户启动后获得root 权限。

显示问题行为的应用示例:

var process = require('process');
var http = require('http');
var server = http.createServer(...);
// Several steps here that are unsafe to run as root
promptUserForAdminPassword();
server.listen(80); // Fails, needs to be root

我想编写函数promptUserForAdminPassword(),它会提示用户输入密码,提升Node的权限,以便它可以以root权限运行server.listen(80),但以用户权限运行之前的所有内容。

【问题讨论】:

  • 这实际上是对您对加布里埃尔回答的评论的回复,但我认为它属于这里更好。我们在这里最擅长的是了解整体问题并提出解决方案,我们经常找到比 OP 想到或询问的任何解决方案都要好得多的解决方案。您只要求一个似乎没有人回答的特定解决方案,并且您没有描述您实际的整体问题范围,因此我们无法提供其他解决方案。你在这里给社区造成了障碍并成功了,所以如果你的具体要求不存在,我们可能无法提供帮助。
  • 另外,你在什么平台上运行。 WIndows 与 *nix 上的权限内容通常不同。
  • @jfriend00 我不同意。 Stack Overflow 不适用于整体解决方案建议,存在 Too Broad close 原因及其随附的描述就证明了这一点。我很乐意在聊天中进一步讨论什么是关于 SO 的好问题。
  • 顺便说一句 - 对这个问题缺乏答案本身就是一种答案,而且这些信息很有用。一个明确的答案,“因为 XYZ,你所问的问题是不可能的”,这会更好,因为其他试图实现类似东西的人可能会缩短他们的研究并改变他们的设计。
  • Too Broad 是指有人提出的问题过于宽泛,根本不具体。当有些人描述了他们面临的整体问题,然后展示了他们尝试过的解决方案以及他们陷入困境的地方时,它永远不会适用。这完美地定义了他们试图解决的具体问题(在足够高的层次上包括整体背景),展示了他们尝试了什么以及他们卡在哪里,然后允许其他人为他们提供他们甚至不知道的解决方案。祝你的问题好运,因为这里似乎没有什么可做的。

标签: node.js ubuntu macos-sierra


【解决方案1】:

您实际上是想将节点进程的uid 更改为 0,即 root 的 id。这是使用 Node 的process.setuid(0) 完成的,但只有root 或使用sudo 运行的进程才能通过该调用成功,所以这是不可能的。

具有非特权用户uid 的进程无法将其uid 更改为0。

替代方案

启动另一个进程

// Prompts user for password in terminal running Node process
child_process.spawn('sudo', ['node', 'serverlistener.js']);

// Prompts user for password using UI element
child_process.spawn('gksudo', ['node', 'serverlistener.js']);

This 问题为 macOS 上缺少的gksudo 提供了一些选项。

有效用户 ID

如果可以使用sudo 启动应用程序,您可以通过以下方式减少root 的暴露:

  1. 以 root 身份启动
  2. 立即将effective user id 更改为更安全的用户
  3. 稍后根据需要将有效用户改回 root

例子:

var userid = require('userid');
var sudoUserId = userid.uid(process.env.SUDO_USER);
process.seteuid(sudoUserId);
// Do things
process.seteuid(0);
server.listen(80);

使用userid module

【讨论】:

    【解决方案2】:

    通常您想要做的是以 root 身份启动您的服务器,然后删除权限,而不是相反。

    https://thomashunter.name/blog/drop-root-privileges-in-node-js/

    如果您只想在端口 80 上运行,那么我建议您这样做。

    如果您需要其他事情的权限,您可能应该让您的服务器正在运行的用户拥有这些事情的权限。 (对目录等的写入权限)以 root 身份运行通常很糟糕。

    【讨论】:

    • 事情是 99% 的时间应用程序运行这个特权功能没有被利用。在这种情况下,以 root 身份启动应用程序不是一个选项,这就是为什么我像以前那样提出问题的原因。 在非root用户启动应用程序后,我需要将用户切换到root。
    • @CoryKlein - 为什么以 root 身份运行应用程序不是一个选项。我同意 Gabriel 的观点,这样做的常识是让用户在运行服务器之前启动服务器以获取适当的权限。如果您希望您的服务器在他们以不足的权限启动它时告诉他们需要哪些权限,您可以为用户添加该帮助。
    • 仅供参考,有多种方法可以在端口 80 上运行而无需以 root 身份运行。我有一个在 8080 上运行的节点服务器,并且端口 80 已在操作系统配置文件中转发到 8080,因此外部世界连接到端口 80,操作系统端口将其转发到我在 8080 上的服务器,我不必运行我的具有提升权限的服务器,而它似乎正在为端口 80 提供服务。
    • @jfriend00 这不是一个选项,因为在使用sudo 权限之前遇到了 100 个不同的必要代码路径。其中包括在文件系统的不同位置创建文件。使用sudo 运行应用程序会在前面的所有步骤中引入风险。此外,这个问题不是关于“如何解决 Cory Klein 的”根本问题,而是“如何在节点启动后提升权限”。如果答案是“对不起,你不能”,那么 that 就是答案。 “你可以用不同的方式解决你的问题”形式的答案不是我想要的。
    猜你喜欢
    • 2013-05-12
    • 2011-05-18
    • 2019-10-09
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多