【问题标题】:Node Express Unix Domain Socket PermissionsNode Express Unix 域套接字权限
【发布时间】:2014-02-16 01:07:11
【问题描述】:

我正在运行一个 nginx 服务器和一个 node express web 服务器,使用 daemontools,设置为通过 Unix 域套接字进行通信。有几个问题:

  1. socket 文件在关机时仍然存在,所以我必须在重新启动服务器时将其删除,否则我会收到 EADDRINUSE 错误。
  2. nginx服务器以nginx用户运行,node服务器以node用户运行。
  3. 在服务器启动时 Express 会创建套接字文件,并且 umask 将套接字文件的权限设置为 755。
  4. setuidgid 应用程序将组设置为用户的默认组,在这种情况下都是节点用户名。
  5. 应用程序的部署脚本和 daemontools 的运行脚本在节点服务器实例启动之前执行,因此无法设置文件的权限,因为它必须在启动过程中重新创建。

如果我 chgrp 和 chmod g+w 套接字文件,一切正常。有没有办法进行设置,以便生成具有正确权限的节点应用程序的套接字文件,以便 nginx 能够写入它而不损害一个应用程序或另一个应用程序的安全独立性?我什至可以将 nginx 添加到节点用户的组中,如果还有一种方法可以设置套接字文件的权限以便它是组可写的。

【问题讨论】:

  • 我也很想知道一种干净的方法来做到这一点。我最终放弃并重新使用 TCP。

标签: node.js nginx express file-permissions unix-socket


【解决方案1】:

我不知道它是否仍然相关,但我成功连接到 unix 套接字作为节点客户端(服务器在 c 中)。

对于运行节点的用户,我只是简单地触摸了一个新文件 s.sock,当我的服务器启动时,它会监听这个 unix 套接字。

我的问题是我尝试以 sudo 运行我的服务器,然后它将套接字更改为 root 权限。

无论如何,对我有用的只是在没有 root 权限的情况下运行服务器,然后尝试从我没有得到的节点连接到它。

错误:连接 EACCES

希望对你有帮助。

【讨论】:

    【解决方案2】:

    @Bobby 的回答让我在 nginx 中留下了 connect() to unix:/run/static0.sock failed (13: Permission denied)。 Chmod 777 是诀窍。这是我的解决方案 [建立在他的基础上]:

    var fs = require('fs');
    var http = require('http');
    var process = require('process');
    var express = require('express')
    var app = express()
    
    app.get('/', function (req, res) {
      res.send('Hello World!')
    })
    
    var sock = process.argv[2];
    
    fs.stat(sock, function(err) {
      if (!err) { fs.unlinkSync(sock); }
      http.createServer(app).listen(sock, function(){
        fs.chmodSync(sock, '777');
        console.log('Express server listening on ' + sock);
      });
    });
    

    运行方式:

    $ node server.js /run/static0.sock
    Express server listening on /run/static0.sock
    

    【讨论】:

    • 我推荐@Patxitron 的回答。您遇到的问题可能是套接字不属于同一用户/组。 777 perms 将使您机器上的任何进程都可以写入套接字,这可能是一个相当大的安全问题,而这正是我一开始就试图避免的。
    【解决方案3】:

    也许我来得太晚了。

    作为您自己答案的补充,有一个解决方案不必将 nginx 用户添加到节点组。

    仅为套接字文件创建一个目录,将其分配给节点用户和 www-data(或 nginx 所属的任何组)组,并在该目录上设置 group-id 位(SGID)。

    mkdir -p /var/lib/yourapp/socket
    chown nodeuser:nginxgroup /var/lib/yourapp/socket
    chmod g+rxs /var/lib/yourapp/socket
    

    在此目录中创建的所有文件将自动归 nginxgroup 组所有。

    【讨论】:

    • 完美,这是一个更优雅的解决方案。谢谢!
    • 这几乎是完美的,但我不知道为什么,但我不能在 g+w 上为套接字进行继承......有什么想法吗?
    • 新文件的写入权限不会继承其父文件夹的权限。它们必须在文件创建时或之后使用 chmod 命令设置(请参阅 karma0 答案中的示例代码)。
    • 新文件的权限受umask的影响,例如如果您的节点应用程序是由在systemd 下运行的pm2 启动的,您可以将UMask=0002 添加到服务定义中。
    【解决方案4】:

    我能够通过将 nginx 添加到节点用户的主要组来使其工作:

    gpasswd -a nginx node
    

    然后使用以下命令启动 express 服务器:

    // Create the server
    fs.stat(listen, function(err) {
      if (!err) { fs.unlinkSync(sock); }
      http.createServer(app).listen(sock, function(){
        fs.chmodSync(sock, '775');
        console.log('Express server listening on ' + listen);
      });
    });
    

    我真的不觉得这是一个有效的解决方案,只是一个 hack。 Express 的构建并没有考虑到删除和设置文件权限,尤其是让我不得不将 nginx 用户添加到节点用户的主要组中。如果 nginx 帐户遭到入侵,可以想象,攻击者可以访问所有应用程序的源代码,并且可以尝试使用套接字对代码进行无休止的攻击。我能做的最好的事情是将节点用户的 umask 设置为 077,并尝试在每个文件上使用 chmod 600 并在每个目录上使用 chmod 700 来获得 100% 的覆盖率,或者将组设置为用户的非默认值一切。

    也就是说,我仍然会很感激任何想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 2015-07-20
      相关资源
      最近更新 更多