Symfony2 Capifony deploy setfacl Operation not permitted on cache directory - symfony

I am deploying my Symfony2 web app onto an Apache web server, on an Ubuntu machine, hosted on AWS, using Capifony multistage deploy.
I have user set
set :user, "ubuntu"
And writable directory for cache set like so
set :writable_dirs, ["app/cache"]
set :webserver_user, "www-data"
set :use_set_permissions, true
set :permission_method, :acl
Everything is deploying fine apart from when this is run
executing "setfacl -R -m u:ubuntu:rwx -m u:www-data:rwx /var/www/releases/20140310012814/app/cache"
I get multiple Operation not permitted errors such as
setfacl: /var/www/releases/20140310012814/app/cache/prod/classes.php: Operation not permitted
It seems that the user, presumably 'www-data', cannot set permissions on files created by 'ubuntu'. However, I have run the following on the server from the /var/www/current directory, but I'm not entirely sure what they do:
sudo setfacl -R -m u:www-data:rwX -m u:`whoami`:rwX app/cache
sudo setfacl -dR -m u:www-data:rwx -m u:`whoami`:rwx app/cache
Here is some acl info
getfacl app/cache
# file: app/cache
# owner: ubuntu
# group: ubuntu
user::rwx
user:www-data:rwx
user:ubuntu:rwx
group::rwx
mask::rwx
other::rwx
default:user::rwx
default:user:www-data:rwx
default:user:ubuntu:rwx
default:group::rwx
default:mask::rwx
default:other::rwx
I have had a look at a similar issue here Should I run something similar? such as:
sudo sh -c 'setfacl -R -m u:ubuntu:rwX -m u:www-data:rwX /var/www/current/app/cache'
Thanks

