Debian – Apache PHP uploads – ownership and permissions

apache-httpddebianpermissionsPHP

I am giving my first steps to install a VPS web server (Debian 8 + Apache 2 + PHP 5.6) and need some help with files/folders permissions, please.

I already found some similar topics about this subject (not exactly the same), and all from 4 or 5 years old. Some of them point to solutions using deprecated PHP methods. Maybe today there are some new methods or solutions.

Well, there is Apache 2 that runs in www-data user/group. So I created a user called webadmin, put it in the www-data group and configured it as the owner of the main web site folder:

adduser webadmin
usermod -a -G www-data webadmin
chown -R webadmin:www-data /var/www/website.com

I also changed the permissions of the public_html folder like this:

find /var/www/website.com/public_html -type f -exec chmod 644 {} +
find /var/www/website.com/public_html -type d -exec chmod 755 {} +
find /var/www/website.com/public_html -type d -exec chmod g+s {} +

And created the folder that will receive the uploaded files (only static files – images):

mkdir /var/www/website.com/public_html/uploads
chown webadmin:www-data /var/www/website.com/public_html/uploads
chmod 774 /var/www/website.com/public_html/uploads

Now, what is happening: all the folders and PHP/Html files that I upload using SFTP (logged as webadmin) of course get webadmin as owner. When I use PHP to create subfolders and upload the images, they get the www-data user as owner. In this scenario I am having some permission issues, like to delete files throught SFTP.

I could assign Apache to run as webadmin user and www-data group, but I think I can have security issues (don't I?). Please, is there a standard and best pratice to configure the server or the PHP script that will created the folders and upload the files to avoid this issue?

Best Answer

Your problem is that new files are not group writable. Instead of using setgid on directory to set the group, use ACLs which offer more flexibility.

The default ACL entry is inherited for new files and directories, granting permissions defined in the ACL. To set a default ACL entry for group webadmin to allow rwx:

setfacl -m default:g:webadmin:rwx /var/www/website.com/public_html/uploads

New files created in the directory will be readable and writable for group webadmin.


If ACL is not an option, you need to change the umask, which is determines the default UNIX permissions for new files. Sensible choices for new umask are 002 (world-writable bit masked) and 007 (all world permission bits masked, i.e. only group and owner have access).

To set Apache umask, copy systemd unit file to /etc:

cp /lib/systemd/system/apache2.service /etc/systemd/system/

Configure umask in /etc/systemd/system/apache2.service by appending UMask=<umask> to [Service] section. Note that this affects all files created by Apache.

Changing umask for sftp is only required if you need to change uploaded files/directories from PHP/Apache. The default umask 022 creates files group and world readable, but not group writable. Easiest way to configure default umask for sftp is with pam_umask.

To apply your custom umask only for users in a specific group and only when using sftp, append /etc/pam.d/sshd with:

session [default=1 success=ignore] pam_succeed_if.so user notingroup <yourgroup>
session optional                   pam_umask.so umask=<umask>

The first rule tells pam to skip the next rule if the user is not in group <yourgroup>, i.e. only apply the next rule if the user is in group <yourgroup>. The second rule sets the umask to <umask>.


Addendum: Note that existing files moved with mv retain their original permissions and ownership. You can apply default permissions from umask and directory setgid/ACLs by copying files with cp -d instead.

Related Question