Bug in nginx helper?

Just found this in my logs:

2013/08/07 09:21:14 [error] 312193#0: *21919 FastCGI sent in stderr: "PHP message: PHP Warning: opendir(): open_basedir restriction in effect. File(/var/run/nginx-cache) is not within the allowed path(s): (/var/www/clients/client2/web8/web:/var/www/clients/client2/web8/private:/var/www/clients/client2/web8/tmp:/var/www/foodandchatter.co.za/web:/srv/www/foodandchatter.co.za/web:/usr/share/php5:/usr/share/php:/tmp:/usr/share/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin:/usr/share/php:/var/cache/nginx) in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 684

My nginx is configured to cache here: => fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:500m inactive=60m;

So how come this plugin tries to delete the cache in here: /var/run/nginx-cache ?

First, it looks like you are using ISPConfig or have open_basedir restriction on.

For Nginx-helper and /var/run/nginx-cache please refer to - http://rtcamp.com/nginx-helper/faq/

You still need to add nginx-cache path to open_basedir list or move cache dir inside open_basedir directories.

THX for the pointer to the FAQ. I have edited that define properly to point to /var/cache/nginx - the same location I configured in my nginx.conf and of course added the path /var/cache/nginx globally via a template to all vhists but if I now initiate a purge I get this error:

PHP message: PHP Warning:  unlink(/var/cache/nginx/b): Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 692  
PHP message: PHP Warning:  opendir(/var/cache/nginx/b): fai

It simply looks like that, it seems to cut off after fai

I checked file permissions:

ls -al /var/cache/nginx/
total 4
drwxr-xr-x 18 www-data root 360 Aug 7 02:21 .
drwxr-xr-x 20 root root 4096 Jul 14 17:01 …
drwx------ 15 www-data www-data 300 Aug 7 16:24 0
drwx------ 23 www-data www-data 460 Aug 7 17:58 1
drwx------ 14 www-data www-data 280 Aug 7 17:55 2
drwx------ 29 www-data www-data 580 Aug 7 18:07 3
drwx------ 22 www-data www-data 440 Aug 7 16:14 4
drwx------ 28 www-data www-data 560 Aug 7 18:39 5
drwx------ 19 www-data www-data 380 Aug 7 18:01 6
drwx------ 11 www-data www-data 220 Aug 7 18:08 7
drwx------ 19 www-data www-data 380 Aug 7 18:09 8
drwx------ 18 www-data www-data 360 Aug 7 17:58 9
drwx------ 24 www-data www-data 480 Aug 7 18:41 a
drwx------ 21 www-data www-data 420 Aug 7 18:41 b
drwx------ 18 www-data www-data 360 Aug 7 17:57 c
drwx------ 30 www-data www-data 600 Aug 7 16:43 d
drwx------ 21 www-data www-data 420 Aug 7 18:03 e
drwx------ 20 www-data www-data 400 Aug 7 18:09 f

What are your permissions? I’m just wondering because the permissions seem right, after all nginx is able to write the cache files, why not be able to delete them?

I moved my nginx fastcgi cache back to the default to avoid having to set the directive for nginx helper on each site but still facing the same problem:

2013/08/08 08:07:37 [error] 734347#0: *37 FastCGI sent in stderr: "PHP message: PHP Warning:  opendir(/var/run/nginx-cache/3): failed to open dir: Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 686  
PHP message: PHP Warning:  opendir(/var/run/nginx-cache/2): failed to open dir: Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 686  
PHP message: PHP Warning:  opendir(/var/run/nginx-cache/a): failed to open dir: Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 686  
PHP message: PHP Warning:  opendir(/var/run/nginx-cache/d): failed to open dir: Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 686" while reading response header from upstream, client: 196.210.116.150, server: foodandchatter.co.za, request: "GET /wp-admin/index.php?nginx_helper_action=purge&nginx_helper_urls=all&_wpnonce=43aafce385 HTTP/1.1", upstream: "fastcgi://unix:/var/lib/php5-fpm/web8.sock:", host: "foodandchatter.co.za", referrer: "http://foodandchatter.co.za/wp-admin/index.php"

but permissions seem right:

ls -al /var/run/nginx-cache/a/
total 0
drwx------ 4 www-data www-data 80 Aug 8 08:06 .
drwxr-xr-x 6 www-data www-data 120 Aug 8 08:06 …
drwx------ 2 www-data www-data 60 Aug 8 08:03 54
drwx------ 2 www-data www-data 60 Aug 8 08:06 5c

Any ideas?

First upgrade to nginx-helper 1.7.3. That will suppress any unlink related error.

For open_basedir, add nginx-cache path in allowed folder list. If you are using ISPConfig, you can do it from web-interface. In other case, you can do it via editing php.ini files or php-fpm pool config file.

The open_basedire problem is solved by adding the /var/run/nginx-cache folder to the list and nginx plugin is at 1.7.3 but still I get above error saying: permission denied.
so nginx can write inside the cache but not delete?

