We use the client_body_in_file_only option with nginx, to allow file upload via Ajax. The config looks like this:
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;
}
This works, but the web server process (Mongrel) that handles the request has to sudo
the temp file that comes through in headers['X-FILE']
, before it can do anything with it. This is because the temp file comes through with 600
permissions.
I'm not happy with this approach, which requires us to edit the /etc/sudoers
file to allow the web server user to do sudo chmod
without a password. It feels very unsecure.
Is there a way, with the nginx config, to change the permissions on the temp file that is created, eg to 775?
EDIT: I just tried changing the value of the umask
option in the nginx init config, then restarting nginx, but it didn't help. It had been at 0022
, I changed it to 0002
. In both cases it comes through with 600 permissions.
EDIT2: I also tried adding this line under the proxy_redirect
line, in the nginx config.
proxy_store_access user:rw group:rw all:r;
But, it didn't make any difference - it still just has user:rw
Looking through the nginx
source, it appears that the only mechanism that would modify the permissions of the temporary file is the request_body_file_group_access
property of the request, which is consulted in ngx_http_write_request_body()
:
if (r->request_body_file_group_access) {
tf->access = 0660;
}
But even that limits you to 0660
and it seems that it is not a user-settable property, only being utilized by the ngx_http_dav
module.
The permissions are ultimately set in ngx_open_tempfile()
, where they default to 0600
:
fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR, access ? access : 0600);
So it seems that there is currently no configuration-based solution. If you're willing/able to build nginx
from source, one possibility is to apply a simple patch to set the permissions to whatever you want in ngx_http_write_request_body()
:
+ tf->access = 0644;
+
if (r->request_body_file_group_access) {
tf->access = 0660;
}
rb->temp_file = tf;
I tested this and obtained the following, the first file having been uploaded without the modification, and the second file with it:
$ 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
It seems, that it is not possible at the moment to configure the file permissions, but there is an 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).
The ticket was opened in October 2018 with minor priority.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With