Capifony has a cookbook entry explaining how to automatically set proper permissions. Basically what you need is this:
set :writable_dirs, ["app/cache", "app/logs"]
set :webserver_user, "www-data"
set :permission_method, :acl
set :use_set_permissions, true
:use_sudo doesn't need to be true as long as the :writable_dirs are owned by :user.
The problem
setfacl: /var/www/releases/20140310012814/app/cache/prod/classes.php: Operation not permitted
This message indicates that the cache directory isn't empty when the task is run (setfacl operates on prod/classes.php in that directory), which is not owned by :user (setfacl is not permitted).
The fact that the file is not owned by :user is quite normal because the webserver will create a lot of cache files, which make them owned by :webserver_user.
The strange thing here is that the cache directory isn't empty. Normally a new release should have an empty cache directory. A common cause for this is that the cache directory is shared, meaning you've added it to :shared_children. If so, please remove it. The cache directory shouldn't be shared.
If this is not the case, then try to find out why the cache directory isn't empty when the setfacl task is run. Maybe other tasks are running to soon.
Writable shared children
What if you actually want a shared directory to be writable for the webserver? This is actually very common, think of a media or uploads directory that should be shared.
The permissions should be set on the actual shared directory, not the symlink in the release directory. Capifony takes care of this for you, as long as the exact same phrase in :writable_dirs is also in :shared_children.
# this will work:
set :shared_children, ["web/uploads"]
set :writable_dirs, ["web/uploads"]
# this will also work:
set :web_path, "web" # is default
set :shared_children, [web_path + "/uploads"]
set :writable_dirs, ["web/uploads"]
# this will not:
set :web_path, "web" # is default
set :shared_children, [web_path + "/uploads"]
set :writable_dirs, ["web/uploads/"] # trailing /
Please check if the directory mentioned in the error is the actual shared directory (not the symlink).
The owner of the shared directory must be the user that will run the setfacl command. In other words, it must be :user. When you've changed the value of :user, or have had :use_sudo enabled in the past, this could cause issues. Please check if the directories (as set in :writable_dirs) are indeed owned by :user.
Capifony will perform a check if the permissions are already set. If so, it won't try to do it again. This is done with the following command:
getfacl --absolute-names --tabular #{dir} | grep #{webserver_user}.*rwx | wc -l"
Try to run this command manually (replace #{dir} and #{webserver_user} with the actual values) to see the outcome. If it yields no results, then Capifony assumes the permissions have not yet been set, and will try to do so.
In that case, manually check the permissions with getfacl. If they are indeed incorrect, manually set them (again, replace #{user}, #{webserver_user} and #{dir}) using "the power of root":
sudo setfacl -R -m u:#{user}:rwX -m u:#{webserver_user}:rwX #{dir}
sudo setfacl -dR -m u:#{user}:rwx -m u:#{webserver_user}:rwx #{dir}
Then run Capifony again. If all is well, it should succeed this time!

You have run the sudo setfacl on the current directory, but you are receiving the errors on the single releases folders. Anyway, www-data should be the right owner of the cache folder, it is the main user of that dir, in the end!
In our deploy script, we use this:
set :permission_method, :acl
set :writable_dirs, ["app/cache"]
set :webserver_user, "www-data"
set :use_set_permissions, false
set :use_sudo, false
I think this is the right solution.

Related

Can not access a file in a lxd container shared from the host

I have an lxd container, that is named master. I found out that it's root can be found at:
/var/lib/lxd/containers/master/rootfs/home/ubuntu/
So, I transferred my folder, tars to this address. Note that tars has two files.
Now, I know that the user id and the group id of tars is root. On the other hand, the user id and group id of every other file in the container is 166536.
So, for the folder and the files, I did sudo chown 166536 <file/folder name>, to change the user id, and sudo chown :166536 <file/folder name>, to change the group id.
Once, I did this, I expected tars to be accessible from the container master, but that didn't happen. Can anyone tell me what am I missing?
Here is a method, I found on reddit:
Yeah this was the answer, running with unprivileged container you are
not able to see the permissions on the LXD Host, so it appears as
Nobody:Nobody. In a way is silly because you can mount the folder into
the Container and see the files on it..
For future reference, for anyone having this issue, this are the steps
i made (it may not be the correct ones but it works)
sudo mkdir /tmp/share
adduser subsonic --shell=/bin/false --no-create-home --system --group --uid 6000 (this is a "service account")
sudo chown -R subsonic: /tmp/share
lxc exec Test -- /bin/bash
mkdir /mnt/share
adduser subsonic --shell=/bin/false --no-create-home --system --group --uid 6000 (important that the uid is the same)
exit
lxc stop Test
lxc config edit Test (add the line security.privileged: "true" right bellow config: save and exit)
lxc start Test
lxc config device add MyMusic MyLibrary disk source=/tmp/share path=/mnt/share
lxc exec Test -- /bin/bash
ls /mnt/share/ (note that the subsonic user is there)
exit
It's a shame that i couldnt find a way to map the user inside the
unprivileged container. if Anyone know's let me know.
Basically, to create a common user, for both the host and the container. Is there anything better that this method available?
When you open the container and do
whoami
You'll get the result:
root
So, the current user is root, and not ubuntu. That being said, the address where I was sending the folder to, is wrong. The current address is var/lib/lxd/containers/master/root/. Once the folder is sent, check the uid/gid (something like 165536). Change the uid by:
sudo chmod 165536 <folder-name>
and gid by:
sudo chmod :165536 <folder-name>
Once that is done, we're sure that the container user root will be able to access these files.
Or in a single step sudo chmod 165536:165536 <folder-name>.

Symfony 4 file permissions of var directory change every time

I am setting up a new server and installed Ubuntu 18.04 in combination with Apache2. My project is stored in /var/www/project. In apache2.conf I added
<Directory /var/www/project/>
AllowOverride All
Order Allow,Deny
Allow from All
</Directory>
In my virtualhosts file I point to /var/www/project/public
When I go to the Ip address of my server I see my project and everything works, except one thing:
whenever I clear the cache with php bin/console cache:clear the permissions of my directory var are messed up which results in errors in the production environment.
I can fix this with:
chmod -R 777 var/
But the problem returns wheneven I clear the cache again. I tried with different users including root, but always the same problem. I do not understand what is causing this. In the documentation on file permissions it says:
In Symfony 3.x, you needed to do some extra work to make sure that your cache directory was writable. But that is no longer true! In Symfony 4, everything works automatically
Well not for me, but what could cause the problem?
The problem
The cache directory is owned by the user executing the cache:clear command.
Lets say your project files are owned by www-data.
Clearing the cache with root user
Cache is owned by root
www-data can't write in cache directory
Solution
execute cache:clear using the user owning the files.
Login as www-data: su www-data -s /bin/bash
clear the cache ./bin/console cache:clear
Depending on your settings, your www-data user may be different
The solution that worked for me (using Symfony 3.x and Ubuntu 18.04) is the one explained in the official site, here:
https://symfony.com/doc/3.4/setup/file_permissions.html#using-acl-on-a-system-that-supports-setfacl-linux-bsd
Maybe that solution work also with Symfony 4?
Extract:
3. Using ACL on a System that Supports setfacl (Linux/BSD)
Most Linux and BSD distributions don't support chmod +a, but do
support another utility called setfacl. You may need to install
setfacl and enable ACL support on your disk partition before using it.
Then, use the following script to determine your web server user and
grant the needed permissions:
HTTPDUSER=$(ps axo user,comm | grep -E
'[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1
| cut -d\ -f1)
sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:$(whoami):rwX var
sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:$(whoami):rwX var
Note:
The first setfacl command sets permissions for future files and
folders, while the second one sets permissions on the existing files
and folders. Both of these commands assign permissions for the system
user and the Apache user.
setfacl isn't available on NFS mount points. However, storing cache
and logs over NFS is strongly discouraged for performance reasons.
Personal hint:
sudo apt-get install setfacl may says "unable to find setfacl".
If so:
check if setfacl is present: setfacl -h
setfacl is part of the acl package, so install acl if missed
It took me quite a while to solve the problem in Symfony 4.4 that only was present in PROD but not in DEV. I still don't know what difference between PROD and DEV caused it, however. At least it's working now.
If ACL is present, the first solution in https://symfony.com/doc/4.4/setup/file_permissions.html#permissions-required-by-symfony-applications should work. I just manually set the HTTPDUSER since the given code returned the wrong one. Else, setting the permissions after every single cache:clear should do the job, too:
sudo chown -R "$local_user":"$webserver_group" "$app_dir/var/"
sudo chmod -R 0777 "$app_dir/var/"
Maybe you have to manually delete old files in var/ bevore first by rm -rf var/*

Cache permissions error when deploying with Capifony

When I deploy with Capifony a Symfony2 project I get this error message in apache log when accessing a webpage:
PHP Fatal error: Uncaught exception 'RuntimeException' with message
'Failed to write cache file
"/var/deploys/acme/releases/20150219150638/app/cache/prod/classes.php"
In order to avoid this, each time I deploy I have to execute chmod 777 -R cache for fixing the permissions, which doesn't seem to me like a good solution.
The cache is set in the writable_dirs option, so I don't know exactly why it gives a permissions error:
set :writable_dirs, ["app/cache", "app/logs", "app/sessions"]
I have the following deploy.rb configuration:
set :stages, %w(production staging)
set :default_stage, "staging"
set :stage_dir, "app/config"
require 'capistrano/ext/multistage'
set :application, "Api"
set :domain, "<my_domain>"
set :deploy_to, "/var/deploys/acme.com"
set :app_path, "app"
set :repository, "git#bitbucket.org:acme/api.git"
set :scm, :git
set :model_manager, "doctrine"
# Or: `propel`
role :web, domain
role :app, domain, :primary => true
set :keep_releases, 3
# Be more verbose by uncommenting the following line
logger.level = Logger::MAX_LEVEL
# Other options
set :user, "root"
set :use_sudo, false
# Symfony2 specific configuration
set :shared_files, ["app/config/parameters.yml"]
set :shared_children, [app_path + "/logs", web_path + "/uploads", "vendor"]
set :use_composer, true
set :update_vendors, true
set :writable_dirs, ["app/cache", "app/logs", "app/sessions"]
set :webserver_user, "www-data"
set :permission_method, :chown
set :use_set_permissions, true
set :assets_install, true
set :dump_assetic_assets, true
task :upload_parameters do
origin_file = "app/config/parameters.yml"
destination_file = shared_path + "/app/config/parameters.yml"
try_sudo "mkdir -p #{File.dirname(destination_file)}"
top.upload(origin_file, destination_file)
end
after "deploy:setup", "upload_parameters"
UPDATE
The cache folder has the following permissions when deployed:
drwxrwxrwx 3 root root 4096 Feb 20 13:13 cache
Inside the cache folder, a prod folder is also created with these permissions:
drwxrwxr-x 7 root root 4096 Feb 20 13:13 prod
UPDATE 2
I use root as user because in the server the user root has my public ssh key. If I set another user in the config, it asks me for root password when deploying. However I have set the webserver_user variable in my config above. Also the user root it's not in the group www-data, should it be?
My capifony version it's 2.8.3. Here is an example of command it executes when setting permissions if chmod_alt is selected as settings permissions method:
getfacl --absolute-names --tabular ...
This error is also generated if I have chmod as setting permissions method.
Although the previous command gives an error, I think the command that provokes the roll back (with chmod_alt) is this one:
`echo stat /var/deploys/acme.devel/releases/20150226123037/app/sessions -c %U`
It generates the following error message (after which it makes a rollback):
cannot stat `/var/deploys/acme.devel/releases/20150226123037/app/sessions':
No such file or directory
I have set the following parameters in my deploy.rb in order to make it work:
set :use_sudo, true
default_run_options[:pty] = true
And I have removed app/sessions from writable dirs option:
set :writable_dirs, ["app/cache", "app/logs"]
If you are using linux you could try to configure ACL for these directories to not override them each time you deploy.
See "Setting up Permissions" Part in installation documentation
I prefer method like
$ sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX app/cache app/logs
$ sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX app/cache app/logs
Your system probably doesn't support chmod +a. Try using:
set :permission_method, :chmod_alt

Wordpress Could not copy file. /var/www/wp-content/upgrade/attitude.tmp/attitude/images/my-space#2x.png

This problem occurs when I try to install any themes inside my wordpress admin console.
I have tried change the owner of the /var/www directories (with chown -R <username> /var/www) I have also setup permission 755 for the directory. I realize the problem is due to the file's permission in the upgrade directory. The file has permission -rw-r--r-- (this directory and files inside are supposed to be created by the FTP user I supplied when installing the theme)
Do you have selinux installed?
You can check by going to the ssh window and type # sestatus
It should show you
SELinux status: enabled/disabled
SeLinuxfs mount: /selinux
Current mode: enforce/permissive
Mode from config file: enforce
Policy Version: XX
Policy from config file: targeted
if it's on 'enforce', you can temporarily change it to permissive to see if that's your issue but using
# setenforce 0
# getenforce // Should return permissive
Try to upload then. If it works you need to add that directory to tell selinux to allow httpd to write there.
chcon -R -t httpd_sys_rw_content_t DIRECTORY/PATH/THAT/YOU/WANT/TO/WRITE/TO/
Hope this helps

Symfony command cache:clear make certain permissions to be lost

I am using Symfony 2.0.12 in a Mac Os X Lion (10.7.4).
For some reason, every time I clear cache (php app/console cache:clear), the permissions of cache/* folder are lost.
The result is that I try to enter my application and it start to give me a bounch of errors like "unable to write in app/cache/dev/XXX folder".
So there starts a "fight" against the machine. No sooner I give permissions for that folder, quickly I get an error message for the next YYY folder. And that happens during about 8 or 9 folders until it's me the winner and everything apparently starts to works normally again.
Did anyone pass through this? How can I manage to conserve the permissions when clearing the cache?
in the documentation there are some alternative commands on how to set up the permissions. but i dunno if they work for mac. Check the Setting up Permissions box.
http://symfony.com/doc/current/book/installation.html
on my ubuntu system the following commands made the permissions permanent
sudo setfacl -R -m u:www-data:rwx -m u:`whoami`:rwx app/cache app/logs
sudo setfacl -dR -m u:www-data:rwx -m u:`whoami`:rwx app/cache app/logs
making the webserver run as your user is not a good idea in my opinion because the webserver should not have access to your personal files and so on...
If you're running the commands as a different user than the php process that create the cache files then this will happen. You'll either have to run the commands as the web server user, make the web server run as your user, or chown/chmod the app/cache app/logs directories after you run commands.

Resources