A solution which I usually go for on web servers is using ACLs. Basically, this means using additional sets of permissions, other than the usual user-group-other system. I find this particularly useful when I'm setting up restricted PHP access (for instance, using suPHP).
In order to maintain ownership on my files, I make sure they belong to me:
$ chown me:me /var/www -R
Then I give
www-data read access everywhere (and access permission on directories ; finer settings might desirable sometimes).
$ setfacl -Rdm 'u:www-data:r-X' /var/www
$ setfacl -Rm 'u:www-data:r-X' /var/www
I also give write-access to Apache wherever I want it to write stuff. For instance:
$ setfacl -Rdm 'u:www-data:rwX' /var/www/uploads
$ setfacl -Rm 'u:www-data:rwX' /var/www/uploads
Note that, in order to use ACLs, you need to make sure you mounted the filesystem with the
acl option. This is done in
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/sdxy /var ext4 defaults,acl 0 2
/var is on a different partition, otherwise see
By the way on some systems, the
acl option is set by default. For instance:
As of Ubuntu 14.04 and for ext4, the above is not required as acl are already default.
You can check whether ACLs are enabled on a filesystem using
tune2fs (assuming an ext* FS) :
# tune2fs -l /dev/sdxy | grep acl
Default mount options: acl ...
For more information on
setfacl, have a look here.