Recently two experienced Drupal developers, working separately, both looked for clear instructions on the process of setting up a private file system in a Drupal 7 installation. One of them, Mike Gifford (mgifford), believes he found the best answer. On his blog, Mike posted a description of the problem and his approach for solving it.

We need two things to happen:

  1. If you are familiar with setting up private file systems, and especially if you know the traps to avoid in setting up a private file system, review Mike's way of doing it. If he's doing anything risky or wrong, let him know.
  2. Once we've identified a reasonable way, and hopefully the best way, to set up private file systems in Drupal 7, we will need to add that information to the Drupal documentation. It looks like the best place to add these instructions would be on Working with files in Drupal 7, specifically under the heading, "Managing file locations and access."

Once we've had a technical review of Mike's approach to setting up private files, I would be happy to take on the task of refining the instructions and adding them to the handbook.

Comments

mgifford’s picture

Thanks for posting this Cliff!

Cliff’s picture

Can anyone give Mike access to this section of the documentation so he can add the instructions he has worked out?

arianek’s picture

you'll need to post the suggested edits/additions into an issue for a docs admin to review and update the page (unless he's planning to work actively on docs in a more permanent fashion, in which case, he should file an issue to apply for docs admin role, and then we can review his application).

mgifford’s picture

Right now it says:

Managing file locations and access

When you create a file field, you can specify the subdirectory of the site's file system where uploaded files for this content type will be stored. The site's file system paths are defined on the File system page (Administer > Configuration > Media: File system).

You can also specify whether files are stored in a public directory or in a private file storage area. Files in the public directory can be accessed directly through the web server; when public files are listed, direct links to the files are used and anyone who knows a file's URL can download the file. Files in the private directory are not accessible directly through the web server; when private files are listed, the links are Drupal path requests. This adds to server load and download time, since Drupal must resolve the path for each file download request, but allows for access restrictions.

It probably should say something more like:

Managing file locations and access

When you create a file field, you can specify the subdirectory of the site's file system where uploaded files for this content type will be stored. The site's file system paths are defined on the File system page (Administer > Configuration > Media: File system).

You can also specify whether files are stored in a public directory or in a private file storage area. Files in the public directory can be accessed directly through the web server; when public files are listed, direct links to the files are used and anyone who knows a file's URL can download the file. Files in the private directory are not accessible directly through the web server; when private files are listed, the links are Drupal path requests. This adds to server load and download time, since Drupal must resolve the path for each file download request, but allows for access restrictions.

The best practice for public files is to store them in the multi-site directory like /DRUPAL/sites/example.com/files, but there are many ways to create a private directory. The easiest way to securely add a a private directory for your files is simply to create a sub-directory under files and add a .htaccess file simply with the text Deny from all in it. This stops Apache from serving files from this directory.

arianek’s picture

Status: Active » Needs review

thanks mgifford - i ran this by chx and he likes the info. he's suggested we add at the end:

"Another approach is to create a directory outside of the Apache document root. For example, if your Apache document root is public_html/example.com then create public_html/example.com-files."

sound good? +1 then i'll go update the page.

arianek’s picture

Assigned: Cliff » arianek
arianek’s picture

chx also says:

http://img11.imageshack.us/img11/5143/screenshot049r.png "For these domains, creating a /files directory and one directory under it for each domain is a viable strategy." this is cpanel which is like 99% of the shared hosts.

mgifford’s picture

I thought about simply suggesting a directory outside of the public folder, but I wanted a system that would work easily with existing backup strategies. There's a greater risk of files not being backed up if they are sitting outside of the root directory.

We do use multi-sites extensively (which is pretty common in the Drupal community) and so having something that would keep client content together seemed like a clean approach.

I'm glad that chx had a chance to review it.

jensimmons’s picture

Yeah:
The text in Drupal itself let's me know I need to do something special:

A local file system path where private files will be stored. This directory must exist and be writable by Drupal. This directory should not be accessible over the web.

But it leaves me hanging. I don't know what to do next. I found http://drupal.org/documentation/modules/file through a google search (a link inside Drupal's help text owuld be much better.) But that page is long and has a ton of text, and nothing says "Setting Up Private Files". There should be a section that I can just scroll down to. Most of what's on that page just tells me stuff I don't need to know / that's already fine. I get what private files are, but how do I set them up? Does it have to be on another server? Can it be inside the Drupal directory on the same server as my website? Do I use permissions to restrict the directory as private? How important is security? Is there more than one way to do it? What does "accessible over the web" mean? I could point to my local laptop and then close it. That's not accessible to the web — but of course the files have to be accessible to the web!! Drupal has to get to them...

