Linux - client_body_in_file_only - 如何设置临时文件的文件权限?

Linux - client_body_in_file_only - how to set file permissions for the temp file?

我们使用 nginx 的 client_body_in_file_only 选项,允许通过 Ajax 上传文件。配置如下所示:

location ~ ^(\/path1|\path2)$ {

  limit_except POST { deny all; }
  client_body_temp_path      /path/to/app/tmp;
  client_body_in_file_only   on;
  client_body_buffer_size    128K;
  client_max_body_size       1000M;

  #this option is a quick hack to make sure files get saved on (ie this type of request goes to) on a specific server
  proxy_pass                 http://admin;
  proxy_pass_request_headers on;
  proxy_set_header           X-FILE $request_body_file;
  proxy_set_body             off;
  proxy_redirect             off;

  # might not need?
  proxy_read_timeout         3m;
}

这可行,但处理请求的 Web 服务器进程 (Mongrel) 必须先 sudo headers['X-FILE'] 中通过的临时文件,然后才能对其执行任何操作。这是因为临时文件带有 600 权限。

我对这种方法不满意,它需要我们编辑 /etc/sudoers 文件以允许 Web 服务器用户在没有密码的情况下执行 sudo chmod。感觉很没有安全感。

有没有办法通过 nginx 配置更改创建的临时文件的权限,例如更改为 775?

编辑:我只是尝试更改 nginx init 配置中 umask 选项的值,然后重新启动 nginx,但没有帮助。原来是0022,我改成了0002。在这两种情况下,它都具有 600 个权限。

EDIT2:我还尝试在 nginx 配置中的 proxy_redirect 行下添加这一行。

proxy_store_access user:rw group:rw all:r;

但是,它没有任何区别 - 它仍然只有 user:rw

目前似乎无法配置文件权限,但是有一个official feature request

The file permissions are always 0600 making the application unable to read the file at all. [...] This is currently an unsupported scenario: [Nginx] creates the temporary file with the default permissions [...] 0600 (unless request_body_file_group_access is set - but unfortunately that property is not settable).

工单于 2018 年 10 月开放,次要优先级。

查看 nginx 来源,似乎唯一可以修改临时文件权限的机制是请求的 request_body_file_group_access 属性,在ngx_http_write_request_body():

if (r->request_body_file_group_access) {
    tf->access = 0660;
}

但即使这样也将您限制在 0660 并且它似乎不是用户可设置的 属性,仅由 ngx_http_dav 模块使用。

权限最终在 ngx_open_tempfile() 中设置,默认设置为 0600:

fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR, access ? access : 0600);

所以目前好像还没有基于配置的方案。如果您 willing/able 从源代码构建 nginx,一种可能性是应用一个简单的补丁来将权限设置为您在 ngx_http_write_request_body():

中想要的任何内容
+    tf->access = 0644;
+
     if (r->request_body_file_group_access) {
         tf->access = 0660;
     }

     rb->temp_file = tf;

我对此进行了测试并获得以下信息,第一个文件未经修改上传,第二个文件经过修改:

$ ls -al /tmp/upload/
total 984
drwxr-xr-x  2 nobody root     12288 Feb 18 13:42 .
drwxrwxrwt 16 root   root     12288 Feb 18 14:24 ..
-rw-------  1 nobody nogroup 490667 Feb 18 13:40 0000000001
-rw-r--r--  1 nobody nogroup 490667 Feb 18 13:42 0063184684