Would you mind cross-checking this other plugin? http://wordpress.org/plugins/nginx-champuru/ it seems to clear the cache without hickups... I don't want to switch from a trusted plugin to something else I simply found but I'm a bit stuck here why the cache isn't purged by your plugin or what exactly my permission problems entail.

To fix permission denied - you need to add either chmod/chown /var/run/nginx-cache folder correctly.

If problem reappears then you need to alter user & groups. A dirty fix could be chmod 0777 /var/run/nginx-cache. This is not always recommended but your cache is anyway temporary data...

Regarding other plugin... the headache is because of permission issue. We added a true-purge all option which no other plugin adds.

For conditional purge, e.g. flushing cached post when it is edited in wordpress, you won't see error because if uses purge module.

True-purge-all directly deletes cache without using purge-module-directive. Hence its faster, efficient & accurate.

Apart from this, cache-purging shouldn't be a serious affair. So feel free to use any plugin which gets the job done.

I did a: chown- R www-data:www-data /var/run/nginx-cache chmod -R 755 /var/run/nginx-cache

and it doesn't change anything.

I only see these errors when I click the PURGE CACHE button, the "normal" under the hood purging of your plugin does work without errors.

What permissions does the plugin expect?

I mean everything in the cache folder is owned by www-data and chmodded 755 and the folder is added to the open_basedir and nginx is able to successfully write the cache so how come the plugin cannot delete it?

Any other idea?

chmod 755 doesn't give write access to group and others.

I think, in your case www-data is used for nginx only. PHP-FPM pools are run by different users. Then you click "Purge Cache" button, deletion is done by PHP. Since PHP user is different than www-data you are running into issues.

Either add all php-fpm pool users to www-data group and chmod to 0775. This way group member will get delete permission.

Otherwise simply chmod 0777. Then php-fpm pool should be able to delete cache no matter which user/group it is running from.

I understand what you are saying but so far. I tried chmod -R 775 and that resulted in these errors:

PHP message: PHP Warning: opendir(/var/run/nginx-cache/3/6a/16b1037de556c942c76bf32ee62f06a3): failed to open dir: Not a directory in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 686 PHP message: PHP Warning: rmdir(/var/run/nginx-cache/3/6a): Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 700 PHP message: PHP Warning: rmdir(/var/run/nginx-cache/3): Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 700 PHP message: PHP Warning: rmdir(/var/run/nginx-cache/d/c4): Permission denied in /var/www/clients/client2/web8/web/wp-content/plugins/nginx-helper/purger.php on line 700 PHP message: PHP Warning: rmdir(/var/run/nginx-cache/d/06): Permission denied i

So I decided to go with chmod -R 777 and be done with this whole issue :-(

Even a

chown -R 777 /var/run/nginx-cache

doesn’t seem to solve the issue. The result is:

ls -al /var/run/nginx-cache/ total 0 drwxrwxrwx 3 www-data root 60 Aug 24 10:37 . drwxr-xr-x 28 root root 1020 Aug 21 22:05 … drwx------ 3 www-data www-data 60 Aug 24 10:37 a

So after the cache is deleted, the new cache again is not 777 and has different owners or am I seeing this wrong?

I’m experiencing this now as well. I have one question as a debug, what actually creates the cache directory and assigns www-data:root ownership to it? If this is changed manually, will it reset at some point in the future? Thanks.

I’m pretty sure I can help answer this but please correct me if I’m wrong:

As Rahul explained above: www-data is used for nginx only meaning nginx runs as this user. PHP-FPM pools are run by different users meaning each of the websites hosted on this particular server runs as their own separate user.

The end result is that this is a nginx cache so it is owned by www-data but you are trying to delete it with the nginx-helper plugin which is PHP and thus runs as another user.

Honestly, I don’t see any easy solution for this and am stuck here too.

I just realized that one can use a redis cache instead, would switching to a redis cache solve the problem?

Maybe Rahul could help out with some more information here?

I’m guessing then that nginx creates the cache folders and assigns the permissions and ownership. There are a couple of issues here which seem to prevent using this in a multi-user shared environment.

  1. Even if users are assigned to the group www-data and the permissions opened up to 770 on the existing cached folders, these folders are recreated with the original 700 permissions after being purged.

  2. After manually changing the permissions as in #1, purge does work (once) but any site that purges will delete ALL cache files, not just the ones for that site.

I can’t see how this will ever work “as is” for shared hosting, unless the plugin was altered to loop through all the cached pages for the individual site and delete them through the purge module. That could be rather involved for a large site but I suppose some sort of mechanism could be added to stagger it over a period of time. At least it would do what we are after.

The other alternative would be rather kludgy, a cron to repeatedly change permissions on the cache folders to 770, so that it was likely most folders would be deleted by a manual purge. This would still result in all cached files for all sites on the server being deleted by that one user.

Am I the only one that thinks this a bit odd that such a great caching system is only useful for a single user/site? Or is the thinking that a full purge is not essential to it’s operation?

PS: Could ACL’s be used to force permissions on new folders under cache?

The one thing I would suggest to the authors is to provide a setting to disable all instances of the manual “Purge Cache” buttons to avoid confusion on systems where this is not going to do anything. Thanks.