omega8cc / boa

Barracuda Octopus Aegir 5.4.0
https://omega8.cc/compare
394 stars 75 forks source link

Private files #1360

Open timlie opened 5 years ago

timlie commented 5 years ago

Hi,

I wanted to set the private file system as default in a pressflow 6.47 installation. After changing the:

allow_private_file_downloads

to TRUE in the ini file.

I can choose for PRIVATE and this works. Only, the path to the files system path keeps:

sites/sitename/files

I cannot change it to:

sites/sitename/private/files

The temp directory is:

sites/sitename/private/temp

Is this normal behaviour?

Thanks

pricejn2 commented 5 years ago

File paths are hardcoded in settings.php. local.settings.php can be used to override filedirectory variables.

omega8cc commented 5 years ago

There’s no point in overriding default paths. Files don’t have to be moved anywhere to make them private. It’s handled automatically on the global.inc level and managed by INI variable and corresponding Nginx configuration. It’s automated and forces requests to go via Drupal instead of directly, which makes the actual file system paths irrelevant.

timlie commented 5 years ago

There’s no point in overriding default paths. Files don’t have to be moved anywhere to make them private. It’s handled automatically on the global.inc level and managed by INI variable and corresponding Nginx configuration. It’s automated and forces requests to go via Drupal instead of directly, which makes the actual file system paths irrelevant.

I indeed thought it worked like that. When accessing a file from within Drupal the file path is now: https://site.com/system/files/file.jpg which is correct and from outside Drupal this file is not accessible from this link, but still the file is accesible from: https://site.com/sites/site.com/files/file.jpg

The .htaccess only includes this: https://gist.github.com/timlie/db9dc293d96060e9d7d82a99e01fab1f

Thanks for the replys.

omega8cc commented 5 years ago

Hmm.. it shouldn’t work like that.. but .htaccess is not used with Nginx anyway. We should investigate further.

omega8cc commented 5 years ago

Since it's possible to use mixed public/private mode in Drupal for years, there are separate variables defining paths to public and private files directories. Like this:

Drupal 7
  $conf['file_public_path'] = 'sites/<?php print $this->uri ?>/files';
  $conf['file_private_path'] = 'sites/<?php print $this->uri ?>/private/files';
Drupal 9
  $settings['file_public_path'] = 'sites/<?php print $this->uri ?>/files';
  $settings['file_private_path'] = 'sites/<?php print $this->uri ?>/private/files';

But once you enable the possibility to use private files with allow_private_file_downloads switch, it doesn't mean that previously public files become private, because private files have their dedicated subdirectory.

Modules utilising this dual system should follow Drupal API and use file_public_path and/or file_private_path respectively.

BOA/Aegir has Nginx configuration which automatically protects the private files subdirectory, even if you don't enable private files mode in Drupal. That is also why Aegir leverages this protection to always hide temporary files from public access, hence:

$conf['file_directory_temp'] = 'sites/<?php print $this->uri ?>/private/temp';

For any custom or legacy configurations you may have to extend custom configuration or simply force file_public_path to use file_private_path in the local.settings.php to enjoy built-in protection on the Nginx level, which automatically sends these requests to Drupal for processing. But then you probably need to add some extra rewrites to handle legacy URIs too, so /files/foo.pdf is redirected to private. Example from default configuration:

###
### Private downloads are always sent to the drupal backend.
### Note: this location doesn't work with X-Accel-Redirect.
###
location ~* ^/sites/.*/files/private/ {
  if ( $is_bot ) {
    return 403;
  }
  access_log off;
  rewrite    ^/sites/.*/files/private/(.*)$ $scheme://$host/system/files/private/$1 permanent;
  set $nocache_details "Skip";
  try_files  $uri @drupal;
}
timlie commented 5 years ago

Thanks for this documentation. How about Drupal 6 - Pressflow? Can these variables:

$conf['file_public_path'] = 'sites/<?php print $this->uri ?>/files';

also be used in the local.settings.php? As per documentation for Drupal these variables where not defined yet in Drupal 6.

omega8cc commented 5 years ago

These variables will not work for Drupal 6, because in Drupal 6 there was no concept of separate variable to define private files path, just single:

$conf['file_directory_path'] = 'sites/<?php print $this->uri ?>/files';

That said, while you can't define the path for private files globally in D6, you can still leverage the built-in protection and put the files you want keep private in sites/sitename/files/private so it would be still covered by our Nginx configuration:

###
### Private downloads are always sent to the drupal backend.
### Note: this location doesn't work with X-Accel-Redirect.
###
location ~* ^/sites/.*/files/private/ {
  if ( $is_bot ) {
    return 403;
  }
  access_log off;
  rewrite    ^/sites/.*/files/private/(.*)$ $scheme://$host/system/files/private/$1 permanent;
  set $nocache_details "Skip";
  try_files  $uri @drupal;
}

###
### Deny direct access to private downloads in sites/domain/private.
### Note: this location works with X-Accel-Redirect.
###
location ~* ^/sites/.*/private/ {
  internal;
<?php if ($nginx_config_mode == 'extended'): ?>
  if ( $is_bot ) {
    return 403;
  }
<?php endif; ?>
  access_log off;
}

###
### Deny direct access to private downloads also for short, rewritten URLs.
### Note: this location works with X-Accel-Redirect.
###
location ~* /files/private/ {
  internal;
  if ( $is_bot ) {
    return 403;
  }
  access_log off;
}
timlie commented 5 years ago

Allright, thanks.

Changed the:

$conf['file_directory_path'] to

$conf['file_directory_path'] = 'sites/<?php print $this->uri ?>/private/files';

When now trying to access the files through the full url:

https://site.com/sites/site.com/private/files/file.jpg

I get a 404. This is not the 403 like described above but files are not shown to anonymous users anymore. Thanks!

omega8cc commented 5 years ago

You would get 403 if you would use files/private not private/files

omega8cc commented 5 years ago

Ah, scratch that.. the 403 is for bots only :-)