应用启动后成为root用户

时间:2017-07-13 22:25:42

标签: node.js ubuntu macos-sierra

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

我对使用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),但先运行所有用户权限

2 个答案:

答案 0 :(得分:2)

您基本上想要将节点进程的uid更改为0,即root的id。这是使用节点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
  4. 示例:

    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

答案 1 :(得分:0)

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

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

如果你想要做的只是在端口80上运行,那么这就是我的建议。

如果您需要其他内容的权限,您可能应该让您的服务器运行的用户具有这些权限。 (对目录等的写访问权限)以root身份运行通常很糟糕。