Kingsfordweg 151, 1043GR Amsterdam, The Netherlands ● 24/7 support — support@novogara.com
Knowledge base

Permissions and ownership

When something cannot read a file, the internet says chmod 777. That makes the file writable by every process on the machine, including the compromised one.

The numbers

Three digits: owner, group, everyone. Read is 4, write 2, execute 1.

  • 644 — owner reads and writes, everyone else reads. Normal for files.
  • 755 — the same plus execute. Normal for directories and programs.
  • 600 — owner only. Keys, configuration with secrets.
  • 700 — owner only, directory.

On a directory, execute means “may enter”, not “may run”. A directory with read but not execute lists names and lets you open nothing.

What a web application actually needs

Files owned by a deploy user, group owned by the web server's group, and the web server given read only:

chown -R deploy:www-data /srv/app
find /srv/app -type d -exec chmod 750 {} +
find /srv/app -type f -exec chmod 640 {} +

Then grant write access only where the application genuinely needs it — an uploads directory, a cache directory — with 770 and nothing else.

The application being unable to overwrite its own code is a feature. It is the difference between a web shell being uploaded and a web shell being uploaded and your source being rewritten.

umask

What permissions new files get. 022 gives 644 for files and 755 for directories; 027 gives 640 and 750, keeping other users out entirely.

Set it per service in the systemd unit with UMask=0027 rather than globally, so one application's choices do not affect another's.

setgid for shared directories

chgrp -R developers /srv/project && chmod -R g+ws /srv/project

New files inherit the group instead of belonging to whoever created them. This is what makes a shared working directory actually work, rather than slowly accumulating files nobody else can edit.

ACLs for the awkward cases

When one more user needs access and you do not want a new group:

setfacl -m u:backup:rx /srv/app

And so that new files inherit it:

setfacl -d -m u:backup:rx /srv/app

getfacl /srv/app to read it back. A file with ACLs shows a + in ls -l, which is the clue when permissions look right and behave oddly.

Finding problems

find / -xdev -type f -perm -002 2>/dev/null — world-writable files, which should be almost none

find / -xdev -perm -4000 2>/dev/null — setuid binaries; know what is on this list

namei -l /srv/app/data/file — permissions on every component of the path, which is usually where the real problem is

See also users and sudo and knowing when a file changed.


Still stuck? Mail support@novogara.com — an engineer answers, at any hour. Back to the knowledge base