应用启动后成为root

Become root after app starts

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

我对我的应用程序使用 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 的权限,以便它可以 运行 server.listen(80) 具有 root 权限,但是运行 一切优先于用户权限。

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

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

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

如果您需要对其他事情的权限,您可能应该让您的服务器的用户 运行ning 拥有对这些事情的权限。 (对目录的写入权限等)运行 作为 root 通常是不好的。

您实际上是想将节点进程的 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.