The text in comment 4 is better. There are bits of helpful information in there, but that's still not enough.

The easiest way to securely add a a private directory for your files is simply to create a sub-directory under files and add a .htaccess file simply with the text Deny from all in it. This stops Apache from serving files from this directory.

I suggest expanding that into a paragraph, with a specific example, step-by-step of one way to do it. People who are lost can just follow that one example precisely. People who understand server config better can do something more advanced if they want to.

arianek’s picture

Assigned: arianek » Unassigned

can someone post an updated version of this that we can move to the docs page?

DocuAnt’s picture

Take a look at the discussion: http://drupal.org/documentation/modules/file, please.
It looks like also some words for user pictures are needed.

Thanks
DocuAnt

arianek’s picture

@docuant - would you mind filing a new issue with some more detail on what's needed on the file module page? thanks!

DocuAnt’s picture

@arianek - after further investigations it looks to me, that there is a general problem protecting user pictures in D7 that could not be solved by better documentation. Therefore I opened: #1061312: User pictures are always accessible.

mgifford’s picture

I don't have access to edit the page, but the basic changes can be done without too much hassle to at least improve the description.

Certainly it would be useful to make sure that we've got the best docs possible, but I'd also like to see this fixed as soon as possible. A quick view of the comments on the page shows how important this really is.

arianek’s picture

Waiting for someone to merge your (mgifford) and jensimmons' work together into something that can be added to the page by an admin. If you need docs admin role yourself, as I said above, just file an issue for it so we can take a moment to do a review + assign.

mgifford’s picture

@jensimmons, tell me if I'm wrong, but your main point is in the last paragraph:

I suggest expanding that into a paragraph, with a specific example, step-by-step of one way to do it. People who are lost can just follow that one example precisely. People who understand server config better can do something more advanced if they want to

We could open up a new issue with a patch to enhance the help text in Drupal itself, but let's get the fuller explanation set up first and then enhance it from there. There's really no reason I can see for this to have waited 2 months to get implemented in the docs.

I suggested this in #4 for this section:

When you create a file field, you can specify the subdirectory of the site's file system where uploaded files for this content type will be stored. The site's file system paths are defined on the File system page (Administer > Configuration > Media: File system).

You can also specify whether files are stored in a public directory or in a private file storage area. Files in the public directory can be accessed directly through the web server; when public files are listed, direct links to the files are used and anyone who knows a file's URL can download the file. Files in the private directory are not accessible directly through the web server; when private files are listed, the links are Drupal path requests. This adds to server load and download time, since Drupal must resolve the path for each file download request, but allows for access restrictions.

The best practice for public files is to store them in the multi-site directory like /DRUPAL/sites/example.com/files, but there are many ways to create a private directory. The easiest way to securely add a a private directory for your files is simply to create a sub-directory under files and add a .htaccess file simply with the text Deny from all in it. This stops Apache from serving files from this directory.

Perhaps the last paragraph should be something like:

The best practice for public files is to store them in the multi-site directory like
/DRUPAL/sites/example.com/files

The easiest way to securely add a a private directory for your files is simply to create a sub-directory under this directory like
/DRUPAL/sites/example.com/files/private

and then add a simple .htaccess file with the text:
Deny from all

This stops Apache from serving files from this directory. Make sure that you test this by adding file to that directory and verifying that you can't browse their directly.

I don't much care about exactly how it is worded, but something more needs to be inserted there and I don't think that there is any disagreement about the need for clarification of this point.

mgifford’s picture

Assigned: Unassigned » mgifford
Status: Needs review » Closed (fixed)

I think I got this right. I found out in the doc sprint that indeed you don't need to manually go in and create the subdirectory or add the .htaccess file. Drupal does that for you, but we did need to state that clearly. Might want to have that actually documented in the interface in D8.

arianek’s picture

Status: Closed (fixed) » Fixed

Was just going to check if this got completed, thanks for the work Mike!

mgifford’s picture

good.. was fun to do this as part of the doc sprint.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

katkut’s picture

Hi,

I created a private directory as a sub-folder under file (i.e. sites/default/files/private) and I can see that Drupal automatically created the .htaccess file with the following content:

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
Deny from all
Options None
Options +FollowSymLinks

However when I run my status report, it still shows that my Private File Directory is not set. Has anybody encountered similar issues? Any help will be appreciated.

Cheers,
katkut

CatsFromStonehenge’s picture

Issue summary: View changes

OK, this is a very old thread, however, if anyone is having problems creating a private file area, remember to clear the cache after doing all the settings.