Hi everybody!

Most of files in my Drupal installation should be public, but several ones must be private and managed by some module to grant access.
I managed to configure Drupal, so that it meets my requirements. In a nutshell, my current configuration is as follows:

1. Default file system: public
2. nginx:
location ^~ /sites/default/files/private/ {
internal;
}
3. Private files download permission module is installed and manages access rules.

Well, now I can insert links like "/system/files/..." and they will work (depending on permissions rules). But I'd like for full URLs (/sites/default/files/private/...) to work too. In this case, I could easily insert links via CKEditor and IMCE, using "Link"->"Browser server" feature. Is it possible to build a secure configuration that meets my requirements?

To be more specific, I have the solution that seems to work as expected, but I am afraid for the security.
Is it enough to use the following nginx config instead of the above one?

location ^~ /sites/default/files/private/ {
rewrite ^/sites/default/files/private/(.*) /system/files/$1 last;
}

Thanks,
Alexander

Comments

John_B’s picture

I am a bit lost because it is basic to the Drupal private file system that the files have no public URL; having files which are private, with access control handled by Drupal, AND giving them a predictable public URL, is pretty much impossible.

Digit Professionals specialising in Drupal, WordPress & CiviCRM support for publishers in non-profit and related sectors

Chewits’s picture

In my understanding this nginx config:

location ^~ /sites/default/files/private/ {
rewrite ^/sites/default/files/private/(.*) /system/files/$1 last;
}

redirects internally all requests like http://example.com/sites/default/files/private/.../... to http://example.com/system/files/.../... and Drupal handles them as expected. So the path "/sites/default/files/private/.../..." has newer actually worked, it's only like a proxy path; the actual path is "/system/files/.../...".
The URL for the end-user is still http://example.com/sites/default/files/private/.../... (in address bar). So this seems to work fine. The only issue that I have not found such configuration recommendation for nginx on the Internet.

Isn't this post about the same method, but for Apache?

John_B’s picture

That post relates to problem of being able to use some private files on a Drupal site where the file system is set to default to public. Using that system, for the private files the user would still not see the path to files/private in the file path, even though the real path where the file is located is a sub-folder of files/.

Since it is possible in Drupal 7 to specify whether a particular file field uses public or private when setting up a file field, the problem of using mixed public and private file systems is now less likely to need the workaround suggested in the post you linked, which was written with earlier versions of Drupal in mind.

Thus, a standard nginx rewrite is all that is needed to implement that post's suggestion. Using that system, the private file path will still always be hidden from the website visitor, regardless of whether it is inside or outside document root.

Digit Professionals specialising in Drupal, WordPress & CiviCRM support for publishers in non-profit and related sectors

Chewits’s picture

That post relates to problem of being able to use some private files on a Drupal site where the file system is set to default to public.

This is exactly what I need.

Since it is possible in Drupal 7 to specify whether a particular file field uses public or private when setting up a file field, the problem of using mixed public and private file systems is now less likely to need the workaround suggested in the post you linked, which was written with earlier versions of Drupal in mind.

Oh, I haven't mentioned that my private files are not related to file fields, i.e. they are "unmanaged" files. There are no entries in "file_managed" table and they are uploaded by, e.g. FTP.

Thus, a standard nginx rewrite is all that is needed to implement that post's suggestion. Using that system, the private file path will still always be hidden from the website visitor, regardless of whether it is inside or outside document root.

Thanks! I hope my solution is a "standard nginx rewrite".. :)