Default file and directory permissions in Linux

Context

Just yesterday night while I was configuring Grav, I realised some of the permissions were not setting right and I was unable to modify files created by Grav via a privileged user with SFTP.

Looking into it, I checked the properties via ls -l and sure enough:

$ ls -l /-snip-grav-parent-directory-/
total -snip-
drwxr--r-x 13 -snip-grav-user- -snip-grav-group- 4096 Aug  6 08:00 -snip-grav-folder-

Since the files were owned by the Grav user, while my user was in the Grav group. I was unable to edit the files due to the absense of write permissions for the group clause.

Simple chmod

At first, running a simple recursive chmod everytime I met the issue was fine as normally my web files were not created by the Grav user as I mainly host static pages before:

$ chmod -R g+w /-snip-grav-directory-/

Default groups and permissions

But there was two problems, the first problem is that new files created by my privileged user had the group not set to the Grav user and thus not allowing Grav to modify it too. I didn't wish to add the grav user to any groups so I had to resort to recursively adding the setgid bit on the directory:

$ chmod -R g+s /-snip-grav-directory-/

That solves the first problem by having new files automatically set its' group to the parent directory whenever they are created.

The other problem was there was no default permissions and new files were created were not allowed to be modified by my privileged user. That's where this nifty tool comes in, acl (Access Control Lists) which extends the basic chmod, chown and chgrp commands.

This tool requires you to add acl your filesystem mount option to always apply if it's not already set, you can check it by running this and seeing if acl is returned:

$ tune2fs -l /dev/sdXY | grep "Default mount options:"

Most filesystems turn it on by default, but if it does not, proceed to add it into /etc/fstab.

After that it's just a simple command as this to set default permissions for the directory and the files

$ setfacl -R -d -m g::rwX -snip-grav-directory-
  • setfacl - set acl command
  • -R - recursive
  • -d - target default permissions
  • -m - modify
  • g::rwX - target group with read write and only directories should be set with eXecutable

A confirmation with getfacl:

$ getfacl -snip-grav-directory-
getfacl -snip-grav-directory-
# file: -snip-grav-directory-
# owner: -snip-grav-user-
# group: -snip-grav-group-
# flags: -s-
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:other::r-x

Once you see # flags: -s- and default:group::rwx, you are all set and future new directories and files inside will be set with the default permissions automatically.

You may want to run chmod -R g+X the directory after the above step to apply the permissions to the existing files.

Pointers from mistakes I made

  • Do not forget to set the executable permission for directories, if it is missing the user will not be able to access it, note the pointer below when needing to fix this.
  • Do not ever run chmod -R g+x as it would set all files executables too which is a security risk, instead use chmod -R g+X with capital X which only sets directories with executable, same thing for acl.

Further reading and references