What it means
chmod 660 lets the owner and members of the file's group read and write it. Everyone else gets nothing. In ls -l it shows as -rw-rw----.
| Who | Digit | Read | Write | Execute | Symbolic |
|---|---|---|---|---|---|
| Owner (u) | 6 | yes | yes | no | rw- |
| Group (g) | 6 | yes | yes | no | rw- |
| Others (o) | 0 | no | no | no | --- |
The symbolic equivalent:
chmod ug=rw,o= shared.db
On a file
Two parties can change the file: its owner, and any user in its group. Nobody else can read it. It's the shared-but-private mode, useful when a service and an admin (or two services) both need to write the same file, and no one else should see it.
On a directory
660 doesn't work on a directory: with no execute (x) bit, neither the owner nor the group can enter it or open files inside. For a directory a group shares, use chmod 770 (others shut out) or chmod 2775 (others can read, new files keep the group).
Where Linux uses 660
You'll see 660 on things that a privileged group is allowed to use:
| Path | Typical owner | Who gets access |
|---|---|---|
/var/run/docker.sock |
root:docker |
members of the docker group can control Docker |
/dev/sda, /dev/nvme0n1 |
root:disk |
the disk group can read and write raw disks |
/dev/ttyUSB0 |
root:dialout |
the dialout group can use serial ports |
PHP-FPM socket (listen.mode = 0660) |
pool user and group | the web server's group can connect |
For sockets and devices, "write" means "can connect" or "can send commands". That's why adding a user to the docker group is effectively giving them root: write access to the Docker socket lets them start a container that mounts the host's filesystem.
Typical uses
- A Unix socket shared between two services, for example PHP-FPM and nginx:
; /etc/php/8.3/fpm/pool.d/www.conf
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
- SQLite databases or data files written by an app and by an admin script running as a different user in the same group.
- Shared log or queue files that several services append to.
Making it stick
When a user in the group edits or recreates the file, the new copy gets that user's umask and primary group, which may undo 660. Two things help:
- Put the file in a setgid directory (chmod 2775 or 2770) so new files inherit the directory's group.
- Give the users involved a umask of
007(no access for others) so new files come out as 660 and directories as 770.
Recursive pitfalls
chmod -R 660 dir takes execute off every directory and makes the tree unusable. Set files and directories separately:
find /srv/shared -type d -exec chmod 2770 {} +
find /srv/shared -type f -exec chmod 660 {} +
Security notes
Group write is only as safe as the group's membership. Check who is in it with getent group docker (or the group in question), and keep it short. Don't use 660 to work around a service that "can't write": first check whether it really needs write access, or only read (chmod 640).
Related modes
- chmod 640: the group can read but not write.
- chmod 664: others can also read.
- chmod 666: everyone can write, usually a mistake.
- chmod 2775: a shared directory that keeps its group.
Check any combination in the chmod calculator.